When a rule says "ask a named approver", the action waits for a person in Govern. All of these requests meet in one approvals inbox, in the console service Approvals (pages Inbox, Channels, SLA and Decision history).
What lands in the inbox
| Source | Comes from | Who may decide |
|---|---|---|
agent_policy | An agent action whose rule is ask with approval: approvers | A named approver (or any holder of agentpolicy:approve when none is named) who also holds approvals:approve or is in the request's approver group |
mcp_call | An MCP tool call that needs approval | Holders of mcp:approve |
access_activation | A just-in-time activation of a binding that requires approval | Holders of iam.activations:approve where the role is granted |
agent_action and other subject types | The approval service's own requests, including AI Gateway tool calls held by tool governance (action ai_gateway.tool_call) | Holders of approvals:approve, or members of the request's approver group |
Rules for every source:
- The requester can never approve their own request (
403 self_approval). - Decisions need a reason of 1 to 1000 characters.
- A holder of
approvals:readsees every request; anyone else sees what they filed, voted on, decided or may decide. - Every decision, and every refused attempt to decide, is audited as
approvals.inbox.decided, besides the source's own audit event.
Decide an agent action
An agent permission request shows the requester, project, engine, session, kind, the action, the rule that required approval and its approvers, and whether you may decide it.
| Decision | Effect |
|---|---|
| Approve once | The action may run once. The endpoint agent consumes the grant immediately before running it; it cannot be used twice. It expires after the organisation's approval_ttl_seconds (15 minutes by default). |
| Approve for the session | The same action in the same agent session is allowed until the grant expires (session_grant_max_seconds, 8 hours by default). |
| Deny | The action is refused. |
curl -sS -X POST "$KEYSTONE_URL/api/v1/orgs/$ORG_ID/agent-policy/approvals/$APPROVAL_ID/decision" \
-H "Authorization: Bearer $APPROVER_TOKEN" -H 'Content-Type: application/json' \
-d '{"decision": "approve", "scope": "once", "comment": "Release 4.2 tag"}'
While a request is pending, the developer's tool call is refused with a message naming it; the agent retries once the request is approved. A request nobody decides expires. Govern re-evaluates the action against the person's current policy every time it is asked, so a revocation or a changed rule takes effect before a stored request is answered.
Only the approver's own vote decides an agent request. If someone else voted on the shared request through the general approvals API first, the decision answers 409 and nothing is granted.
The inbox API
| Route | Purpose |
|---|---|
GET /api/v1/approvals/inbox?view=open (or decided) &source=&cursor=&limit= | One list across every source, with SLA state and can_decide for the caller |
GET /api/v1/approvals/inbox/{id} | One request with its reason, parameters, votes and channel dispatches |
POST /api/v1/approvals/inbox/{id}/decision | {"decision": "approve" or "deny", "reason", "scope"}; scope is required for items that take one (agent permissions: once or session) |
GET /api/v1/approvals/settings | The SLA and the channels, without secrets |
Refusals: 403 not_an_approver or self_approval; 409 out_of_turn, already_voted, already_decided or expired; 503 source_unavailable when a source does not answer. The routes need api:access; the source decides who may act.
Notification channels
Approval requests can be sent to webhook, email, Slack and PagerDuty channels, and approved with signed single-use links. Configuring channels (POST, DELETE /api/v1/approval-channels) needs approvals:admin; reading them and dispatching a request (POST /api/v1/approvals/{id}/dispatch) need api:access. Channel URLs and credentials are never shown back; error messages are cut to the scheme and host.
A person who may decide a request can get a single-use token for it (POST /api/v1/approvals/{id}/issue-token), which POST /api/v1/approvals/redeem accepts once.
SLA
PUT /api/v1/approvals/sla (approvals:admin) sets the account's thresholds: warn_after_mins, escalate_after_mins, auto_reject_after_mins and escalation_target_group, each 1 to 43200 minutes, in that order. The inbox shows each item's SLA state (on_track, warning, escalation_due, escalated, overdue, and once decided met, late, auto_rejected or expired).
SLA processing and recurring approvals are recorded as partial in the source. Do not rely on automatic escalation or auto-rejection without testing it in your deployment.
Related
- Rules that create agent requests: Agent policy.
- JIT activations: Just-in-time access.
- AI Gateway tool calls held for approval: Guardrails and DLP.