NewIntroducing Integrations
All guides
Glossary
Updated
3 min read
by Anlyon Team

What is approval drift in AI agent tool calls?

Approval drift is the gap between the request a reviewer approved and the request that runs. Where it comes from, the three ways it is caught, and what a bound approval does not cover.

glossaryapproval bindinghuman in the loop

Approval drift is any difference between the operation a reviewer approved and the operation that actually runs, such as a changed amount, recipient, target, action version or provider state between the decision and the call. The reviewer said yes to one thing. Something else ran.

Some writing calls the request-side case approval substitution. This glossary uses approval drift for every way the two can come apart, because they are caught by different mechanisms.

Where does approval drift come from?

An agent's tool call is rarely approved and executed in the same instant. A reviewer may take an hour. In that time:

  • The request changes. The agent retries with a different amount, or mutable run state is edited before the call resumes.
  • The definition changes. Someone edits the action, so the same input now produces a different HTTP request.
  • The credential changes. The key behind the action is revoked or rebound to another host.
  • The world changes. The file the reviewer read was edited by someone else, or the payment was partly refunded already.

An approval flag catches none of these. It records "yes" and lets whatever comes next run.

How is each kind caught?

DriftHow Anlyon handles it on a governed actionReceipt
A changed request sent with the reviewed previewRefused at admission with 409 PREVIEW_MISMATCHNone. No effect is created
The action was edited after reviewDispatch is refused (action_changed)refused
The approval, or its preview, expired before dispatchDispatch is refusedrefused
A secret is missing or no longer allows the requestDispatch is refused (credential_unavailable)refused
A GitHub file changed at the providerGitHub refuses the write on the reviewed blob SHAfailed

The first four are Anlyon's own state, checked by the bound approval: a digest of the request, target, versions, preconditions and expiry, recomputed before dispatch. The last is the provider's state, and it is caught by the provider's conditional write, not by Anlyon's digest.

Example

A reviewer approves a $20 refund for order 42. Before dispatch, the agent's loop sends the same call with $200 and the reviewed previewId. The request no longer matches the reviewed preview, so Anlyon refuses it at admission and nothing reaches Stripe. Getting the $200 refund requires a new preview and a new decision.

What a bound approval does not cover

  • Provider state without a conditional write. Stripe has no compare-and-set, so the refundable amount a reviewer sees is as of review. Resend and a declared action have no stale-state protection.
  • Calls outside Anlyon. A tool your own code calls directly is not routed through Anlyon and is not governed by it.
  • An action with no declaration and no adapter. It is approved on its request snapshot, which freezes what the approver reviewed.

Frequently asked questions

What is approval drift?

Approval drift is any difference between the operation a reviewer approved and the operation that actually runs, such as a changed amount, recipient, target, action version or provider state between the decision and the call. An approval that is not bound to the exact request cannot detect it.

How do you prevent approval drift for AI agents?

Bind the approval to the exact reviewed request and recompute that binding before dispatch, refusing on any difference. Use the provider's own conditional write where one exists, because a request can be unchanged while the resource behind it has changed.

Continue with a related task

Free tier, no credit card. One command if you use Claude or Cursor.

$ claude mcp add anlyon -- npx -y @anlyonhq/mcp-server