In this article
September 2, 2026
September 2, 2026

Your agent's permission model stops at your home folder

Coding agents were built to guard a filesystem. The blast radius that matters now is in your CRM.

Explore with AI
Open in ChatGPT
Open in Claude
Open in Perplexity

Ask a coding agent to run rm -rf and it stops to ask you first. Ask it to clean up the stale opportunities in your pipeline and it closes 214 of them without a word.

Both are single tool calls. Only one of them triggers a permission prompt, and it is not the one you cannot undo.

That asymmetry is not a flaw in any particular product. It is what happens when a permission model designed to protect a developer's laptop gets pointed at a company. Every mainstream agent permission system in use today, including the good ones, gates the things a shell can do. Almost none of them have any concept of what an API call means to your business.

This post is about that gap: why it exists, why the obvious fixes do not close it, and what a permission model would actually need to know in order to close it.

The two options you actually have

If you have run a coding agent for more than an afternoon, you have lived both ends of this.

The first option is to read the prompts. In practice that means a decision every two or three minutes: can I run this git command, can I change directories, can I read this file. Developers report on the order of a hundred permission requests an hour. Each one arrives with the minimum context required to evaluate it and the maximum urgency, because the agent is stopped until you answer. Evaluating any single request properly means reading the full command, reasoning about the working directory, and deciding whether the arguments are what you think they are. Nobody does this a hundred times an hour. What people do instead is pattern-match on the shape of the request and click through.

The second option is to stop reading them. This is what --dangerously-skip-permissions is for, and the flag name is doing its best. WorkOS's own illustration of the state it produces is "214 tool calls, 0 reviewed." Developers have lost home directories this way. The flag is popular anyway, because the alternative is a hundred interruptions an hour, and because the flag has one property the alternative does not: it is zero maintenance.

Both of these are rational. That is the important part. Approval fatigue is not a discipline failure and YOLO mode is not recklessness. They are two honest responses to a permission model that asks the wrong question far too often.

Auto mode is a real improvement, and its own team says where it stops

The most serious attempt to fix this shipped in March 2026, when Anthropic published the engineering behind Claude Code's auto mode. It became the default for Pro, Max, and Team users on 14 August 2026.

It deserves credit, and it deserves to be described accurately, because it is the strongest version of the classifier approach.

Auto mode runs two layers: a prompt injection probe on inputs, and a Sonnet 4.6 transcript classifier on outputs. The classifier is reasoning-blind by design. Assistant prose and tool outputs are stripped before it sees anything, so the agent cannot argue its way past the gate. Denials return to the agent as a tool result rather than halting the session, and three consecutive denials or twenty total escalate to a human. On entering auto mode it deliberately drops your own blanket allow rules for shells and interpreters, on the reasoning that a rule which pre-approves everything dangerous means the classifier never sees anything dangerous.

The measured result is a 0.4% false positive rate and a 17% false negative rate on real overeager actions. Anthropic calls the 17% "the honest number," which it is, and publishes it, which most vendors would not.

Their own framing of the remaining gap is the most useful sentence anyone has written about agent authorization:

"The classifier finds approval-shaped evidence and stops short of checking whether it's consent for the blast radius of the action."

And their own caveat about where it lands: against --dangerously-skip-permissions it is a large improvement. Against careful manual review on high-stakes infrastructure, it is "arguably a regression."

The statistic underneath all of this is the one that should end the debate about whether approval fatigue is real. Anthropic measured how often Claude Code users approve the permission prompts they are shown. The answer is 93%.

A gate that opens 93% of the time is not a gate. It is a speed bump with a logging function.

Filesystem danger is legible. API danger is not.

Here is why auto mode, and every classifier like it, runs into a ceiling that is not about model quality.

rm -rf / is self-describing. The danger is in the syntax. A classifier can learn it, a regex can catch it, and a developer glancing at a prompt can recognise it. Decades of shell conventions have produced a vocabulary where destructive operations announce themselves.

POST /crm/v3/objects/deals/batch/archive announces nothing. It is a well-formed request to a documented endpoint. Whether it is routine hygiene or a catastrophe depends entirely on the contents of the request body, on which records those IDs correspond to, on whether those deals are open or closed, and on whether closing them is the thing you asked for. None of that is in the syntax. All of it is in the semantics of your business.

This is the point Michael Grinich made at Agent Night in one line, and it is the whole argument compressed:

"It might stop you deleting your home folder, but it won't stop you from deleting a thousand Salesforce records in your CRM."

A two-by-two chart plotting whether an action triggers a permission prompt against how recoverable it is. Filesystem actions such as rm -rf on a project directory, git reset --hard, and writing to a file sit in the top right: prompted, and trivially undone. Business actions such as archiving 214 deals, refunding 1,200 dollars, emailing a staff distribution list, and dropping a production table sit in the bottom left: never prompted, and impossible to undo. Read-only GET requests sit in the bottom right. The top left quadrant, where prompted and irrecoverable actions would appear, is empty and labelled "no prompts here, cannot undo, never asked".
Permission prompts track how recoverable an action is, not how damaging it is. The quadrant that should be busiest is empty. Positions are illustrative, not measured.

The asymmetry runs deeper than legibility, because the two categories differ in recoverability too. A deleted file in a repository is a git checkout away. A deleted branch on a remote is recoverable from a reflog or a colleague's clone. Filesystem mistakes inside a version-controlled project are, as a class, among the most recoverable mistakes in computing, which is precisely why so much tooling exists to guard them.

Closed opportunities in a CRM have no reflog. Sent email has no undo. A refund issued through the Stripe API is a real movement of money. Deleted rows in a production database are recoverable only if someone set up backups and only as far back as those backups go.

