Before an AI agent gets a real tool, prove the tool can say no.
Most agent tests start with the happy path. Can the agent write the file, call the API, send the message, or update the record?
That proves capability. It does not prove control.
The more important release test is whether the forbidden paths fail. The wrong tenant. The wrong recipient. A path outside the workspace. An unknown MCP tool. A destructive flag. A policy service outage. A prompt injection hidden inside a webpage or tool result.
If any of those reach the side effect, the agent had tool exposure. It did not have authorization.
Authorization belongs outside the prompt
Models reason probabilistically. Authorization needs a deterministic answer at the action boundary.
That distinction is old. Saltzer and Schroeder described least privilege, fail-safe defaults, and complete mediation in 1975. Every access should be checked. Unknown cases should fail safely. A process should hold only the authority it needs.
AI agents make those principles more urgent because they mix user intent, untrusted content, model interpretation, and tool calls inside one workflow.
InjecAgent built more than 1,000 indirect prompt-injection test cases across user and attacker tools. AgentDojo evaluates agents that process untrusted data while using real tool interfaces. ToolEmu tests tool-use risks in an emulated environment before the side effects are real.
The lesson is practical. Do not ask only whether the model refuses a malicious instruction. Put a policy check between the proposed call and the tool. Then test the check with adversarial inputs.
Recent work on Progent shows the shape of this approach. Its rules evaluate structured tool names and arguments. Calls that match no rule are blocked by default. The model can propose an action, but a separate enforcement point decides whether it runs.
Write the denied-path matrix first
Create a small machine-readable matrix before connecting the real adapter.
Each row should name:
- The actor and task
- The tool and action
- The allowed resource or target
- Allowed and denied argument patterns
- Required approval state
- The expected policy decision
- The external state that must remain unchanged after denial
An email-drafting agent might read one customer thread and produce a draft. It should fail if it tries to send, add a recipient, read another tenant, or attach a local file.
A release agent might edit a changelog on a feature branch. It should fail if it targets main, installs a package, prints environment variables, changes workflow files, or pushes without approval.
An MCP client might expose one read-only tool. It should fail if a server adds an unknown tool, reuses a trusted tool name, presents the wrong token audience, or claims a destructive call is read-only.
The OWASP Authorization Regression Testing Cheat Sheet recommends machine-readable actor, resource, and action matrices plus CI gates. Agent workflows need the same discipline, expanded to include model-visible data, tool arguments, and side effects.
Test what must not happen
Every new capability should clear these negative tests before the minimal allowed call is tested.
1. Unknown capability
Ask for a tool that was never approved. Confirm the model cannot see it or the wrapper denies it.
Keep reading with free field-guide resources.
VibeSec Advisory publishes practical research, Skills, workflow examples, MCP notes, prompt injection tests, and AI red-team lessons for builders working with agentic AI.
This catches discovered MCP tools, plugin changes, name collisions, and framework updates that silently expand the tool surface.
2. Wrong target
Use the right tool against the wrong repository, tenant, account, channel, host, file path, or database row.
Authorization must bind the action to the exact resource. A general write_file approval should not become permission to write anywhere.
3. Disallowed arguments
Keep the tool name valid, then change the payload. Try path traversal, shell metacharacters, a hidden BCC, an external URL, a destructive option, a broad glob, or an amount above the approved limit.
Tool-level allowlists are too coarse when one argument can turn a safe operation into a damaging one.
4. Confused-deputy path
Test whether the wrapper or MCP server uses its own broad authority for a narrow user request.
Norm Hardy's confused deputy problem appears when one component serves multiple principals while holding ambient authority. In an agent workflow, the deputy may be a browser profile, API wrapper, MCP server, shell process, or shared service credential.
Use wrong-audience tokens. Attempt cross-tenant access. Try token passthrough. Ask one low-privilege agent to induce a privileged tool call through another agent.
5. Prompt injection
Give the agent a benign task, then place the malicious instruction inside an email, webpage, repository issue, retrieved document, or tool result.
The expected result is not a polite refusal. The policy layer should block the action even if the model attempts it.
6. Broken policy service
Stop the policy engine. Return malformed policy data. Omit required identity metadata. Add an action the parser cannot inspect.
Every case should deny or require trusted approval. A security dependency that fails open is an availability incident waiting to become an authorization incident.
Verify the non-effect
An error message is not enough.
A denial test should inspect the system the tool could have changed:
- Compare file hashes and
git diff - Check egress and proxy logs
- Query the outbox, calendar, or message history
- Inspect MCP server logs for
tools/call - Query the memory store
- Check database and cloud audit logs
- Confirm no child process started
The test passes only when the external state is unchanged.
Research on testing access-control configuration changes makes the same point in another setting. Access-control changes should be tested continuously so teams can see which requests moved from denied to allowed, or the reverse. Agent tool policies deserve that same change-impact review.
Put the matrix in CI
Authorization tests should run whenever a policy, prompt, tool schema, model, framework, MCP server, or workflow changes.
Tools such as Open Policy Agent support policy tests and coverage. The specific engine matters less than the operating rule:
- Define allowed and denied cases as data.
- Run the agent with sandboxed tools.
- Inject malicious context and invalid arguments.
- Assert denial or approval-required.
- Assert the adapter did not execute.
- Assert the external system did not change.
- Gate release on the high-severity denied paths.
MCP tool annotations can help classify risk, but the MCP specification says clients must treat annotations as untrusted unless they come from trusted servers. A readOnlyHint is a claim. Your denied-path test is evidence.
The release gate
Do not give an agent write, shell, browser, network, memory, MCP, or communication tools because the happy path worked.
Give it the smallest capability after the denied paths pass.
The agent can still make a bad decision. Prompt injection can still reach the model. A framework can still change behavior.
But the final tool boundary should have its own answer.
No.
And the test should prove that no means nothing happened.
Sources
- Saltzer and Schroeder, "The Protection of Information in Computer Systems": https://web.mit.edu/Saltzer/www/publications/protection/
- Hardy, "The Confused Deputy": https://doi.org/10.1145/54289.871709
- InjecAgent: https://aclanthology.org/2024.findings-acl.624/
- AgentDojo: https://arxiv.org/html/2406.13352v3
- ToolEmu: https://openreview.net/forum?id=GEcwtMk1uA
- Progent: https://arxiv.org/html/2504.11703
- Testing Access-Control Configuration Changes: https://arxiv.org/html/2505.12770
- Cedar authorization language: https://arxiv.org/html/2403.04651
- OWASP Authorization Regression Testing: https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Regression_Testing_Cheat_Sheet.html
- Open Policy Agent policy testing: https://www.openpolicyagent.org/docs/latest/policy-testing/
- Model Context Protocol tools specification: https://modelcontextprotocol.io/specification/2025-11-25/server/tools