A person approves a refund for one order. The agent later submits a different amount, retries after a timeout, or routes the action to another account. The approval can be authentic and the final action still unauthorized. The missing property is a durable binding between the reviewed request and the effect that actually executes.
Agent workflows make this familiar systems problem more visible. Plans evolve, tool arguments stream, humans respond asynchronously, and workers retry. Authorization is therefore a lifecycle, not a single yes-or-no event. Every transition needs an explicit rule for what may change and what must remain fixed.
Define the invariant before the token
The basic invariant is that a granted authority covers only the authenticated principal, tenant, connection, operation, resource, and material arguments that were evaluated. It also has a validity period and applicable ceilings. A change outside that scope requires a fresh decision.
For a reference execution permit, bind those attributes using a canonical representation and integrity protection appropriate to the architecture. Include issuer and audience validation, a unique identifier, expiry, and the policy revision. Cryptographic integrity prevents undetected edits to the permit; it does not prove that the requested business action was safe.
OWASP recommends checking permissions for each request [1]. Our systems-level inference is that a request resumed after approval or queue delay is still a request requiring a valid scope at dispatch. The original grant remains evidence, but its conditions must still hold when the external effect begins.
Argument substitution changes the approved action
Consider a reviewed message to an internal address with a short attachment. Before execution, the recipient becomes external or the attachment changes. If the dispatcher checks only an approval identifier, it can execute an action the reviewer never saw.
Bind material fields rather than relying on a display label. Resolve resource aliases and destination identities before review, and verify them again at execution. A dynamic alias can change its meaning without the visible tool name changing. The policy should define when that resolution must be pinned or refreshed.
Canonicalization is security-sensitive. Equivalent encodings should compare consistently, while meaningful differences must remain visible. Decide how arrays, numeric formats, omitted defaults, URLs, and provider-side aliases are represented. Do not blindly hash raw JSON and assume the hash captures the actual business effect.
Time changes authority even when arguments stay fixed
An approved operation may wait in a queue while the workload is disabled, the connection is revoked, or the policy changes. A short permit lifetime bounds the delay but does not necessarily provide immediate revocation. State which conditions require a fresh online check at dispatch.
Reference designs can use grant versions or revocation state alongside permit validation. The shared state needs its own availability contract. If the system cannot establish that a consequential grant is still valid, it should hold the action according to policy rather than silently fall back to an old cached allow.
Distinguish policy evolution from retroactive invalidation. Some organizations may allow a short-lived permit to finish under its original revision; others require new policy to apply immediately. Either choice has implications for emergency revocation. Document and test the intended semantics.
| Transition | What must remain bound | Failure case |
|---|---|---|
| Review to approval | Exact material scope and reviewer | Approval applies to changed recipient |
| Approval to queue | Principal, tenant, expiry, ceilings | Grant survives retirement indefinitely |
| Queue to dispatch | Current resource and connection | Execution uses another account |
| Dispatch to retry | One intended business operation | Duplicate external effect |
Single-use consumption must be atomic
If two workers validate the same unconsumed permit at the same time, both may attempt execution. A check followed by a separate write is not enough. The consume operation needs an atomic state transition in the enforcement domain, with a defined behavior under retries and shared-state failure.
Scope replay identifiers to the correct authority domain. Tenant, issuer, audience, and operation identity may matter depending on the system. Do not let a permit accepted for one service become reusable at another service that shares a parser or signing key.
Atomic consumption prevents duplicate dispatch through that gate. It does not by itself guarantee exactly-once effects at an external provider. A worker can crash after consumption but before sending, or send successfully and lose the response. Those cases require a dispatch record, provider idempotency where available, and reconciliation.
Model the ambiguous outcome
An uncertain provider result is neither success nor confirmed failure. Preserve the provider request identifier or idempotency key and query the authoritative state when possible. Do not ask the agent to infer the result from conversational context and then issue the operation again with a new identifier.
Separate authorization expiry from operation reconciliation. A permit may expire while the team is determining whether the provider accepted the original dispatch. Expiry should stop a fresh action; it should not erase the evidence or prevent the system from resolving an already attempted effect.
For providers without reliable idempotency or lookup, define a manual recovery path. Some workflows can tolerate duplication or compensate safely; others cannot. The limitation belongs in the integration contract and approval experience, not in a hidden implementation assumption.
Proposed adversarial validation matrix
Create a fixture provider that records accepted actions and can simulate delayed responses, lost responses, and duplicate delivery. Approve one synthetic operation, then change each material field independently. Verify that changed tenant, principal, connection, target, amount, destination, and payload are rejected or reauthorized as specified.
Submit the same permit concurrently through multiple workers and instances. Restart a worker around the consume and dispatch transitions. Disable shared replay state and observe the documented fallback. Verify both local decision records and the provider's accepted-effect count.
Test expiry boundaries and revocation during the queue delay. Include a legitimate retry using the same business-operation identifier, and a legitimate second operation that must receive a different identifier. These benign cases catch controls that prevent replay only by breaking normal recovery.
Evidence and conclusions
Record the reviewed request hash or canonical scope, approval identity, permit identifier, policy revision, dispatch attempt, provider identifier, and reconciliation result. Store secrets and sensitive payloads separately under restricted access. The audit should explain what was approved and what happened without requiring raw credentials.
A successful test establishes a bounded implementation property under the tested concurrency and failure conditions. It does not prove arbitrary provider behavior or eliminate every semantic mismatch between a tool and its downstream API. The essential discipline is to preserve authority across time, transformation, and retry. Approval is one event in that chain; execution is where the chain must still hold.