Skip to main content
Intelliger
Exact Approval for Agent Actions

How to Bind Human Approval to an AI Agent Action

Bind human approval to a canonical AI agent request digest so changes to amount, destination, scope or timing invalidate the approval before execution.

A human approval cryptographically bound to one exact agent request
Intelliger
9 minute read · Security and UX expert review required before publication

Human approval is meaningful only when it identifies what was approved. For an AI agent action, bind the approver, canonical request digest, policy context, expiry and allowed use count in one approval record. If the amount, destination, tool arguments or protected resource changes, require a new approval.

This pattern is a narrow part of AI agent authorization. It prevents a common gap in which a user approves a friendly summary and the system later executes different structured arguments.

Build the review object first

The reviewer needs the facts that change risk, not the whole model transcript.

type ApprovalRequest = {
  approvalId: string;
  requestDigest: string;
  action: string;
  resource: string;
  counterparty?: string;
  destination?: string;
  amountMinor?: number;
  currency?: string;
  evidenceRefs: string[];
  policyReason: string;
  expiresAt: string;
  maxUses: 1;
};

type ApprovalDecision = ApprovalRequest & {
  approverId: string;
  decision: 'approved' | 'rejected';
  decidedAt: string;
  authenticationContext: string;
  signature: string;
};

Create the digest from validated, canonical data. RFC 8785 defines a JSON canonicalization scheme that can support repeatable hashing when the implementation also defines its schema and signature profile.

Prevent summary substitution

An approval screen might say "Pay Northwind EUR 1,250." The protected request also contains an account destination, buyer entity, invoice digest, execution date and provider. A malicious or buggy agent can keep the friendly summary constant while changing one hidden field.

Show material fields directly from the canonical object. If the UI resolves human-readable names, keep the stable identifiers available and include them in the digest. Mark new destinations, unusual currencies and missing source evidence. Do not let model-written prose hide a mismatch.

Change after approvalRequired behavior
amount, currency or destinationinvalidate approval
action or resourceinvalidate approval
evidence display text onlypreserve digest, record presentation change
policy version becomes stricterre-evaluate and possibly reapprove
approval expiresreturn approval_required
duplicate execution attemptatomic use claim rejects the second attempt

Google's AP2 specification uses signed mandates to connect intent, cart and payment authorization. That protocol provides useful transaction objects. An enterprise still has to connect its own approver identity, supplier controls, policy and payment system.

Close the time-of-check gap

Immediately before dispatch:

  1. Recreate the canonical request from the arguments that will be sent.
  2. Compare its digest with the approval record.
  3. Revalidate expiry, revocation, approver authority and policy obligations.
  4. Atomically reserve the approval's single use and the operation's idempotency key.
  5. Dispatch through a protected adapter.
  6. Record the decision and observed response separately.

If the upstream times out, do not consume another approval to retry blindly. Query by the same transaction or idempotency key and reconcile the result. Approval answers "may this request be attempted?" It does not prove settlement or completion.

Test the ugly cases

Create one approved fixture and mutate each protected field. Test two concurrent consumers. Test an approver whose role is revoked between click and dispatch. Test clock skew at the expiry boundary. Finally, capture the network request from the adapter and verify its digest matches the approved object.

See transaction-constrained permissions and payment exact approval for adjacent implementations. Store approval evidence in the AI agent audit trail, with sensitive payloads minimized.

The OATI Receipt path demonstrates portable evidence concepts in developer preview. Production approval UX, identity assurance and policy require workflow-specific design and independent review.

Approval design questions

Should the approver see the model's explanation?

The explanation can help a reviewer understand why the agent proposed an action, but it must remain secondary to protected fields and source evidence. Show which text came from the model and which values came from systems of record. A persuasive explanation cannot compensate for an unverified destination or missing invoice. Preserve the explanation version if it influenced the decision, while binding approval to the canonical request object.

What counts as a material change?

Policy should define material fields by action. Amount, currency, destination, counterparty, resource, buyer entity and execution purpose are common examples. A display-label correction may not require reapproval if its stable identifier and protected meaning did not change. Compute the digest over every field the execution adapter uses. If a field can change risk or routing but is outside the digest, the approval is vulnerable to substitution.

How long should approval remain valid?

Set expiry from the volatility and consequence of the request, not reviewer convenience. A production change may be limited to a maintenance window. A supplier payment approval may need revalidation when destination or invoice status changes. Immediately before execution, check approval expiry, approver authority, policy version and current protected state. An unexpired timestamp alone does not keep a stale approval safe.

Can one approval authorize a batch?

Yes, if the approved object explicitly defines the batch, every item, aggregate limits, permitted mutations and use semantics. A vague approval for "today's invoices" is difficult to verify. Decide whether one failed item blocks the batch, whether additions require new approval and how retries preserve item-level idempotency. For high-risk items, separate exact approvals often produce clearer accountability and recovery.

What if approval service is unavailable?

Do not convert an unavailable approval lookup into allow. Low-risk workflows may queue the request until service returns. Material actions should stop unless a pre-issued, narrow and locally verifiable approval remains valid under documented outage policy. Record the failure and preserve the original proposal so the approver sees the same request later rather than a newly generated summary.

A useful usability test puts the original source, the model's summary and the protected request side by side. Ask reviewers which amount, destination, resource and expiry they believe they approved. If their answer differs from the canonical object, the problem is not cryptography. The approval screen is presenting the wrong decision. Fix that before increasing automation or shortening the review path.

Preserve rejected and abandoned proposals long enough to detect repeated probing under the applicable retention policy. Several small mutations around a threshold can reveal misuse that a single approved request does not show.