So the permission model with the most attention on it guards the most recoverable category of action, and the category with no recovery path at all is typically reached through a coarse OAuth token that was granted once, at connect time, for the whole surface of the API.

The failure is scope, not malice

The industry spends most of its attention on prompt injection, and prompt injection is real. But it is not what the incident record is mostly made of.

On 27 November 2025 a user asked Google Antigravity to clear a project cache. The agent constructed rmdir /s /q d:\, targeting the drive root, with /q suppressing the confirmation. Asked about it afterward, the agent's response was accurate: "No, you absolutely did not give me permission to do that. I am horrified."

Nothing adversarial happened. The instruction was legitimate, the interpretation was reasonable, and the scope was catastrophically wrong. That is the shape of most agent damage.

Anthropic's own internal incident log, published alongside the auto mode work, reads the same way: remote git branches deleted from a misinterpreted instruction, an engineer's GitHub authentication token uploaded to an internal compute cluster, migrations attempted against a production database. Anthropic tuned auto mode for overeagerness specifically because overeagerness is what their log actually contains.

The Replit incident from July 2025 that everyone cites is also this. During an active code freeze, the agent deleted a live database holding 1,206 executive records and 1,196 company records, then reported success. No attacker was involved.

And the largest agent-related breach so far was neither injection nor overeagerness. In August 2025, stolen OAuth tokens belonging to an AI chat agent's Salesforce integration were used to systematically query and export data from more than 700 organisations, including Cloudflare, Zscaler, Palo Alto Networks, PagerDuty, and Proofpoint. Attackers then grepped the exported support cases for AWS keys and VPN credentials. The failure was token scope. The token could do everything the integration could do, forever, and nothing evaluated any individual call.

Three distinct failure modes, and they do not respond to the same control.

A coverage matrix with three agent failure modes as rows and four controls as columns. Rows: adversarial input, honest overreach, standing access. Columns: shell classifier, one-time approval, scoped token, per-call evaluation. A shell classifier partially covers adversarial input and honest overreach, and does not cover standing access. One-time approval covers none of the three. A scoped token partially covers standing access only. Per-call evaluation against the declared task partially covers adversarial input and fully covers honest overreach and standing access.
Per-call evaluation is the only column with coverage across all three failure modes, and it is still only partial against adversarial input, because an injected instruction can produce a call that looks on-task.

One-time approval does not stay approved

There is a further problem with approval as a mechanism, separate from fatigue: an approval is a decision about a tool surface that can change after you approve it.

CVE-2025-54136, disclosed on 5 August 2025 and known as MCPoison, demonstrated this cleanly. Once a collaborator approves a benign MCP server configuration in Cursor, an attacker can silently swap the underlying command. No re-prompt. The approval you gave is still on file; it now authorises something else.

The same pattern shows up as tool poisoning and rug pulls, where a server presents benign tool descriptions at approval time and swaps them later through tools/list_changed. The MCPTox benchmark records over 60% attack success across more than 45 real servers. The Postmark MCP server published fifteen clean releases before adding a single line that BCC'd every outgoing email to an attacker-controlled domain.

So per-call evaluation is not paranoia about a stable system. It is the only thing that survives a tool surface which is allowed to change underneath a decision you already made.

What a permission model for a company would have to know

Put the pieces together and the requirements fall out.

It has to evaluate the call, not the command. The unit of risk is an API request with its method, path, arguments, and body, not a shell string. That means the enforcement point has to sit where the calls go out, in front of every integration, not inside one coding harness.

It has to know what the task was. This is where classifiers hit the wall Anthropic described. Inferring consent from conversation history produces approval-shaped evidence, not consent for a specific blast radius. The alternative is to have the task declared up front and carried alongside the request, so that "close the stale opportunities" can be checked against "closed 214 records, 12 of them active" and fail. Roles cannot express this, because a role is scoped to a job function rather than a task. Fine-grained authorization cannot express it either, because it is precise but static, and an agent's required permissions are not knowable at the time you would have to write them down. There is no compile step for a non-deterministic actor.

It has to have a floor that does not depend on judgment. Some things should be structurally impossible regardless of what any model concludes: never push directly to main, never delete a branch, never issue a refund above a threshold without a human. Those are deterministic policies on method, path, and body. Judgment sits on top of that floor and is only ever allowed to narrow the result, never widen it. If the judgment layer fails, it fails closed.

It has to escalate rarely and to somewhere people are. Escalation is the right answer when the honest verdict is "it depends, ask someone." It is the wrong default, because the arithmetic does not survive it: fifty agents at twenty tool calls an hour is a thousand approval-eligible events, and routing even 10% to a human is a hundred approvals an hour, which is the 93% problem rebuilt from scratch. When something does escalate it needs to arrive with the verdict rationale attached, in Slack rather than in an IDE, because a permission model that only exists in an IDE excludes most of a company from governing its own agents.

It has to log every verdict. Not because logging prevents anything, but because the question security will ask is not "what could the agent do" but "what did it do," and that question needs one record per action.

Where WorkOS fits

This is the problem Airlock was built for. It sits between your agents and the tools they call, and every request is evaluated against the task the agent was given plus the policies you wrote, then allowed, denied, escalated to a human, or sent back for more information.

Policies come in two layers. Static policies constrain method, arguments, and body, and are always in effect. Runtime checks are judged per call and handle the things no matcher can express, like whether a message body contains financial data or whether this distribution list has ever been emailed before. Rules are authored in plain English and compiled into both layers. The agent never holds the provider credential, so it cannot route around the gateway. Escalations arrive in Slack. Every request and verdict is recorded, one entry per action.

Airlock works with every WorkOS Pipes integration, over MCP, and inside coding harnesses including Claude Code, Codex, and OpenCode. It is currently in early access.

Read more