The direct answer
An approval should authorize a specific action snapshot, including its destination and significant arguments, rather than a conversation or an agent’s general plan. Store that snapshot in a trusted service, authenticate the approver, and allow execution only when the current request still matches an unused, unexpired approval.
Make the approval screen describe the consequence
“Approve the agent's next step” is difficult to review because it hides what will happen. Show the consequence using fields that matter for the operation. For a message, show recipients, subject, body, and attachments. For a payment, show the verified recipient, amount, currency, and relevant fees or terms. For a deletion, show the exact objects, versions where available, and whether recovery is supported.
OWASP's transaction authorization guidance calls for users to acknowledge significant transaction data and for the service to enforce authorization. The design below applies that principle to agent tool actions; it is an implementation outline, not a banking compliance procedure.
Use a stored action snapshot
Suppose an agent prepares a synthetic invoice reminder to [email protected] with one attachment, invoice-042.pdf. The application creates action A-42 from validated data and stores it server-side. The review interface loads A-42 from that stored record. It does not trust a second copy of the body supplied by the agent when approval is requested.
Action A-42
Operation: message.send
Recipient: [email protected]
Subject: Invoice 042 reminder
Body version: 3
Attachment version: invoice-042, version 2
State: pending reviewThe domain and document names are fictional. The important property is that the reviewed content and executable content refer to the same immutable snapshot. If the recipient, body, attachment, or other significant field changes, create a new review. A digest can help detect changes, but a digest alone does not authenticate an approver or make an approval single use.
Treat approval as a controlled state change
A practical service can model the action as pending, approved, executing, succeeded, failed, expired, or cancelled. Define the permitted transitions explicitly. The model may propose an action, but it cannot set the approver identity or promote its own proposal to approved.
At approval time, verify that the signed-in person can authorize this action for the relevant account. Store the action identifier, approver, expiry, policy version, and review outcome. At execution time, verify current authorization and policy again. A person may lose access after approving, or a recipient may become prohibited before execution.
The approval record should not be a reusable “yes” attached to a conversation. An approval to send A-42 does not authorize A-43, a later reminder, or an expanded recipient list.
Handle concurrency and retries deliberately
Two workers may pick up the same approved action at nearly the same time. Claim the approval with an atomic operation shared by all workers so only one begins execution. A check followed by a separate update can allow both workers through. OWASP explicitly discusses single-use authorization and atomic consumption in its transaction authorization guidance.
Approval consumption and the external effect still form separate failure points unless your architecture makes them transactional. A worker can claim an approval and crash before sending. It can also send successfully and lose the response. Track an execution identifier and use the provider's supported idempotency mechanism when available. If the result is uncertain, reconcile it before retrying. Do not call an unknown outcome a confirmed failure and send again automatically.
Adjust the snapshot for each action type
The same review pattern needs different significant fields.
- Messages: Include every recipient class, attachments and their versions, and the actual body. A display name is not sufficient to identify an address.
- Payments: Bind the payee identifier, amount, currency, account, and any consequential options. A new payee or changed amount should trigger a new review.
- Deletions: Expand selections before approval. “Delete old files” can select different objects later. Prefer a fixed object list with versions, plus a stated recovery path if one exists.
For large batches, a concise summary can help navigation, but reviewers still need access to the complete scope. Define whether approval covers all items atomically or a fixed set of individual operations, and expose partial completion accurately.
Check the failure cases with synthetic actions
Before enabling a real external effect, run a table of expected outcomes: an unchanged approved action executes once; a changed recipient fails; an expired approval fails; an unauthorized approver fails; two concurrent workers cause only one execution attempt; a provider timeout becomes an uncertain state that requires reconciliation. Also verify that a direct API call cannot skip the review transition.
Human review can miss a deceptive address or an inappropriate action. Approval is one control alongside least privilege, destination policy, rate limits, recovery, and monitoring. It is not proof that a payment is legitimate or a deletion harmless. Boundary's planned model-request checks do not constitute a deployed approval engine for messages, payments, or file operations.
Primary sources
Official references supporting the guidance. Examples in this guide are synthetic and are not reports of a production incident.