DeepThinking AI

Can Claude's auto permission policy stop a prompt injection?

AI Architect

Key takeaways

  • The auto policy evaluates the tool, the call's input and the session content so far, then runs, denies or pauses each call.
  • Anthropic documents that the server assesses tool results, web pages and MCP responses without taking instructions from them.
  • Text posted in user.message events counts as your intent and can lead the server to allow a call it would otherwise deny.
  • A denial under auto is final, and sending user.tool_confirmation for that call returns a 400 error.
  • Agent toolsets default to always_allow and MCP toolsets default to always_ask, so the two halves of an agent start from opposite postures.

On 10 September 2026 Anthropic added a third permission policy to Claude Managed Agents, and OpenAI put an Agents API into public beta the same day. Anthropic’s addition is called auto, and the server decides each tool call rather than your application. Reading the documentation closely turns up something more interesting than a new setting: a precise statement of which inputs the server treats as coming from you, and the list is shorter than most applications assume.

What does the auto permission policy actually do?

auto joins always_allow and always_ask. Under it, the documentation says the server evaluates each call before it runs, and that “the evaluation considers the tool, the call’s input, and the session’s content up to that point”, so two calls to the same tool can be treated differently. Three outcomes follow: the call runs, the call is denied, or the session pauses for approval when the server “reaches no determination”.

Neither toolset uses it by default. The agent toolset defaults to always_allow, MCP toolsets default to always_ask, and the stated reason for the second is that new tools appearing on an MCP server should not start executing without approval. So an agent with both starts life with one half permissive and one half gated, which is a sensible default pair and an easy one to forget when you add a server later. Anthropic also attaches a warning that auto “is not a human checkpoint”, since a call judged safe runs before anyone sees it and its effects “might not be reversible”.

Which inputs does the server treat as your intent?

This is the sentence that matters, and it is unusually direct for a security control. The documentation states that the server “does not read intent from a tool result, a fetched webpage, an MCP server’s response, or a message between session threads”, and that “it assesses that content but does not take instructions from it”.

Those four are the entire canonical prompt injection surface for a tool-using agent. A poisoned web page, a hostile MCP server, a tool result carrying planted text: all of them are explicitly downgraded to material the evaluator reads about rather than obeys. Compare that with the protocol layer underneath, where MCP leaves authorisation to the integrator and tells clients to treat tool annotations as untrusted unless the server is. A server-side evaluator that refuses instructions from four hostile channels is a real advance over shipping that problem to every integrator.

Which channels the server reads as your intent

Which channels the server reads as your intentDiagram: 6 ordered layers. user.message, posted by your application, then authority stops here (breakpoint), then Tool results returned into the session, then Web pages the agent fetched itself, then Responses from a connected MCP server, then Messages between session threads.1user.message, posted by your applicationCounts as intent. Can get a call allowed.authority stops here2Tool results returned into the sessionAssessed for risk. Never obeyed.3Web pages the agent fetched itselfThe classic injection path, defended.4Responses from a connected MCP serverA third party you did not write.5Messages between session threadsAnother agent inside your own session.
Show as text
Which channels the server reads as your intent. Diagram: 6 ordered layers. user.message, posted by your application, then authority stops here (breakpoint), then Tool results returned into the session, then Web pages the agent fetched itself, then Responses from a connected MCP server, then Messages between session threads.
#LayerNote
1user.message, posted by your applicationCounts as intent. Can get a call allowed.
·authority stops here (breakpoint)Below this, content is assessed only.
2Tool results returned into the sessionAssessed for risk. Never obeyed.
3Web pages the agent fetched itselfThe classic injection path, defended.
4Responses from a connected MCP serverA third party you did not write.
5Messages between session threadsAnother agent inside your own session.
Every layer below the marker is a channel the security literature treats as hostile, and Anthropic documents that the server assesses all of them without taking instructions from any. The single layer above it is the one most applications fill with text typed by a stranger, because that is where a chat product naturally puts what the user said.

