Skip to content

🚧 Roadmap — The capability described here is on the roadmap. The concepts and design are settled; interfaces and steps are subject to the final release.

When a human must approve: async authorization

By the end of this guide you will know:

  • Which operations should never be covered by a pre-granted authorization
  • What "the agent pauses, a human is reached out of band, and only this one action is approved" looks like as a flow
  • How to design for timeouts, rejections, and an approver who is unreachable

Prerequisites

  • You understand the three moments of human decision in Consent and approval
  • You have an out-of-band channel that reaches approvers (push, chat, email, SMS)
  • You know which operations need per-use approval — that is a product decision, not a technical one

Which operations need per-use approval

The test is simple: can it be undone?

CharacteristicExamplesPer-use approval?
IrreversibleTransfers, bulk deletion, outbound emailRequired
High value or high impactPurchases above a threshold, production changesRequired
Affects a third party's interestsSigning for a customer, ordering for a customerRequired
Reversible, small blast radiusQueries, drafting, internal reportsNot required — a pre-granted authorization is enough

Do not mark everything as requiring approval. Approval fatigue makes people click yes with their eyes closed, and at that point approval is theatre.

The flow: six steps of one approval

Take "an agent wants to execute a transfer above the threshold":

  1. Agent → your app: request the transfer.
  2. Your app determines this operation hits an approval policy (amount, type, counterparty) and — instead of executing — raises an approval request that states three things:
    • What the agent wants to do (payee, amount, purpose)
    • What it affects (which account it leaves, whether it can be undone)
    • Why you are being asked now (which policy fired)
  3. The out-of-band channel pushes the request to the accountable person. The agent is suspended: holding no resources, not retrying.
  4. The accountable person approves or rejects on their own device. The approval screen must show full context — the approver has to be able to understand what they are approving.
  5. Approved → issue an authorization scoped to that one operation: bound to this transfer's parameters, single use, short-lived. Rejected or timed out → the operation ends and the agent receives an explicit failure reason.
  6. Either way, the approval event joins the audit chain: who approved, when, and with what parameters (see Audit and accountability chain).

The key design point: the authorization is bound to the operation's parameters. If what was approved is "transfer 5,000 to A", that authorization cannot transfer 5,000 to B, nor 50,000 to A. Change a parameter and it needs a new approval.

Design guidance

Deny by default. A timeout without approval means rejection, not "carry on". Write that into policy and leave no configuration option.

Give approval requests an expiry. Is a transfer requested an hour ago still appropriate to approve now? Give requests a short window and let them lapse.

The approver cannot be the requester. Forbid self-approval structurally — this matters especially with agents, because the "requester" may be an agent whose Owner happens to also be the approver.

Have a degradation path. When the approver is on leave, the channel is broken, or the system is unavailable, the agent should stop and fail loudly rather than route around approval.

Standards and protocols

On the standards side this pattern maps to CIBA (Client-Initiated Backchannel Authentication, OpenID Foundation): the backend initiates the authentication request and the user confirms out of band. It exists precisely to solve the structural problem that the approver is not inside the agent's session — an agent has no browser to redirect, so the backend has to go find a human.

Expressing the authorization's scope follows the same idea as RFC 9396 Rich Authorization Requests: declare not just a scope, but the specific resource and parameters this authorization is bound to.

FAQ

Will approvals make the agent slow? Yes — by design. Operations that need approval were never supposed to be fast. Narrow the approval surface to genuinely irreversible operations and let everything else run on pre-granted authorization.

Can one approval cover similar operations afterwards? You can implement that as policy ("same counterparty, below the threshold, no approval within 24 hours"), but it must be explicitly configured, auditable and revocable. Do not enable it by default.

What should the agent do while suspended? Design it as a stateless wait: the agent records the request ID and exits, then resumes on a callback or a poll when the decision arrives. Do not hold a connection open waiting.

Next steps