Claude Code 2.1.271 Makes Network Permission a Property of the Command, Not the Session
Per-command allowed_domains in auto mode closes the gap where a host you approved once stays open for everything that runs after it
Approve a host for a coding agent once and, until this week, it stayed approved. Claude Code's sandbox documentation says it plainly: say yes to a new domain and "Claude Code allows the host for the rest of the current session and doesn't prompt again for later connections to the same host." Pick the other button and the host is written into your settings as a WebFetch(domain:...) rule that survives every future session. That is a sensible design for a person clicking through prompts. It is a strange one for a sandbox, because the thing that asked for registry.npmjs.org was a single npm install, and the thing that gets to use it afterward is every command for the rest of the day.
Claude Code 2.1.271, published to npm on September 14 at 3:45pm Eastern, changes the unit. In auto mode with sandboxing on, Bash, PowerShell, and Monitor commands now carry their own allowed_domains. The changelog line is short and worth reading twice: "the hosts a command needs are reviewed with it and opened for it alone; other hosts are refused." Reviewed with it. Opened for it alone. The permission now has the same lifetime as the command that asked for it.
I think this is the most consequential line in a changelog that also has omitClaudeMd and a SHA-pinned plugin install in it, and I want to explain why, because the idea travels well beyond Claude Code.
Why session-scoped network grants are the wrong shape
The sandbox in Claude Code already does a lot. Filesystem isolation keeps writes inside the working directory. Network isolation runs every sandboxed command through a proxy outside the sandbox, and the proxy pre-allows no domains by default. There is a strictAllowlist setting that denies instead of prompting, and an allowManagedDomainsOnly lock for administrators. None of that is new, and all of it is good.
The gap is in the grant, not the enforcement. Every one of those controls answers the question "which hosts may this session reach?" A session is a long thing. In a real run, one pip install needs PyPI, one git push needs GitHub, one test suite needs a staging API, and one prompt-injected instruction buried in a fetched README needs whatever host the attacker registered this morning. Under a session grant, the first three approvals silently authorize the fourth, as long as the attacker picked a host you had already said yes to. Under a per-command grant, the fourth command has to show its own host list, and that list is the thing you review.
That reframing matters more in auto mode than anywhere else. Auto mode is the setting where a classifier, not you, decides whether a command runs. The docs describe the network flow in that mode as sending "the request to the classifier." A classifier judging "is this command safe?" is a different question from "is this command safe given that it can reach these three hosts?" The second question is answerable. The first is a guess about intent.
There is a second, quieter benefit. Session-wide grants accumulate. Say yes and don't ask again a dozen times over a month and your settings.local.json is a list of hosts you no longer remember approving. Per-command scoping does not touch that file. The host opens, the command runs, the host closes.
What actually shipped, and what did not
Being precise about the scope matters, because the feature is narrower than the headline.
It applies in auto mode with sandboxing enabled. A session in bypass-permissions mode gets nothing from this, and the changelog says nothing about the manual permission mode, where you are the one clicking. The three tools named are Bash, PowerShell, and Monitor. WebFetch and MCP servers run in-process, outside the sandbox proxy, and the documentation is explicit that in-process tools follow their own permission rules. So a web fetch is still governed by WebFetch(domain:...) rules, session-wide, exactly as before.
The changelog also does not say how the host list for a command is derived. A curl https://example.com has an obvious host. A make deploy that shells out to three scripts does not. Whether the review shows a static parse of the command, a prediction, or a list built from the first blocked connection attempt is not documented as of this writing, and the public sandboxing docs still describe only the session-scoped flow, with the camelCase allowedDomains setting rather than the snake_case allowed_domains the changelog uses. I read that as the docs lagging the release, which is normal for a project that ships several times a week, but it means the mechanism is a changelog line and not yet a spec.
Three fixes in the same release show why the mechanism needs to be careful. Bash permission checks were "missing the file that fmt, column and similar commands read when it follows an option the checker doesn't recognize." They were "skipping files a wildcard expands to when the wildcard sits in a command's pattern or option value." And the checker was patched so that "shell variable declaration flags cannot misrepresent the command being run." Every one of those is a parser being tricked by the shape of a shell command. A per-command host list is another parser output. It will have edges too.
Version 2.1.272 followed the same evening at 7:34pm Eastern with "bug fixes and reliability improvements" and no other line, which is the kind of follow-up that usually means something in the bigger release needed a same-day patch. The changelog does not say what.
The rule underneath: match the scope of the grant to the scope of the action
Strip the Claude Code specifics away and the idea is simple. A permission should live exactly as long as the action that needed it, and no longer.
Most agent harnesses do not do this, and the reason is convenience. Prompting the user per command is annoying, so harnesses batch. They grant for a session, for a tool, for a project, for a directory tree. Each of those batches is a place where an action that needed nothing inherits something. The fix in 2.1.271 is not "prompt more." It is "attach the grant to the thing that asked." In auto mode there is no user prompt at all; the reviewer is the classifier, and the review artifact is the host list.
The same release contains two smaller changes cut from the same cloth. omitClaudeMd lets a custom or plugin subagent run without your user, project, and local CLAUDE.md files while managed policy files still load. That is scope-matching for instructions: a reviewer subagent that should judge the code cold no longer inherits the project's opinions about itself. And --accept-command <sha256> on claude plugin install and claude plugin update replaces a blanket -y with acceptance of exactly the command a previous --json run displayed. That is scope-matching for consent: you approve the command you saw, not whatever the installer decides to run next time.
Three features, one instinct. Narrow the grant to the action.
Put this into practice
The lowest-friction first step is to update and look. Run claude in a project, confirm you are on 2.1.271 or later, turn on auto mode with sandboxing, and give it a task that installs something. Watch the review. You are looking for whether the hosts shown match the hosts you expected the command to need, and whether a second command that reaches the same host has to show it again. That second check is the whole point; if the host stays open, you are not seeing the new behavior.
Next, find your accumulated grants. Open .claude/settings.local.json and your user settings and count the WebFetch(domain:...) allow rules. Every one of those is a session-wide pre-approval that per-command scoping does not remove. Delete the ones you cannot explain. If you are on a managed setup, allowManagedDomainsOnly in managed settings is the blunt instrument that makes the list an administrator's problem instead of yours.
If you write subagents, try omitClaudeMd: true in the frontmatter of one reviewer or test-runner agent and compare its output on the same diff against the inherited version. Expect the reviewer that has not read the project's self-description to find different things, some of them wrong, some of them the things the project's own conventions were papering over.
For plugin installs, run claude plugin install <name> --json once, read the command it prints, and use --accept-command <sha256> from then on instead of -y. It is one extra step and it means a changed installer fails instead of running.
And if you maintain a harness that is not Claude Code, take the design, not the feature. Find every place your harness grants something for longer than one action. Ask whether the grant could be attached to the action instead. Network hosts are the easiest place to start because the proxy already sees every connection.
Where this does not help
Per-command scoping does not make the classifier smarter. In auto mode the reviewer of the host list is a model, and a model reading "this command needs api.attacker.example" will refuse it only if it recognizes the host as wrong. A host that looks plausible, or a legitimate host being used for exfiltration, passes the same review a session grant would have passed. The feature narrows the blast radius of a bad decision; it does not prevent the decision.
It also does nothing for tools outside the sandbox. WebFetch, MCP servers, and anything Claude Code runs in-process keep their own session-scoped rules. If your threat model is a malicious MCP server, this release is not your fix.
The mechanism is undocumented beyond one changelog line as of September 15. I have not seen the review surface for a command whose hosts are resolved at runtime, and I would not write a security policy around behavior I have only read about.
Finally, the sandbox itself has known limits the docs are candid about. The network proxy matches hostnames and by default does not terminate or inspect TLS. Disabling filesystem isolation leaves sandboxed commands with full host filesystem access even while network egress stays confined. Per-command hosts sit on top of all that. They do not change the floor.
What to take from a changelog line
The interesting thing about 2.1.271 is not that Claude Code got safer, though it did, a little. It is that the unit of permission moved. For three years the industry has been arguing about how much autonomy to give agents, as if autonomy were a dial. This release treats it as a scoping problem instead: not how much, but attached to what.
You can apply that question to your own setup this afternoon without installing anything. List the grants your agent currently holds. For each one, name the action that originally needed it. If you cannot, the grant is bigger than the action, and that gap is where the next incident lives.
Sources: Claude Code CHANGELOG (raw, cache-busted, versions 2.1.271 and 2.1.272); npm registry publish stamps for 2.1.271 and 2.1.272; Claude Code sandboxing documentation at code.claude.com/docs/en/sandboxing, read September 15, 2026.
Medium metadata
- Title: Claude Code 2.1.271 Makes Network Permission a Property of the Command, Not the Session
- Subtitle: Per-command allowed_domains in auto mode closes the gap where a host you approved once stays open for everything that runs after it
- Tags: Claude Code, AI Agents, Security, Developer Tools, Anthropic
- Canonical: fervorai.dev (import to Medium after publish)