Approvals
An approval is an object, not a dialog box. When a Worker proposes an action it is not trusted to take alone - a deploy, a rollback, opening a pull request - the action does not run. An approval is created and waits for a human. You can list approvals, read one, and approve or deny it over the API, the console, or a Slack button.
Lifecycle
pending- proposed and waiting. The action has not run.deciding- briefly claimed while a decision is carried out. Two concurrent decisions (a Slack click and a console click) cannot both execute the action; the second one sees the row already claimed.approved- the action ran. Readresultfor what it returned, orerrorif the tool itself failed. A failed tool is still an approved decision: you said yes, and the attempt is on the record.denied- the action never ran, and any unattended run that was waiting on it ends.
Endpoints
GET /api/approvals # all states, newest first
GET /api/approvals?status=pending # just what needs you
GET /api/approvals?worker_id=<uuid> # one worker's proposals
GET /api/approvals/{request_id} # one approval, any state
POST /api/approvals/{request_id}/approve # run it
POST /api/approvals/{request_id}/deny # discard itWhat an approval looks like
{
"request_id": "9f3c1e...",
"status": "pending",
"worker_name": "pr-reviewer",
"worker_role": "deploy_proposer",
"run_id": "4a1b...",
"tool": "deploy",
"args": { "project": "api", "env_vars": "***redacted***" },
"requested_at": "2026-07-26T09:14:02Z",
"decided_at": null,
"result": null,
"error": null
}Arguments are shown redacted. The full arguments are stored encrypted and never leave the server - they exist only so the action can actually run once you approve. An approval card is something an agent can influence the contents of, so it is never a place secrets are printed.
Who can approve
Deciding requires a signed-in session. API tokens cannot approve - including, especially, a Worker's own token, since a worker approving its own proposal would defeat the gate entirely. An agent can see that its action is pending (it gets a pending result back, and can poll it) but it can never resolve it.
By default only the worker's owner can approve. A worker set to channel approver policy can also be approved by anyone in its report channel from a Slack button - useful for a team on call, and a deliberate loosening you opt into per worker.
Attribution
An approved action is recorded as the worker's action, not yours. Your decision is recorded separately, on the approval itself. The activity log shows the worker that proposed the action and the policy role it acted under, so "a worker deployed this, and a human allowed it" stays two distinct facts rather than collapsing into one.