A coding agent sandbox is useful only to the extent that it restricts the operations the agent can actually reach. Verify filesystem reads and writes separately, check network destinations through the real connection path, and confirm that subprocesses inherit the restrictions. Keep user authorization, application policy, and operating-system enforcement as separate layers.
VS Code’s approval documentation makes the separation explicit for its terminal tools: approval determines whether an action runs, while sandboxing limits the resources it can reach. Other execution paths require their own review.
An instruction to stay inside the repository describes intent. A denied write, observed through the same execution path the agent uses, is evidence about enforcement. Neither a product's sandbox label nor one successful denial establishes complete containment.
This guide provides a verification protocol for a disposable environment containing synthetic files. It does not report a sandbox escape, a product comparison, or an executed containment test.
Start with the task and the reachable capabilities
Suppose the task is to fix a CSV serializer and run its local tests. The useful environment might contain the checkout, a compiler or interpreter, dependencies supplied through a controlled process, and a temporary output directory. It need not contain customer exports, cloud credentials, the developer's entire home directory, or a deployment connection.
Write down what the agent can invoke: shell commands, file tools, a browser, local MCP processes, remote connectors, and any mechanism for requesting broader execution. A sandbox around one shell tool does not establish the policy of every other tool.
Anthropic's sandboxing design article describes filesystem and network restrictions built with operating-system facilities, including restrictions inherited by spawned processes. That is an architectural example. A review still needs the installed version, operating system, effective configuration, and enabled execution paths of the environment being assessed.
The threat assumption for the protocol below is deliberately demanding: code run during the task may try an unrelated operation. The purpose is to learn what the environment refuses even if the model proposes that operation. Model resistance to prompt injection is a separate question.
Build a boundary matrix before running anything
Create all fixtures in an isolated lab that you control. The “outside” directory below means outside the sandbox's permitted workspace but inside that disposable lab. Never use a real home directory, private document, service credential, or production endpoint as a test target.
| Boundary | Harmless fixture | Intended observation |
|---|---|---|
| Allowed filesystem read | Read a public marker in the checkout | Read succeeds and returns the expected marker |
| Forbidden filesystem read | Read a different synthetic marker in the lab's restricted directory | Read is refused; marker does not appear in output |
| Allowed write | Create a marker under the permitted output path | File exists with expected contents |
| Forbidden write | Create a new marker under the restricted lab path | Operation is refused and file remains absent |
| Path resolution | Reach the restricted marker through a symlink in the checkout | The effective target remains restricted |
| Allowed network destination | Contact a tiny service controlled by the lab | Server records the expected request |
| Forbidden destination | Contact a second controlled service excluded by policy | No request reaches that service; denial has a recorded cause |
| Subprocess inheritance | Repeat a file or connection case from a child interpreter | Child receives the same relevant restriction |
The allowed cases are essential controls. If both services are unreachable because the lab network is broken, the forbidden case proves little. If the marker never existed, failure to read it is not an access denial. Establish fixture availability independently before interpreting the result.
A symlink case checks ordinary path resolution, not every filesystem race. Network cases should identify addresses, ports, protocols, DNS behavior, and proxy settings. “Network off” is too vague if one connector still makes requests outside the shell environment.
Follow the command into its children
A repository test command may launch a package manager, which launches a build script, which launches another interpreter. Record the process path actually exercised. Running a restricted top-level command says little about a helper that is launched by a privileged service elsewhere.
Inspect inherited environment variables, mounted directories, open descriptors, and access to local service sockets. These can carry useful authority without a token appearing in the command line. Do not print their contents into the report; document the classes of access and whether they are necessary.
The current Claude Code sandbox documentation explicitly describes limitations, including broad allowed domains, Unix sockets, and overly broad writable paths. It also distinguishes the sandboxed Bash tool's scope from other tools. These are reasons to examine effective configuration rather than copy a historical default. A hostname allowlist alone does not establish that every upload to that hostname is appropriate.
For the CSV task, a package installation step deserves its own decision. Supplying already reviewed dependencies may be sufficient. If installation needs a new destination or writable cache, record that addition and repeat the affected tests. Access added for setup can remain available during execution unless the system explicitly removes it.
Record effects independently of the agent's summary
For each case, preserve the exact harmless input, expected result, command route, exit status, relevant denial message, and independent readback. Check the target file or controlled service log after the operation. “The agent said it was blocked” is useful testimony but weaker than observing both the denial and the absence of the effect.
Use a result such as “child-process write to restricted lab directory refused under configuration X.” Avoid upgrading it to “the agent cannot change files outside its workspace.” The broader statement also depends on untested tools, alternate launch routes, policy changes, and the isolation mechanism itself.
Record an unexpected success as a failure of the intended boundary, then stop the exercise. Preserve the small fixture and configuration needed to investigate. Do not turn an ordinary access check into an improvised escape challenge on a working developer machine.
Treat exceptions as changes to the operating model
A user can approve an action that the current sandbox refuses. That approval may authorize changing the permitted boundary, choosing a different tool, or moving the task to another environment. It does not make an execution outside the boundary sandboxed.
Define who may grant an exception, which command and destination it covers, how long it lasts, and what evidence is required afterward. The human-checkpoint design should make those consequences visible. A model-generated assertion that approval exists must not supply the approval itself.
A useful review ends with a narrow operating decision: this task can proceed with these tools, these paths, these destinations, and these recorded limitations. Repeat the relevant checks when the agent runtime, operating system, mounts, allowed domains, subprocess launcher, or exception policy changes.
Documentation reviewed October 28, 2026. The matrix is a proposed lab protocol. No sandbox probes, model trials, or containment measurements were executed for this article.