--approval secure so pending approvals survive a gateway restart — the SQLite-backed PresentationApprovalBackend persists every decision and rehydrates outstanding requests on startup.
Quick Start
Set required env vars (CLI only)
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).How It Works
| Step | What happens |
|---|---|
persist | Request is written to SQLite before the human is prompted |
rehydrate() | On startup, outstanding requests are restored with their original expiry |
resolve | Every decision (approved / denied / expired) is written to the audit trail |
| actor check | Only actors listed in PRAISONAI_APPROVAL_ACTORS may approve |
Configuration
| Setting | Value | Notes |
|---|---|---|
PRAISONAI_APPROVAL_ACTORS | Comma-separated actor IDs | Required for --approval secure. Approvers not on this list are rejected. |
PRAISONAI_HOME | Any path | Overrides the state root. Default: ~/.praisonai |
Default persistence paths
| File | Contents |
|---|---|
~/.praisonai/state/approvals.sqlite | Pending approvals + audit trail (approved / denied / expired) |
PRAISONAI_HOME:
Programmatic Override
PresentationApprovalBackend constructor parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
store | ApprovalStore | None | None | Durable SQLite store; None means in-memory only |
allowed_actors | Iterable[str] | None | None | Actor IDs that may approve; None allows any actor (legacy) |
channel_send_func | callable | None | None | Async function to send approval prompt to a channel |
target | str | None | None | Default channel/chat ID |
timeout | float | 300.0 | Seconds 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 storedexpires_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
Enable in every production deployment
Enable in every production deployment
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.Always set PRAISONAI_APPROVAL_ACTORS
Always set PRAISONAI_APPROVAL_ACTORS
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.Rotate SQLite files with host rotation
Rotate SQLite files with host rotation
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.Combine with actor allow-lists for defence-in-depth
Combine with actor allow-lists for defence-in-depth
PRAISONAI_APPROVAL_ACTORS scopes who can approve. Pair this with network-level access controls on the gateway callback endpoint for defence-in-depth.Related
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

