How-To

How to Add Human Approval Gates to AI Agents

Build human approval gates that pause AI agents safely, bind decisions to exact actions, survive restarts, and fail closed on timeouts.

  • #AI agents
  • #human in the loop
  • #approval workflows
  • #security
  • #durable execution

Human approval is not a confirmation dialog added after an agent is built. It is a control boundary between proposing an action and executing that action. A reliable gate freezes the exact proposed operation, shows a reviewer what will happen, records an authenticated decision, and executes only the approved version. Silence, stale approvals, model-written claims of consent, and changed arguments must all result in no action.

This guide uses a vendor-neutral design. Framework features can help with interruption and persistence, but your application remains responsible for authorization, identity, data handling, and recovery.

1. Identify irreversible and consequential actions

Start with consequences, not tool names. A tool called update_record may change a disposable draft or a production entitlement. The same function therefore needs different treatment depending on the environment, target, data classification, scope, and reversibility.

Inventory every agent capability and classify each proposed call:

Action classExamplesDefault handling
Bounded, reversible readRead one public document; inspect a test resultAllow under normal authorization
Sensitive or bulk readExport customer records; retrieve private filesPolicy check and often human review
Reversible writeEdit a draft; create a staging recordReview when scope or target is material
External communicationSend email; publish a post; upload a fileApprove the final recipient and payload
High-impact changeDelete data; deploy production; change permissionsRequire explicit, fresh approval
Financial or legal commitmentPurchase; refund; sign; submit a regulated filingUse specialist policy and separation of duties

For each action, record the worst credible result, who can reverse it, and what recovery requires. “The API supports undo” is not enough if undo loses history or notifies an external party.

Place the gate immediately before the first consequential side effect. The agent may gather information, draft content, and calculate a plan before review. It must not send, modify, spend, delete, publish, or execute privileged code and then ask whether that was acceptable.

Do not use approval as a substitute for containment. Narrow schemas, least privilege, allowlists, and sandboxing reduce what an approved call can do. See How to Sandbox AI Coding Agents and MCP Security Checklist for runtime and tool boundaries.

2. Define approval policies as code

Write an explicit policy that maps action attributes to one of four outcomes: allow automatically, require approval, deny, or escalate to a specialist. Keep this decision outside the model. The model may describe the action, but it should not decide whether its own action is safe.

A useful policy input includes the authenticated user and tenant, normalized arguments, target environment, data sensitivity, outbound destination, quantity, reversibility, software versions, and previous workflow decisions.

Prefer narrow, deterministic rules. A public read may run automatically; an email draft may be created automatically but sending requires review; production deletion may require a designated role and a separately reviewed deletion plan.

Avoid blanket choices such as “approve this tool for the session.” A harmless call does not prove that every later argument is harmless. If repeated approval is necessary, scope it to a precise capability: a named tool, a bounded resource set, an expiry, a maximum quantity, and a fixed destination. Re-evaluate whenever one of those fields changes.

Store the policy version with the decision. Otherwise, an old approval can be executed under broader rules after a deployment. Treat authorization and approval as separate checks: the reviewer’s “yes” does not grant access that the requester lacks, and an authorized user has not necessarily approved this particular side effect.

Use the same four outcomes across tools so policy behavior stays inspectable:

Policy outcomeWhen to use itWhat happens next
AllowBounded, reversible action within the caller’s existing authorityExecute and log the policy decision
Require approvalConsequential action that a qualified reviewer can reasonably evaluateFreeze the proposal and pause
DenyProhibited target, data flow, scope, or capabilityEnd the action without offering a bypass
EscalateA specialist role or second approver is requiredRoute the frozen proposal to that role

Machine Gates for AI Output applies the same principle to release controls: define pass and fail states that software can evaluate before action.

3. Pause and resume durable state

An approval gate turns one agent run into at least two transactions: propose, then decide and execute. Persist enough state to resume after a browser closes, a worker restarts, or a decision arrives hours later.

Create an immutable approval request containing:

