# Anthropic Sandbox Runtime (srt): OS-Level Sandboxing Without a Container

> srt wraps arbitrary processes in filesystem and network restrictions using native OS primitives instead of containers. It is a research preview aimed at agent and MCP server authors, and its settings format is still moving.

**anthropics/sandbox-runtime** — A lightweight sandboxing tool for enforcing filesystem and network restrictions on arbitrary processes at the OS level, without requiring a container.

- Repository: https://github.com/anthropics/sandbox-runtime
- Stars: 5,361 · Forks: 463
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/anthropics-sandbox-runtime

## What srt restricts, and who it is for

srt is a command wrapper. You put it in front of a process and the process runs under OS-level restrictions that apply to the whole process tree, not just the parent. The README frames the audience directly: agents, local MCP servers, bash commands and arbitrary processes. The concrete example it gives is the filesystem MCP server, which normally runs through npx with whatever access the user account has. Wrapped in srt, that server can be denied write access to a sensitive directory even though it starts from your shell.

The design philosophy stated in the README is secure by default: processes start with minimal access and you poke only the holes you need. That shows up in the defaults. Write access is denied everywhere until you allow a path. Network access is denied everywhere until you allow a domain. Read access works the other way around, which is the part worth reading twice: reads are allowed by default, and you deny broad regions and re-allow specific paths inside them.

That read model is a deliberate trade-off. It keeps the tool usable on a normal developer machine, where a process usually needs to read headers, libraries and config from many places. The cost is that the default posture for reads is permissive, so a sandboxed process can read anything you did not explicitly deny. If your threat model is a process exfiltrating SSH keys, the README's own example shows the answer: deny ~/.ssh/id_rsa and the read fails with Operation not permitted.

## How the dual isolation model works across macOS, Linux and Windows

The README is explicit that filesystem and network isolation are both required. Without file isolation, a process could read SSH keys or other sensitive files. Without network isolation, it could reach out freely. srt implements both with different primitives per platform, which is the main architectural fact to understand before adopting it.

On macOS, srt generates a Seatbelt profile and runs the process under sandbox-exec. Network access is limited to a specific localhost port where the proxies listen. On Linux, it uses bubblewrap, and the network namespace of the sandboxed process is removed entirely; traffic must go through proxies on the host that listen on Unix domain sockets bind-mounted into the sandbox. On Windows, the process runs under a dedicated srt-sandbox local user account, with a Windows Filtering Platform egress fence keyed on that account's SID and per-session explicit ACEs on the working tree. All outbound connections from that account are blocked except loopback to the proxy port range.

The network layer is a pair of proxies: an HTTP proxy for HTTP/HTTPS and a SOCKS5 proxy for other TCP traffic. Both enforce the domain allowlist and denylist. The dependency list in package.json is consistent with that: @pondwader/socks5-server and node-forge are both runtime dependencies, and node-forge is what you would expect for generating certificates to intercept TLS. The repository also carries a vendor directory with build scripts for seccomp, a Windows binary and a Java proxy agent, so parts of the runtime are not plain TypeScript.

The filesystem rules are asymmetric, and the README calls this out. Writes follow an allow-only pattern: denyWrite takes precedence over allowWrite. Reads follow a deny-then-allow pattern: allowRead takes precedence over denyRead, except that a denyRead entry more specific than the allowRead region it sits inside stays denied. That exception is what makes denyRead: ["**/.env"] work when you have already allowed the current directory for reading.

## Installing srt and sandboxing an MCP server

The package is published on npm as @anthropic-ai/sandbox-runtime and installs globally, which puts the srt binary on your path. The package declares a Node engine requirement of >=20.11.0, so check that before installing.

```bash
npm install -g @anthropic-ai/sandbox-runtime
```

The quickest way to see the two restriction types is to run commands through it. The README's own examples show a request to anthropic.com succeeding, a request to example.com blocked by the network allowlist, a read of the current directory allowed, and a read of ~/.ssh/id_rsa failing with Operation not permitted.

```bash
srt "curl anthropic.com"
srt "curl example.com"
srt "cat README.md"
srt "cat ~/.ssh/id_rsa"
```

