Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Confirmation Model

Every mutating action an agent can take resolves to one of four confirmation tiers. The tiers appear under three different vocabularies depending on where you configure them (connection policies, custom tool metadata, or the request tool call itself), but they describe a single underlying model. This page maps the vocabularies to each other; the pages for Connections, Tools, and Guardrails cover each surface in depth.

The Four Tiers

TierBehavior
Auto-approveThe agent executes without user interaction; the default for reads.
ConfirmExecution pauses. The runtime emits a confirmation_required event and waits for approval before running the call.
ReviewThe agent cannot execute the call itself; it requires human review through the operator surface.
NeverThe operation is blocked entirely (only callable by other tools, never by the agent).

One Model, Three Vocabularies

SurfaceWhere configuredVocabularyTier it resolves to
Connection endpointpolicy.json confirmomitted / true / "review" / "never"auto / confirm / review / never
Custom tooltool.ts exposure.kindopen / operator-gated / requires-confirmationauto / operator UI only / confirm (recorded at the review tier)
Request tool callintent 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.

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 call pauses for explicit approval before executing (an optional prompt field customizes the message). The loader records these tools at the "review" confirm tier.
  • operator-gated: the tool runs only from operator UI actions, never autonomously. Pair it with llm_callable: false so the model does not see the tool at all.

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:

  1. The agent calls with intent: 'write'. No request is sent; the tool returns a preview and the runtime emits confirmation_required to the client.
  2. The user approves (the SDK chat surfaces render this automatically).
  3. The agent calls again with intent: 'confirmed_write', which executes the previewed request.

Endpoints at the review or never tier deny the call regardless of intent.

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

A configured tier is a floor, not a ceiling; two rules can raise it 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 sets delegations.escalateConfirm: true, confirm escalates to review.

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.