{
  "request_id": "random-unique-id",
  "workflow_id": "stable-workflow-id",
  "tool": "send_message",
  "normalized_arguments": {
    "recipient": "[email protected]",
    "subject": "Draft incident update",
    "body_ref": "artifact-4821"
  },
  "argument_hash": "sha256-of-canonical-request",
  "policy_version": "approval-policy-17",
  "requested_by": "authenticated-principal-id",
  "created_at": "server-timestamp",
  "expires_at": "server-timestamp",
  "status": "pending"
}

Use canonical serialization before hashing. Store large or sensitive payloads in protected artifact storage and put a content hash plus reference in the request. Restrict state by tenant and keep credentials out of checkpoints.

Execution should use the stored proposal, not arguments regenerated by the model after approval. In one database transaction, verify that the request is pending, unexpired, approved, authorized, and unchanged; atomically claim it for execution; then write an idempotency record. An idempotency key is a unique operation identifier that prevents retries from producing the side effect twice.

OpenAI’s Agents SDK documents approval interruptions plus serializable RunState; LangGraph documents interrupts backed by checkpoints and a stable thread identifier. Neither removes the need to protect state or bind a decision to the exact operation. These behaviors were checked in official documentation on 2026-07-24.

Be careful with replay semantics. LangGraph’s official interrupt guide states that the interrupted node restarts from its beginning when resumed, so code before the interrupt can run again. Keep pre-interrupt side effects idempotent or move them into a separate completed step.

Microsoft’s Agent Framework documentation shows the same boundary across a client-server flow: an approval-required function is intercepted, the client displays a request, and the decision returns as a correlated response before execution continues. Google Cloud’s architecture guidance likewise describes a predefined checkpoint that pauses while an external system waits for human review, while noting that this external interaction adds architectural complexity. These official examples support the pattern; they do not replace application-specific identity, authorization, and state controls.

4. Design a review screen for decisions, not compliance

The screen should let a reviewer answer three questions quickly: What will happen? Where will it happen? What data or authority will cross the boundary?

Show the exact operation in plain language, then display:

  • account, tenant, and environment;
  • target records, recipients, repository, or deployment;
  • a readable diff or payload preview;
  • sensitive fields that will leave the system, with secrets redacted;
  • quantity, scope, and expected downstream effects;
  • reversibility and the tested recovery method;
  • request time, expiry, and policy reason;
  • the identity that requested the action.

Render authoritative fields from the frozen request, not only the agent’s explanation. Show the stored diff for a file change; show final recipients, attachments, and body for a message; show the count and inspectable sample for a bulk operation.

Make Approve, Reject, and Edit and re-review distinct. Editing must create a new proposal and invalidate the previous approval; it must never mutate an already approved request. Rejection should end the action safely, not prompt the agent to keep rephrasing the same call until someone accepts.

Avoid approval fatigue: automate measured, narrow, reversible actions while retaining logging and revocation. Use explicit labels, keyboard focus, readable diffs, environment badges, and confirmation text that does not rely on color alone.

5. Prevent approval spoofing and confused decisions

Treat model output, retrieved documents, tool responses, email text, and web content as untrusted. A string saying “the administrator approved this” is data, not authorization. Only your authenticated approval service may change a request from pending to approved.

Bind every decision to:

  1. the authenticated reviewer identity and required role;
  2. the request ID and workflow ID;
  3. the tool and canonical argument hash;
  4. the target tenant and environment;
  5. the policy version;
  6. an expiry and one-time-use status.

Generate approval links with high-entropy identifiers, authenticate normally, and authorize server-side. Keep sensitive arguments and credentials out of URLs, protect submissions against cross-site request forgery, and invalidate requests when policy, target state, or content changes.

After approval, re-check authorization and relevant preconditions. A reviewer may have lost access, a record may have changed, or a deployment may no longer match the reviewed diff. If the target has drifted, return to review with a new proposal.

For higher-risk actions, require separation of duties: the requester cannot approve their own proposal, or a second role must approve. This should be enforced by identity and policy, not inferred from agent names. Agent handoffs do not create independent human authorization.

