AI & Automation5 min read

Test Agent Approval Against Changed Tool Arguments

S

Suneet Malhotra

Oct 29, 2026

β€’
1 views
Test Agent Approval Against Changed Tool Arguments - AI & Automation blog post
πŸ”§Agent EngineeringπŸ”§MCPπŸ”§QA Automation

An approval should authorize the action the person reviewed. If an agent changes the recipient, attachment, or destination afterward, the earlier approval should no longer permit execution. For QA, the useful test is to pause the workflow after approval, change one meaningful field, and verify that the write never reaches its destination.

This extends The Plan Is Not the Permission with a reproducible boundary test. Everything below is a proposed synthetic email workflow. The addresses, files, and outcomes are test fixtures, not production observations or employer data.

Where the approval sits

Imagine an assistant that prepares a release summary and offers to email it. The path is: draft the message, show a preview, record approval, queue execution, and call the mail adapter. A revision can enter between any two steps. A worker might reload the latest draft when it starts, even though the person reviewed an earlier version.

MCP can carry the tool invocation. Its 2025-06-18 tools specification describes calls containing a tool name and arguments, and recommends human oversight. It does not mandate a particular interaction design. A confirmation dialog alone therefore tells QA little about which arguments the executor will receive.

The established security principle is narrower: bind authorization to the significant transaction details and check it at execution. OWASP's transaction authorization guidance recommends server-side enforcement, invalidating authorization when transaction data changes, and a final gate before execution. The following fixture applies that principle to an agent integration.

Build an action you can compare

Create proposal P17: send release-summary.txt to reviewer@example.test from a synthetic project account. Store the exact recipient list, subject, message body, attachment bytes or immutable version, account, and tool destination. Give the proposal a revision identifier. Render the preview from that stored revision.

For this exercise, approval A17 refers only to P17 revision 1. It is not a general permission to send whatever the assistant later considers appropriate. The executor receives the proposal reference and resolves the approved snapshot through a trusted store.

A digest can help compare snapshots, but a hash is not permission. If a caller can replace both the payload and the expected digest, matching them establishes nothing. The approval record must be protected separately from editable draft state. Define canonical serialization if you hash structured fields, and include attachments by content or immutable version rather than filename alone.

Pause at the dangerous boundary

Use a deterministic barrier immediately before the executor performs its final authorization check. A barrier is a test-controlled pause that the test can release explicitly. It avoids relying on a lucky sleep interval to create the race.

Start each scenario from a fresh fixture. Approve revision 1, wait until the worker reaches the barrier, apply one mutation, and release the worker. Use an instrumented fake mail adapter with a destination ledger. Assert both the executor result and the recorded side effects.

ScenarioMutation after approvalRequired result in this fixture
BaselineNoneOne delivery of revision 1
Recipient changeReplace reviewer with outsider@example.testDenied; zero deliveries
Attachment changeReplace bytes but keep filenameDenied; zero deliveries
Tool destination changeSwitch the bound mail accountDenied; zero deliveries
New approvalApprove the changed revision explicitlyOne delivery of that revision

These are expected test outcomes, not measured results. The baseline matters: a system that refuses every request can pass all denial cases while being unusable. The new-approval case also proves that the workflow can recover without silently reusing A17.

Check what the person actually saw

Add an assertion before clicking approve: the preview recipient, attachment version, and account must match the stored proposal. Then compare the destination ledger with the same snapshot after execution. That produces a three-way check across preview, approval record, and actual tool arguments.

Do not reduce this to checking an approved boolean in a trace. In the synthetic fixture, capture proposal ID, revision, approval ID, actor, decision reason, adapter invocation count, and delivered content identity. Keep full message content inside the controlled fixture; production evidence needs its own retention and access rules.

Run a negative control in a local test version: deliberately remove the revision comparison while keeping the rest of the executor unchanged. The recipient-change scenario must now fail its zero-delivery assertion. Restore the comparison and require it to pass. This demonstrates that the suite observes a meaningful authorization defect rather than an unrelated validation failure.

A final check still leaves a race

Now add a second barrier after the final check but before the adapter reads its input. Mutate the original draft again. For the immutable-snapshot design proposed here, execution must still use the approved snapshot. If the adapter reloads mutable draft fields, the system has reopened the gap it just checked.

Choose and document a contract: execute the frozen approved action, or reject when its required version is no longer current. Either can be intentional. Executing changed content under the old approval is the failure this exercise targets. If the destination cannot enforce a resource version, document that limitation instead of claiming an atomic guarantee across services.

Duplicate delivery and uncertain outcomes need additional tests. Reusing the same approval after a timeout must not become a new action by accident. The related cancellation exercise explains why a stopped client does not establish whether a destination committed a write.

For the first regression test, keep the scope small: one fake adapter, one approval, one changed recipient, and an assertion on destination state. Which field in your agent workflow can still change between the preview and the write?

Share this post

You Might Also Like

Stay in the Loop

Get weekly insights on AI-driven QA, engineering leadership, and automation strategies.

No spam, ever. Unsubscribe anytime.