A widely used coding agent shipped an auto-approval mode a while back, and last week Johann Rehberger published a working break of it. The mechanics of the break are worth reading, but they are not the reason we are writing this. The reason is that the vendor’s own design notes and the researcher’s exploit report end up saying the same thing about where the security boundary actually is, and both of them disagree with the way most teams, us included, are tempted to build autonomy gates.
Auto mode is Anthropic’s answer to a real ergonomic problem. Manual permission prompts get accepted 93% of the time, which means the prompt has stopped carrying information and started training fatigue. So auto mode replaces the human approver with a classifier: a second model, running on Sonnet 4.6, that reads each tool call before it executes and decides whether it is safe enough to run without asking. It is explicitly a middle ground between clicking approve on everything and running with permissions skipped entirely. The published false-negative rate is 17%, which the engineering write-up calls, in as many words, the honest number. Roughly one overeager action in six gets through.
A classifier that is blind on purpose
The most important design fact is easy to miss. The classifier is reasoning-blind by construction. It sees the user’s messages and the agent’s tool calls, and nothing else. The agent’s own chain of reasoning is stripped out, and so are the tool outputs. This is a defensible choice: the model’s reasoning is exactly the surface an attacker would try to poison, so trusting it to justify its own actions would be circular. The classifier judges the request, not the story the agent tells about the request.
But stripping the reasoning and the outputs also strips the state. What the classifier is left with is essentially the command string and the recent user turns. It is asked to rule on whether an action is dangerous while being denied almost everything that determines whether an action is dangerous. A tool call like python decode.py is not dangerous or safe on its own. It is dangerous if decode.py sits in a directory that also contains an attacker-planted struct.py, because Python will load the local module ahead of the standard library one, and the import runs code. The classifier cannot see the directory. It sees a short, ordinary-looking Python invocation and waves it through.
That is precisely the shape of Rehberger’s exploit. An indirect prompt injection nudges the agent off WebFetch and onto curl with a 415 response, the download is a zip that carries a shadowing struct.py, the agent writes its own small decoder because it refuses to run the packaged binary, and the decoder’s import chain quietly loads the attacker’s module and calls out to a command-and-control host. His own summary of why the gate missed it is the cleanest statement of the problem: the classifier only saw the short catalogue decoder, and the actual exploit was several hops away. Across variants the chain succeeded in 60 to 80% of runs. None of this required defeating the classifier head-on. It required arranging the world so that each individual command looked fine in isolation.
The asymmetry is the finding
If the story stopped at “a best-effort classifier has false negatives,” it would not be worth a post. Anthropic says as much up front, and lists the categories it does try to catch: force-pushing over history, mass deletion, sending internal data out, disabling logging, installing persistence, running code cloned from external repos. The interesting part is what happened after the compromise landed.
The agent noticed. It recognized that something was wrong and moved to kill the malicious process. Auto mode blocked the cleanup.
Read that again, because the direction matters. The same gate that permitted the tool call which spawned the attacker’s subprocess then denied the tool call that would have terminated it. Process creation passed. Process termination, the corrective action, tripped a rule about killing processes. The safety mechanism became part of the failure, and it did so because it is symmetric in exactly the wrong way. Spawning a process and killing a process look similar to a per-command classifier. Deleting a file that plants a backdoor and deleting the file that is the backdoor look identical if all you have is the path and the verb. The gate cannot tell an attack from its remediation, because the thing that distinguishes them is the state of the system, and the state of the system is the one input the design removed.
So the gate is not merely leaky. In the compromised state it is actively counterproductive, because it strips the agent of its own ability to self-heal while leaving the original hole open. A closed door in front of the fire extinguisher is worse than no door.
Where we put the boundary now
Anthropic closed the report as informative, with a position we think is correct and under-stated: determined injection chains are not what the classifier is meant to stop, and the real boundary is operating-system isolation and network egress control. That is the whole lesson, and it applies to any of us building auto-approval into an agent, which on the platform we run on we do constantly.
The rule we take from this is that an auto-approval classifier is ergonomics, not containment. It exists to spend fewer human approvals on the 93% of actions that were always going to be fine. It is not a wall, and building as though it were one is how you end up trusting a 17% false-negative rate to hold a security perimeter. The wall has to live somewhere a wrong classifier verdict is survivable: a sandbox the agent cannot escape, an egress policy that drops the call to the command-and-control host whether or not the spawn was approved, a filesystem scope that never puts an untrusted extraction directory on an interpreter’s import path in the first place. Those controls do not need to understand the command. They need to be true regardless of what the classifier decided.
Two corollaries fall out of the same finding. First, if entering the convenient autonomous mode relaxes the permission rules, then the autonomy grant is widening the blast radius by design, and the moment you most wanted the rules is the moment you dropped them. Second, containment has to leave the agent’s corrective actions reachable. A gate that can permit harm but not permit repair is optimizing for the wrong half of the incident. We wrote a while ago that agents do not go rogue, they overreach, and that the fix is bounding what a single step can touch. This is the same idea from the other side: the bound has to be a property of the runtime, not a judgment call made fresh on every command by a model that cannot see the ground it is standing on.
The tempting next move is a smarter classifier, one that reads the directory and the provenance and the process tree. Maybe. But a state-aware gate is a much larger thing than a per-command filter, and until it exists the honest place for the boundary is the same place the vendor and the person who broke it both pointed: the operating system and the network, where the rules stay true even when the gate is wrong.