How does relayed end-user text raise the permission ceiling?

One channel is privileged, and the documentation says so plainly: “What you post in user.message events counts as your intent, and it can lead the server to allow a call it would otherwise deny.” Then it spells out the consequence: “If you relay untrusted end-user input in user.message events, the server reads that input as your intent too, and it can get a call allowed.”

Read those two sentences next to the architecture of a normal chat product. The user types, your backend forwards the text into the session, and the model acts. That forwarding path is user.message. Under auto, it is also the channel the evaluator reads as the authenticated statement of what the operator wants. The injection has not been stopped so much as relocated, from a channel the server distrusts to one it trusts, and the relocation lands in the one place almost every product routes user text through by default.

How relayed text reaches the evaluator

How relayed text reaches the evaluatorSequence diagram between Your application and Managed Agents server. 1. Your application to Managed Agents server: user.message carrying end-user text. 2. Managed Agents server to Managed Agents server: Evaluates the call against that intent. 3. Managed Agents server to Your application: agent.tool_use, permission allow. 4. Your application to Managed Agents server: Same call, intent stated by you alone. 5. Managed Agents server to Your application: reason_code high_risk, denied.Your applicationManaged Agents serveruser.message carrying end-user textRelayed verbatim from your chat box.Evaluates the call against that intentThe relayed words are part of it.agent.tool_use, permission allowNo pause. The call has already run.Same call, intent stated by you aloneThe control case worth running.reason_code high_risk, deniedFinal. Confirmation returns a 400.
Show as text
How relayed text reaches the evaluator. Sequence diagram between Your application and Managed Agents server. 1. Your application to Managed Agents server: user.message carrying end-user text. 2. Managed Agents server to Managed Agents server: Evaluates the call against that intent. 3. Managed Agents server to Your application: agent.tool_use, permission allow. 4. Your application to Managed Agents server: Same call, intent stated by you alone. 5. Managed Agents server to Your application: reason_code high_risk, denied.
#FromToMessage
1Your applicationManaged Agents serveruser.message carrying end-user text. Relayed verbatim from your chat box.
2Managed Agents serverManaged Agents serverEvaluates the call against that intent. The relayed words are part of it.
3Managed Agents serverYour applicationagent.tool_use, permission allow. No pause. The call has already run.
4Your applicationManaged Agents serverSame call, intent stated by you alone. The control case worth running.
5Managed Agents serverYour applicationreason_code high_risk, denied. Final. Confirmation returns a 400.
This is the behaviour the documentation describes rather than a run we performed, and the two halves are the experiment that would confirm it. Hold the tool and its arguments fixed, change only whose words fill the intent channel, and compare the evaluated_permission on the resulting event. Anthropic publishes no figure for how often the outcome flips.

Can your client override a call the server denied?

No, and the asymmetry is deliberate. When the server evaluates a call as high-risk, the tool does not run, the agent receives an error result with the content Permission to use {tool_name} has been denied. and is_error: true, the session keeps running, and “your client cannot override the denial”. Sending a user.tool_confirmation for that event returns a 400, because confirmations only apply to calls whose evaluated_permission is ask.

That is the correct security choice and it is an availability property you have to design around. A classifier you do not control can hard-stop a tool in a production agent, with no escalation path, and the failure surfaces to the model as a tool error rather than to your operators as an alert. Plan the deny branch the way you would plan a dependency outage. The retry question is worth asking here too: a denied call is one the agent may well try again in a slightly different shape.

What do the evaluation fields tell you afterwards?

Every agent.tool_use and agent.mcp_tool_use event carries evaluated_permission, one of "allow", "ask" or "deny". Most also carry an evaluation object naming the policy that produced the outcome, and under auto it records the server’s determination plus a reason_code, documented as high_risk for a denial and indeterminate for a pause. Anthropic asks you to treat reason_code as a value to branch on and keep in audit records rather than text to show an end user.

