AI Agent Human Approval Workflows That Resume Safely
Place approval immediately before a consequential tool call, after the system has resolved concrete arguments and shown the reviewer the effect. Persist the paused run, bind the decision to that exact call, revalidate authority and freshness, then resume without regenerating the approved action.
Gate the action, not the entire conversation
| Action class | Default control | Reviewer must see | After decision |
|---|---|---|---|
| Read-only, low sensitivity | Policy check; no manual gate when clearly authorized. | Scope and data class in audit trail. | Execute and log bounded result metadata. |
| External communication | Preview and per-call approval. | Recipients, final content, attachments, and identity. | Send exact approved payload or require a new review. |
| Financial or contractual | Strong identity, separation of duties, and transaction approval. | Amount, counterparty, account, rationale, limits, and rollback limits. | Revalidate then execute once with idempotency. |
| Destructive or irreversible | Explicit approval plus backup or recovery evidence. | Targets, blast radius, dependencies, and irreversible portion. | Stop if state drifted since review. |
| Production or privileged | Named authorized reviewer and narrow temporary authority. | Deployment target, change, validation, rollback, and incident owner. | Expire elevation after the bounded action. |
| Ambiguous or unsupported | Clarify or refuse rather than request blind approval. | Missing facts and available safe alternatives. | Resume only from a new, complete proposal. |
Build a decision packet a human can actually review
Approval belongs after the model proposes a tool call and application code validates its schema, but before the side effect. The packet should name the requesting user, acting agent, tool, normalized arguments, target resource and deployment, source evidence, expected effect, risk class, policy checks, and rollback or compensation path. Hide private values while preserving enough detail to distinguish one transaction from another.
The OpenAI Agents SDK human-in-the-loop guide demonstrates this shape: tools declare when they require approval, a run surfaces pending calls as interruptions, and serialized run state can be approved or rejected before the original run resumes. The important design principle is not a particular SDK method; it is that the decision binds to a concrete pending call rather than a vague plan.
Keep authorization separate. OAuth scope or a valid user session proves the caller may request an operation, while approval confirms a particular consequential instance. The MCP authorization guide covers the outer resource boundary. Neither layer permits the model to expand its own authority.
Resume from durable state without changing the deal
Persist the pending call ID, normalized arguments, policy version, workflow version, authority envelope, state version, expiry, and approval decision. On resume, confirm the decision matches the same call and reviewer authority. Recheck mutable preconditions such as inventory, account status, target revision, or deployment. If a material field changed, invalidate the approval and present a new packet.
Do not ask the model to recreate an approved command or message from memory. Execute the exact approved payload. Use idempotency for mutations and read back the end state. If the result is uncertain, pause for investigation instead of asking for a second approval that could duplicate the action. The patterns in AI agent state management make this restart-safe.
Rejection needs equal design. Return a structured reason, leave the prohibited state unchanged, and route the workflow to revise, cancel, or escalate. A reviewer should be able to reject one pending call without accidentally approving siblings. Broad persistent decisions should be rare, scoped to a tool and run, and unavailable for high-impact action classes.
Approval workflows that only look safe
- Approval before arguments exist: the human approves an intention, then the model chooses the target. Gate the normalized call.
- Rubber-stamp prompts: repetitive low-context dialogs train reviewers to click through. Show consequence, evidence, difference, and risk.
- Approval reused after drift: resource state changes while the run waits. Add expiry and precondition revalidation.
- Model interprets the decision: “approved” is fed back as prose and the model invents a new action. Bind the decision to a call ID and payload hash.
- Reviewer lacks authority: any logged-in user can approve a production change. Enforce role, tenant, and separation-of-duties policy in code.
- Rejected call loops: the agent resubmits the same action with cosmetic changes. Record denial, cap attempts, and require materially changed evidence.
- Approval is called a guarantee: a human can miss risk. Keep least privilege, validation, isolation, monitoring, and rollback around the gate.
OWASP's Excessive Agency guidance treats human approval as one mitigation beside reduced functionality, permissions, and autonomy—not a substitute for them.
An approval workflow implementation sequence
- Classify actions. Inventory tools and map each to impact, data sensitivity, reversibility, required role, and approval policy. Default unknown actions to blocked.
- Define the interruption contract. Specify when validation stops execution, which fields are persisted, how reviewers are notified, and terminal behavior for approve, reject, expire, and cancel.
- Build the review packet. Present final arguments, target, effect, evidence, risk, policy result, and rollback in human language. Keep private data and hidden prompts out.
- Bind and authenticate decisions. Associate reviewer identity, decision, time, call ID, and payload hash. Enforce role and tenant rules in owned code.
- Revalidate on resume. Check policy, authority, expiry, target version, and business invariants. Execute the approved payload once or invalidate it.
- Test every branch. Cover approval, rejection, timeout, duplicate click, stale state, unauthorized reviewer, partial completion, and uncertain tool result. Use synthetic systems.
- Observe and improve. Track wait time, rejection reasons, stale approvals, duplicate prevention, and incidents without judging reviewers by approval rate. Connect high-risk cases to an AI kill switch and the agent evaluation suite.
Primary and official sources
- OpenAI Agents SDK: Human-in-the-loop — official pause, interruption, approval, rejection, serialization, and resume behavior.
- OWASP LLM06: Excessive Agency — primary guidance on limiting capability, permission, and autonomy and requiring authorization for consequential actions.