Agent Human Approval Gate Design: From Confirmation Dialogs to Auditable Authorization Contracts
Human confirmation is not a simple "continue?" button. This article explains the action summary, scope, expiry, permission re-check, and audit fields that an Agent write-operation approval should contain, to prevent confirmation from being misused.
Key Points
- Topic Focus: AI Agent、MCP、DevOps
- Suitable for: indie hackers, full-stack engineers, AI application developers
- Core value: quickly understand background, practical paths, common pitfalls, and engineering advice
When an Agent is about to delete resources, send emails, create paid tasks, or modify production configuration, a common product approach is to pop up a "Confirm execution" button. This UI reduces accidental operations, but it does not equal real authorization design. If the confirmation record is not bound to a specific action, operator, resource scope, and validity period, an attacker or an erroneous retry can reuse that one consent for a different operation.
It is more appropriate to treat approval as a short-lived authorization contract. The model proposes a plan; a deterministic service normalizes the plan into auditable actions; then a person with permission issues a one-time confirmation. The confirmation only proves "this person agrees to execute this content summary during this time window"—it does not prove that the model may freely execute similar actions afterwards.
The Approval Target Must Be a Normalized Action
Do not let the frontend directly display the model's natural language and then pass back "confirmed" to the server. The server should first generate a stable approvalPayload: tool name, target resource ID, field diffs, estimated cost, dependency conditions, request version, and hash. For example, "delete old data" is too broad; "delete the 18 drafts before 2024-01 in project p_42, expected to be unrecoverable" is an action that can be judged.
A simplified approval record can contain fields like the following:
{
"approvalId": "apr_01J...",
"runId": "run_01J...",
"actionHash": "sha256:...",
"actorId": "user_42",
"requiredScope": "project.records.delete",
"expiresAt": "2026-07-18T12:10:00Z",
"singleUse": true
}
The input to actionHash must come from the server-side normalized structure, not from arbitrary JSON passed by the frontend. After receiving the confirmation, the executor recomputes the hash and verifies that the resource version, target tenant, and tool parameters are still consistent; any change in any of these must invalidate the old confirmation and require re-approval.
Run Permission Checks Both Before and After Approval
A frequently overlooked risk is "had permission at approval time, but the permission has changed by execution time." For example, an employee is removed from the project after confirmation, or an administrator revokes a high-risk scope. Before execution, the current identity and resource permissions must be reloaded; the approval record must not bypass real-time authorization. Approval is only a necessary condition, not the only condition.
This also explains why the approver and the executor are not necessarily the same person. Some flows allow a business owner to confirm and a backend worker to execute, but the worker still runs under a restricted service identity, and records approvedBy and executedBy separately. For cross-tenant support operations, a ticket number or reason should also be recorded, to prevent "admin confirmed" from becoming an unlimited pass.
Write Risk Tiering into the Execution Policy
Not every tool needs confirmation of the same strength. You can split the policy by side effect: pure reads need no approval; reversible low-risk changes require single-person confirmation; irreversible, cross-system, or high-value operations require secondary confirmation, a delay window, or two-person approval. The key is that the policy is determined by tool metadata and business rules, not by the model saying "this is not dangerous" on its own.
The confirmation page should display facts beyond the model's text: target system, resource count, impact scope, cost ceiling, whether it is reversible, expiry time, and the observable result after execution. Do not bury key differences in lengthy explanations; if the plan will affect a thousand records, the number must be more prominent than the natural language.
Handle Double Clicks, Expiry, and Revocation
The approval token should be single-use. After it is consumed the first time, subsequent identical requests return a "consumed" status rather than writing again. User cancellation, permission changes, plan recomputation, resource version changes, and timeouts should all explicitly revoke the approval. If the tool is an async task, consuming the approval and creating the task should happen within the same transaction boundary, to avoid the gray state of "confirmation consumed but task not created."
Launch validation can use four scenarios: after one parameter is tampered with, the old confirmation must fail; the same confirmation submitted repeatedly produces only one operation; after the approval expires, the request is rejected; after the user's permission is revoked post-approval, the executor still rejects. When all four scenarios pass, the confirmation has gone from a UI interaction to a real authorization contract.
The Approval Policy Itself Must Be Traceable
Tool risk levels and approval rules will change. An export action that allows single-person confirmation today may require two-person approval tomorrow due to a data classification adjustment. Do not save only the final approvalId; also save the policy version, thresholds, and risk labels that matched at the time. Otherwise you cannot answer afterwards "why did this one only need single-person confirmation," nor can you safely replay historical tasks.
After a policy change, unconsumed approvals should be handled according to the change type: if it is only a display text update, they can be kept; if scope, cost ceiling, resource scope, or number of approvers changes, the old confirmation should be revoked and re-issued. Put this judgment in the policy engine, not let the frontend guess based on page refresh time. This way the approval system can protect a single operation while also keeping evidence intact as rules evolve.
Further Reading
Related
Related Content
Article
From Copilot to Codex: AI Coding Tools Enter the Agent Era
Technical trends, engineering practices, and indie-developer perspectives around AI, AI Agents, and Vibe Coding.
Article
Why Does MCP Matter? Understanding the AI Tool Protocol
Technical trends, engineering practices, and an independent developer perspective on MCP and AI Agents.
Article
Core Architecture of AI Agents: Planning, Memory, Tools, and Execution
Technical trends, engineering practices, and independent developer perspectives around AI Agents and large language models.
Article
How Should RAG and Agents Work Together?
An independent developer's perspective on technical trends and engineering practices involving RAG and AI agents.