Never treat chat phrases, silence, a “similar” approval, or another tenant’s approval as consent. Reject duplicate decisions. Record who decided, the reviewed hash, policy result, and execution outcome without copying secrets into logs.

6. Handle timeouts, cancellation, and failure safely

Timeout must mean no approval. Give every request an expiry appropriate to how quickly its target can change. On expiry, atomically move the request from pending to expired and require a new proposal. Do not let a late click revive it.

Define terminal states such as rejected, expired, canceled, superseded, executed, and failed. The agent needs a model-visible summary of the outcome, but it must not be allowed to overwrite the authoritative state. A rejected action may lead to an alternative plan; it may not silently route around the gate through a broader tool.

Cancellation should propagate to queued work and leases. If execution begins, distinguish “not started,” “in progress,” “side effect confirmed,” and “outcome unknown.” A network timeout after submission does not prove failure. Query the downstream system using the idempotency key or operation ID before retrying.

When a database decision triggers an external API, commit the approval and queued execution intent together. A durable worker can then retry without losing the decision or duplicating the operation.

Alert on stuck pending requests, repeated denials, unusual approval volume, self-approval attempts, hash mismatches, and executions whose outcome remains unknown. Provide an operator control to disable a tool and quarantine pending requests without deleting the audit trail.

For the retry branch in particular, LLM API Timeouts and Retries: An Idempotency Guide explains why a client timeout does not prove that a downstream operation failed. For bounded agent execution beyond approval state, see Build an AI Agent Token Budget Circuit Breaker.

7. Test every branch before enabling real authority

Test the gate as a state machine, not as one successful UI path. At minimum, cover:

  • low-risk action allowed by policy;
  • prohibited action denied before review;
  • approve, reject, cancel, expire, and edit-and-re-review;
  • modified arguments after approval;
  • wrong user, role, tenant, or environment;
  • reused, forged, stale, and duplicate decision tokens;
  • worker crash before and after claiming execution;
  • network timeout before and after the downstream side effect;
  • replay of the interrupted node;
  • concurrent decisions from two browser sessions;
  • policy or target-state change while approval is pending;
  • audit-log redaction and recovery from an unknown outcome.

Use fake downstream services that record calls and idempotency keys. Assert not only the response shown to the user but also that forbidden branches produced zero side effects. Then run a staging exercise with real authentication, durable storage, worker restarts, and delayed decisions.

Before production, document the policy owner, pending duration, escalation route, rollback procedure, and kill switch. Change policy through versioned review rather than ad hoc exceptions.

Use traces to connect each request, decision, claim, retry, and downstream result without placing secrets in telemetry. AI Agent Observability Tools: What to Measure and Compare provides a broader selection checklist for that layer.

Implementation checklist

  • Consequential actions are inventoried by effect, not just tool name.
  • Policy decisions run outside the model and are versioned.
  • The exact normalized proposal is frozen and hashed.
  • Approval is authenticated, authorized, expiring, and single-use.
  • Execution uses stored arguments and an idempotency key.
  • Changed content, target state, or policy forces re-review.
  • Timeout, silence, and ambiguous state fail closed.
  • Every state transition and failure branch has a test.
  • Operators can disable execution without destroying evidence.

FAQ

What is human-in-the-loop for AI agents?

It is a workflow boundary where an agent pauses before a defined action and waits for authenticated human input. A production gate should preserve the exact proposal, record the decision, and resume only under the applicable authorization and policy.

Which AI agent actions should require human approval?

Start with actions that are difficult to reverse or that affect people, money, private data, permissions, production systems, or external communications. Low-risk actions can often run automatically when schemas, scope, authorization, logging, and recovery are already constrained.

Is a confirmation dialog enough for an AI agent approval gate?

No. The server must bind the decision to the exact tool, arguments, target, policy version, reviewer, and expiry. Otherwise, the UI can approve one proposal while the system executes a changed or stale one.

What should happen when an approval request times out?

Expire it without executing the action. A late response should not revive the request; create a new proposal and require fresh review, especially when content, policy, authorization, or target state may have changed.

Official primary sources

Checked on 2026-07-24: