ShellTool is configured with require_approval=True, every shell command is queued and waits for explicit approval before executing. The approvals API lets you review, approve, or deny these queued commands.
GET /approvals/pending
List all commands waiting for approval.POST /approvals//approve
Approve a pending command. The command executes immediately after approval.{"always": true} in the body to also persist a durable allowlist entry for the command’s program name, so future matching commands skip the prompt entirely:
404 if the approval ID is not found (expired or already resolved).
POST /approvals//deny
Deny a pending command. The agent receives an error:"Command denied by user approval gate.".
Approval timeout
Approval requests expire after 120 seconds. If no decision is made, the command is automatically denied.Persistent allowlist
Commands matching a stored entry skip the prompt entirely (subject to theask mode below).
pattern is a glob matched against the program name (e.g. git, curl*); arg_pattern (optional) is a regex matched against the full command line.
Security & ask modes
GET /api/v1/approvals/policy also returns require_shell_approval — whether the gate itself is actually enabled on the running shell/browser tools right now (defaults from [security] require_shell_approval in config.toml, see Configuration). The security/ask modes above have no effect at all when this is false — every command just runs. It’s null if the tool registry isn’t available yet (still starting up).
POST /api/v1/approvals/policy also accepts require_shell_approval to toggle the gate live on both tools, no restart needed:
Channel-forwarded approval
A pending approval is also sent as a plain-text message via the channel that triggered it (Telegram, Slack, Discord, etc. — any of the 34 adapters). Reply directly in that channel:CLI equivalents
Enabling the approval gate
Dashboard
The/terminal page in the dashboard shows pending approvals and lets you approve or deny them with a click — without needing to call the API directly.