Skip to main content
Use --approval secure so pending approvals survive a gateway restart — the SQLite-backed PresentationApprovalBackend persists every decision and rehydrates outstanding requests on startup.

Quick Start

1

Set required env vars (CLI only)

export PRAISONAI_APPROVAL_ACTORS="your-user-id"
export PRAISONAI_HOME=/var/lib/praisonai   # optional, overrides ~/.praisonai
PRAISONAI_APPROVAL_ACTORS is required when using --approval secure from the CLI. For the Python API, pass allowed_actors= directly to PresentationApprovalBackend (see next step).
2

Agent-centric example

import os
from praisonai.bots import ApprovalStore, PresentationApprovalBackend
from praisonaiagents import Agent

store = ApprovalStore(path=os.path.expanduser("~/.praisonai/state/approvals.sqlite"))
backend = PresentationApprovalBackend(
    store=store,
    allowed_actors={"your-user-id"},
)

agent = Agent(
    name="Ops",
    instructions="You are a careful ops assistant. Ask before destructive commands.",
    approval=backend,
    tools=["execute_command"],
)

agent.start("Clean up /tmp/cache")
# The gateway asks the human once. Restart the gateway — the pending request
# is rehydrated from SQLite and the human can still Allow or Deny.
3

CLI usage

praisonai run --approval secure agent.py

How It Works

StepWhat happens
persistRequest is written to SQLite before the human is prompted
rehydrate()On startup, outstanding requests are restored with their original expiry
resolveEvery decision (approved / denied / expired) is written to the audit trail
actor checkOnly actors listed in PRAISONAI_APPROVAL_ACTORS may approve

Configuration

SettingValueNotes
PRAISONAI_APPROVAL_ACTORSComma-separated actor IDsRequired for --approval secure. Approvers not on this list are rejected.
PRAISONAI_HOMEAny pathOverrides the state root. Default: ~/.praisonai

Default persistence paths

FileContents
~/.praisonai/state/approvals.sqlitePending approvals + audit trail (approved / denied / expired)
Override the root with PRAISONAI_HOME:
export PRAISONAI_HOME=/var/lib/praisonai
# Store will be created under /var/lib/praisonai/state/approvals.sqlite

Programmatic Override

from pathlib import Path
from praisonai.bots import ApprovalStore, PresentationApprovalBackend
from praisonaiagents import Agent
from praisonaiagents.approval import ApprovalConfig

store = ApprovalStore(path="/var/lib/praisonai/state/approvals.sqlite")
backend = PresentationApprovalBackend(
    store=store,
    allowed_actors={"user-123", "ops-team"},
    timeout=600,
)

agent = Agent(
    name="Ops",
    instructions="Ask before destructive commands.",
    approval=ApprovalConfig(backend=backend, all_tools=True),
)
PresentationApprovalBackend constructor parameters:
ParameterTypeDefaultDescription
storeApprovalStore | NoneNoneDurable SQLite store; None means in-memory only
allowed_actorsIterable[str] | NoneNoneActor IDs that may approve; None allows any actor (legacy)
channel_send_funccallable | NoneNoneAsync function to send approval prompt to a channel
targetstr | NoneNoneDefault channel/chat ID
timeoutfloat300.0Seconds to wait for a decision before failing closed

What Happens on Restart

Rehydrated pending requests keep their original expiry — a restart does not reset the TTL clock. A request that had 30 seconds left still has 30 seconds after rehydration.
  • No live awaiter: the awaiting agent call was lost with the previous process. Rehydrated requests stay resolvable via the gateway UI or API. The audit trail records the terminal state.
  • Expiry is preserved: rehydrate() filters by stored expires_at, so a nearly-expired approval is not inadvertently extended.
  • Fail-open startup: a corrupted store logs the error and returns 0 — it never blocks gateway startup.

Best Practices

Use --approval secure on the CLI (or pass a PresentationApprovalBackend instance via approval= in Python) in your deployment environment. Without a durable store, a gateway restart drops all pending approvals — agents waiting for a human decision receive a timeout/deny.
The secure backend requires at least one authorised actor. Omitting PRAISONAI_APPROVAL_ACTORS causes a startup error by design — it prevents a misconfigured deployment from silently accepting approvals from any actor.
Grants are stored per-host. When rotating to a new host, copy ~/.praisonai/state/*.sqlite to preserve in-flight approvals — do not leave agents in a state where they re-prompt unnecessarily in production.
PRAISONAI_APPROVAL_ACTORS scopes who can approve. Pair this with network-level access controls on the gateway callback endpoint for defence-in-depth.

Secure Approval Backend

Full reference for the actor-authorised, durable approval backend

Gateway

Gateway deployment and configuration

Durable Approvals (Bots)

SQLite-backed approval storage for messaging bots

Approval

Default approval behaviour and backends