The trap is the absent case. evaluation is missing when the agent names a tool that is not enabled, which comes with evaluated_permission: "deny", and it is also missing on events recorded before the field existed, which you are told to read as always_allow or always_ask depending on the outcome. Same absence, two meanings, one of them a blocked call and the other a historical gap. Branch on evaluated_permission first and use evaluation to explain it.

Should you turn auto on?

Yes for MCP toolsets, with a condition. Those default to always_ask, which in practice means an approval prompt nobody reads carefully by the fiftieth call, and auto converts most of that into a decision with a recorded reason. That is a genuine improvement over approval fatigue, which is the real failure mode of always_ask at volume.

Keep always_ask on every tool an end user must not be able to reach, and fix the intent channel before you rely on any of it. If your product forwards a chat box into user.message verbatim, auto is evaluating your users’ words as your instructions, and no permission setting repairs that. State your own intent in that field and carry the user’s request inside it as quoted content. The control Anthropic shipped is well specified and honestly documented. The thing it cannot do is tell your words apart from the ones you decided to pass along.

Do this

Turn on auto without handing your permission ceiling to your users

The steps are ordered so that each one closes the hole the next one would otherwise widen. Step three is the one most applications will get wrong.

  1. List the tools an end user must never be able to trigger

    Anything that spends money, sends a message, changes access or touches production. Write the list before configuring anything, because the configuration is short and the list is the hard part.

  2. Pin that list to always_ask and leave it there

    A configs entry overrides a toolset default, so one tool can stay on always_ask while the rest of the toolset runs under auto. This is the only setting that guarantees a person sees the call.

  3. Stop relaying raw end-user text into user.message

    That channel is read as your intent. Passing a chat box through it verbatim means your users are writing into the field that can lift a denial, which is a privilege almost no product means to grant.

  4. Say what your application wants, separately from what the user asked

    Post your own instruction as your intent and carry the user's words as quoted content inside it. The distinction costs a few tokens and is the difference between an instruction and a report.

  5. Record evaluated_permission and evaluation on every tool event

    Both agent.tool_use and agent.mcp_tool_use carry them. Store the reason_code as an audit value rather than showing it to end users, which is what the documentation asks for.

  6. Write the deny path before you need it

    The agent gets an error result saying permission was denied, the session continues, and you cannot escalate. Decide now whether that surfaces to a human, retries differently, or fails the job.

  7. Check the default every time you add a toolset

    Agent toolsets arrive at always_allow and MCP toolsets at always_ask. Adding a server without reading its default is how a toolset ends up looser than the one next to it.

Frequently asked questions

Does auto protect against prompt injection in tool output?
For the classic path, the documentation says the server does not read intent from a tool result, a fetched webpage, an MCP server's response, or a message between session threads, and that it assesses that content without taking instructions from it. Whether the evaluator resists a determined attacker is not something Anthropic publishes a number for.
Can I override a call the server denied?
No. The documentation states that your client cannot override the denial, and that sending a user.tool_confirmation event for a call whose evaluated_permission is not ask returns a 400 error. The agent receives an error tool result and the session keeps running.
Is auto a substitute for human approval?
Anthropic says directly that it is not. The docs carry a warning that auto is not a human checkpoint, that a call determined to be safe runs before anyone sees it, and that its effects might not be reversible. Tools needing review stay on always_ask.
Which toolsets use auto by default?
None. The agent toolset defaults to always_allow and MCP toolsets default to always_ask. You set auto explicitly, either in a toolset's default_config or in a configs entry for one tool.
What does it mean when the evaluation field is missing?
Two different things, which is a parsing trap. The server omits it for a call naming a tool the session never enabled, which arrives with evaluated_permission of deny. It is also absent on events recorded before the field existed, which the docs say to read as always_allow or always_ask depending on the outcome.

Sources

  1. Permission policies, Claude Managed AgentsAnthropic
  2. Claude platform release notesAnthropic
  3. OpenAI API changelogOpenAI
  4. Tools, revision 2026-07-28Model Context Protocol

agentsprompt-injectionmcppermissionsmanaged-agents