Confirmation Model
Connection policies and custom-tool metadata configure approval for model-selected calls. This page explains their distinct fields and execution behavior. See Connections, Tools, and Guardrails for full configuration.
Durable child-tool execution, authored ctx.request() calls, and direct tool evals bypass the outer agent loop's approval gates. Inline composites refuse confirmation-required and connection-category children. Enforce required authorization and approval in those workflows or in the downstream API. See Agent Workflows.
The Four Tiers
| Tier | Behavior |
|---|---|
| Auto-approve | The agent executes without user interaction; the default for reads. |
| Confirm | Execution pauses. The runtime emits a confirmation_required event and waits for approval before running the call. |
| Review | The runtime refuses execution. The host application owns any separate human-review workflow; approving in chat does not execute the call. |
| Never | The connection operation is denied through the request and native operation tools. Authored ctx.request() calls do not evaluate this policy. Custom tool.json tools with confirm: "never" are not registered. |
One Model, Three Vocabularies
| Surface | Where configured | Vocabulary | Tier it resolves to |
|---|---|---|---|
| Connection endpoint | policy.json confirm | omitted / true / "review" / "never" | auto / confirm / review / never |
| Custom tool | tool.ts exposure.kind | open / operator-gated / requires-confirmation | auto / UI marker (requires llm_callable: false) / confirm |
| Request tool call | intent parameter | 'read' / 'write' / 'confirmed_write' | declares which side of the handshake a call is on (see below) |
Connection endpoints: policy.json confirm
For connection policies, confirm accepts only true, "review", or "never"; omit it for read endpoints (false is not a valid value here). See Connections for the full policy format, and Escalation below for the rules that can raise an endpoint's tier at call time.
Native OpenAPI writes require a matching endpoint policy. Omitting confirm on
that entry permits execution without approval; omitting the entry denies the
write.
Custom tools: exposure.kind
Custom tools declare their tier through exposure.kind in tool metadata:
open(the default): the agent calls the tool freely.requires-confirmation: every model-selected call pauses for explicit approval before executing; the confirmation card's reason is generated by the runtime (Tool "<name>" requires user confirmation). This is distinct from a connection endpoint's"review"policy, which denies execution.operator-gated: a marker for tools meant to be run from operator UI actions. It is not enforced by the runtime; you must setllm_callable: falseso the tool stays out of the model's tool list while remaining reachable by composites and triggers.
The request tool handshake: intent
The built-in request tool declares intent: 'read' | 'write' | 'confirmed_write' on every call. Mutating methods (POST, PUT, PATCH, DELETE) must declare 'write' or 'confirmed_write'; the permission checker rejects them with intent: 'read'.
When a write hits an endpoint at the confirm tier, the two-phase handshake runs:
- The agent calls with
intent: 'write'. The loop parks the call before executing it and emitsconfirmation_requiredto the client. - The user approves (the SDK chat surfaces render this automatically).
- The runtime resumes the same call with
intentrewritten toconfirmed_writeand executes it. The model does not need to call again. (Called outside the agent loop, such as through durable execution, the request tool instead returns a preview object telling the caller to re-invoke withconfirmed_write.)
Endpoints at the review or never tier deny the call regardless of intent.
Native operation tools
Native OpenAPI tools have no intent argument. The runtime derives reads and writes from the method and local policy. Invalid arguments are refused before a confirmation card. Confirm-tier writes emit confirmation_required with the connection, method, template, policy reason and grouped arguments. Approval is bound to that call and its effective arguments; a hook rewrite after approval asks again. review and never deny execution.
The confirmation_required Event
Whenever execution pauses for approval, the runtime emits the confirmation_required SSE event (SSEConfirmationRequiredEvent in the SDK) with endpoint, method, reason, escalated, and timestamp fields. It fires in three cases: a connection write hits a confirm tier, a requires-confirmation tool is called, or a hook returns an ask decision. The chat SSE stream documents the client-side view.
Escalation
Two rules can raise a configured tier at call time:
- Threshold escalation: endpoint policies can escalate based on request parameters, e.g.
{ "field": "body.amount", "above": 10000, "escalate": "review" }. - Delegation escalation: when a sub-agent acts on behalf of a user (
isDelegated) and the connection's policy setsdelegations.escalateConfirm: true,confirmescalates toreview.
Escalation only raises tiers to review or never, both of which deny the call; an escalated tier therefore surfaces as a denial with an escalation reason, not as a confirmation_required event.