For the MCP use case, the change is one line in .mcp.json: replace the command with srt and move the original command and arguments into args. The README gives this exact before and after, and it is the least invasive way to try the tool because nothing else about the server configuration changes.

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "srt",
      "args": ["npx", "-y", "@modelcontextprotocol/server-filesystem"]
    }
  }
}
```

Restrictions live in ~/.srt-settings.json. The README's example leaves denyRead empty, allows writes to the current directory, denies writes to a sensitive folder, and leaves both network lists empty, which under the allow-only network pattern means no outbound access at all.

```json
{
  "filesystem": {
    "denyRead": [],
    "allowWrite": ["."],
    "denyWrite": ["~/sensitive-folder"]
  },
  "network": {
    "allowedDomains": [],
    "deniedDomains": []
  }
}
```

After that, a write attempt into the denied path returns EPERM: operation not permitted. If you want the filesystem server to reach anything on the network, you have to name the domains in allowedDomains; leaving the list empty is a working configuration, not a missing one.

## Where srt is the wrong tool

The README labels the project a beta research preview and states that APIs and configuration formats may evolve. Treat that as a real constraint rather than boilerplate. A tool whose settings schema can change under you is a poor fit for a long-lived CI image or a security control you have documented for auditors. There is no compatibility promise in the README, and the version numbers are still in 0.0.x.

The platform story is uneven. On macOS, srt depends on sandbox-exec and Seatbelt profiles, and the README notes that violation monitoring through the system log store is available on macOS. On Linux, it depends on bubblewrap being present. On Windows, it creates and uses a dedicated srt-sandbox local account and machine-wide filtering rules. Each of those is a host-level dependency you have to provision and, on Windows, a machine-wide change rather than a per-process one. If you cannot create a local account or modify filtering rules on the host, the Windows path is closed to you.

Network mediation has its own limits. HTTP and HTTPS go through an HTTP proxy and other TCP traffic goes through SOCKS5, so the allowlist is enforced at the proxy, not by the kernel. A process that can find another route out of the sandbox is outside the model; the README's answer is to remove the route, as Linux does by deleting the network namespace. That is why the platform mechanisms matter more than the settings file when you are assessing the actual boundary.

Finally, srt is not a virtual machine and does not claim to be. It shares the host kernel and the host filesystem view, restricted by rules. If your requirement is a disposable environment with its own kernel or a different OS image, this is the wrong layer.

## srt compared with containers and with Claude Code's own sandboxing

The obvious alternative is a container runtime such as Docker, which is also what people search for alongside this project. The difference is where the boundary lives. A container gives you a separate filesystem image, its own network namespace and a defined image to rebuild, at the cost of building that image, mounting what the process needs, and running a daemon. srt gives you no image at all: the process runs on your host, with your files, and the restrictions are a generated OS profile plus proxies. Setup is a global npm install and a JSON file. The trade-off is that you inherit the host, so a rule you forgot to write is a hole, and there is no image boundary to fall back on.

Within Anthropic's own documentation there is a second comparison. The README points to Claude Code's sandboxing documentation and to an engineering post titled "Beyond Permission Prompts: Making Claude Code More Secure and Autonomous", and it says the runtime was developed for Claude Code. So if you are already using Claude Code's built-in sandboxing, srt is the standalone implementation of the same idea that you can point at processes Claude Code does not manage, such as an MCP server launched from another client or a plain bash command. The README presents the package as usable both as a CLI and as a library, with src/index.ts as the library export surface, so embedding it in your own tooling is an intended path rather than a workaround.

A third option worth naming is doing nothing and relying on the operating system account you already run as. That is the baseline srt is arguing against, and the dual isolation section of the README is the argument: one process, one account, no distinction between reading a README and reading ~/.ssh/id_rsa.

## Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-09-22. Releases are frequent and small: v0.0.75 on 2026-09-01, v0.0.76 on 2026-09-10, v0.0.77 on 2026-09-18. That cadence is consistent with a research preview that is still being adjusted, and it is the practical upgrade cost you should budget for. Pinning a version is the only way to avoid surprise, and the 0.0.x numbering means npm's caret range will not protect you the way it would on a 1.x package.

The licence is Apache-2.0. That is a permissive licence with an explicit patent grant and a requirement to preserve notices and state changes. It is compatible with commercial use, but this is not legal advice and the licence text in the repository is the authority. If you redistribute srt inside a product, read the NOTICE and modification clauses in LICENSE rather than the summary.

One structural detail affects maintenance planning: the build is not a single tsc invocation. package.json defines build:seccomp, build:srt-win and build:java-agent scripts that run through bun against the vendor directory, alongside the ordinary build script. If you build from source rather than installing the published package, you need bun and the vendored sources, not just Node and TypeScript. Installing the npm package avoids that entirely.

Finally, the README states that feedback and contributions are welcome and that configuration formats may evolve. If you are adopting srt, the settings file is the artifact most likely to need rewriting on upgrade, so keep it small and keep it in one place.

## Conclusion

Adopt srt if you run agents, MCP servers or shell commands you do not fully trust and you want OS-level restrictions without a container runtime. Skip it if you need a stable configuration contract in production, since the README labels it a beta research preview and warns that APIs and configuration formats may evolve. Before rolling it out, verify three things on your own machine: that your platform path works (sandbox-exec on macOS, bubblewrap on Linux, the srt-sandbox account on Windows), that your allowlist actually blocks what you expect, and that ~/.srt-settings.json parses the way you intend, because an empty allowWrite or allowedDomains list means no access rather than full access.

## FAQ

### How do I install Anthropic Sandbox Runtime?

Install it globally from npm with npm install -g @anthropic-ai/sandbox-runtime, which provides the srt command. The package requires Node >=20.11.0.

### How is srt different from a virtual machine?

srt applies OS-level restrictions to a process running on your host rather than giving it a separate machine. Its boundary is a generated sandbox profile plus proxies, not a separate kernel or disk image.

### What happens if allowedDomains is empty in srt settings?

Network access follows an allow-only pattern, so an empty allowedDomains list means no network access. The same applies to allowWrite: an empty allow list means no write access.

### Is srt an official Anthropic product?

The README describes it as a beta research preview developed for Claude Code and released as an early open source preview, and warns that APIs and configuration formats may evolve.

## Sources

- [anthropics/sandbox-runtime on GitHub](https://github.com/anthropics/sandbox-runtime)
- [Issues](https://github.com/anthropics/sandbox-runtime/issues)
- [License: Apache-2.0](https://github.com/anthropics/sandbox-runtime/blob/main/LICENSE)
- [README](https://github.com/anthropics/sandbox-runtime/blob/main/README.md)
- [Releases](https://github.com/anthropics/sandbox-runtime/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/anthropics-sandbox-runtime
