The finding that changes the rendering
One agent has more than one way out.
The most quotable sentence found anywhere in this research is in one vendor's permissions documentation, about its own product. It settles an argument this site keeps having, so it is reproduced verbatim with its date.
“Note that using WebFetch alone doesn't prevent network access. If Bash is allowed, Claude can still use curl, wget, or other tools to reach any URL.”
code.claude.com/docs/en/permissions, read 12 September 2026
“Permission rules are enforced by Claude Code, not by the model. Instructions in your prompt or CLAUDE.md shape what Claude tries to do, but they don't change what Claude Code allows.”
Same page, same date. That is a vendor describing the difference between barrier two and barrier four in its own words — and doing it more plainly than this site has managed. The same page adds, of writing the boundary into the project instructions file: “This shapes what Claude tries but doesn't enforce a boundary.”
The setting that does hold is a different one, and its scope is narrower than most deployers would assume. Four documented properties of it belong on any page that recommends it:
- It covers shell subprocesses only. In the vendor's words: “Claude Code enforces this for sandboxed commands only; in-process tools such as
WebFetch still follow their permission rules.”
- It does nothing when written into the repository. Same sentence, next clause: “Setting it in a repository's
.claude/settings.json or .claude/settings.local.json has no effect.” This is the barrier-three to barrier-four promotion made mechanical — the same words in one file are a setting the agent's own working tree could change, and in another file are a boundary above it. It is the clearest illustration of the enforcer test we have found in anybody's documentation.
- It fails open by default. “By default, if the sandbox cannot start because dependencies are missing or the platform is unsupported, Claude Code shows a warning and runs commands without sandboxing. To make this a hard failure instead, set
sandbox.failIfUnavailable to true.”
- It decides from the announced hostname. “Because the proxy makes its allow decision from the client-supplied hostname without inspecting TLS, code running inside the sandbox can potentially use domain fronting or similar techniques to reach hosts outside the allowlist… Stronger TLS-aware network isolation is an active area of development.” Against an injected agent that will not think to lie about the hostname, this is adequate. Against a compromised one it is not, and a policy row claiming it should say which of the two it is claiming.
All four quoted from code.claude.com/docs/en/sandboxing, read 12 September 2026. A second vendor's defaults run the other way and are worth citing as the counter-example: its shell sandbox has network access off by default, its hosted service blocks internet access during the agent phase unless enabled, and its domain filter resolves deny before allow. A third states plainly that its automatic review of agent actions is not a security boundary and that the classifier can err in both directions. Publishing three positions side by side, sourced and dated, is more useful to a reader than any argument we could make.
A destination list is not a property of an agent. It is a property of an egress path, and an agent has several.
So the rendering has to be a matrix, with paths down the side, and a cell is green only when that path is covered by something at barrier four. A policy recording a single domain list for an agent is describing at most one of its exits.
| Egress path | What governs it | Covered by | Default |
| shell subprocesses | The sandbox allowed-domains list, with strict mode, from user or managed settings | An OS-level boundary outside the process | ○ 4 |
| in-process fetch | Its own permission rules — a separate list that must be reconciled by hand | The client, not the OS | ◐ 3 |
| connector servers | Nothing in the sandbox — they run as separate host processes outside it | Only a network-layer boundary | ● 1 |
| hooks | Nothing in the sandbox — same reason | Only a network-layer boundary | ● 1 |
| name resolution | Not covered by any web-destination list | A resolver allow list, or the firewall's outbound resolution rule | ● 1 |
The minimum across the paths is what the badge should show. An agent with a perfectly written destination list and an unsandboxed connector server earns the glyph for the connector server, because that is the path an attacker uses.
Measured on the machine that built this page · 12 September 2026
# the shell, from the environment that publishes riskmandate.ai
curl https://example.com/ 200
curl https://ipinfo.io/ip 200
exec 3<>/dev/tcp/1.1.1.1/443 open ← a raw socket, no proxy in the path
getent hosts example.com resolves
# the in-process fetch tool, same session
fetch https://example.com/ 200
No allow list stood in either path. This is one deployment — a managed remote environment with its own network policy — and that is exactly the point: the answer to can this agent reach arbitrary hosts lives in the deployment and not in the model. We publish our own measurement because a page arguing that the barrier is a property of the deployment should say what its own deployment does.
One thing we could not reproduce, and say so. The brief behind this entry reports observing the two egress paths diverge in a single session — the fetch tool reaching hosts the shell's tunnel refused. In this session they did not diverge: both reached every host tried. The documented finding stands on the vendor's own sentences above, which say the two paths are governed by different policy; whether they actually differ on a given day is configuration, and we did not see it here.