Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
S

sandbox-runtime

> 编程语言
Open source

A lightweight sandboxing tool for enforcing filesystem and network restrictions on arbitrary processes at the OS level, without requiring a container.

4.8K stars0 likes0 views
WebsiteGitHub

About

A lightweight sandboxing tool for enforcing filesystem and network restrictions on arbitrary processes at the OS level, without requiring a container.

Anthropic Sandbox Runtime (srt)

A lightweight sandboxing tool for enforcing filesystem and network restrictions on arbitrary processes at the OS level, without requiring a container.

srt uses native OS sandboxing primitives (sandbox-exec on macOS, bubblewrap on Linux) and proxy-based network filtering. It can be used to sandbox the behaviour of agents, local MCP servers, bash commands and arbitrary processes.

Beta Research Preview

The Sandbox Runtime is a research preview developed for Claude Code to enable safer AI agents. It's being made available as an early open source preview to help the broader ecosystem build more secure agentic systems. As this is an early research preview, APIs and configuration formats may evolve. We welcome feedback and contributions to make AI agents safer by default!

Installation

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

Basic Usage

# Network restrictions
$ srt "curl anthropic.com"
Running: curl anthropic.com
<html>...</html>  # Request succeeds

$ srt "curl example.com"
Running: curl example.com
Connection blocked by network allowlist  # Request blocked

# Filesystem restrictions
$ srt "cat README.md"
Running: cat README.md
# Anthropic Sandb...  # Current directory access allowed

$ srt "cat ~/.ssh/id_rsa"
Running: cat ~/.ssh/id_rsa
cat: /Users/ollie/.ssh/id_rsa: Operation not permitted  # Specific file blocked

Overview

This package provides a standalone sandbox implementation that can be used as both a CLI tool and a library. It's designed with a secure-by-default philosophy tailored for common developer use cases: processes start with minimal access, and you explicitly poke only the holes you need.

Key capabilities:

  • Network restrictions: Control which hosts/domains can be accessed via HTTP/HTTPS and other protocols
  • Filesystem restrictions: Control which files/directories can be read/written
  • Unix socket restrictions: Control access to local IPC sockets
  • Violation monitoring: On macOS, tap into the system's sandbox violation log store for real-time alerts

Example Use Case: Sandboxing MCP Servers

A key use case is sandboxing Model Context Protocol (MCP) servers to restrict their capabilities. For example, to sandbox the filesystem MCP server:

Without sandboxing (.mcp.json):

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

With sandboxing (.mcp.json):

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

Then configure restrictions in ~/.srt-settings.json:

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

Now the MCP server will be blocked from writing to the denied path:

> Write a file to ~/sensitive-folder
✗ Error: EPERM: operation not permitted, open '/Users/ollie/sensitive-folder/test.txt'

How It Works

The sandbox uses OS-level primitives to enforce restrictions that apply to the entire process tree:

  • macOS: Uses sandbox-exec with dynamically generated Seatbelt profiles
  • Linux: Uses bubblewrap for containerization with network namespace isolation
  • Windows: Runs the sandboxed process 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

Dual Isolation Model

Both filesystem and network isolation are required for effective sandboxing. Without file isolation, a compromised process could exfiltrate SSH keys or other sensitive files. Without network isolation, a process could escape the sandbox and gain unrestricted network access.

Filesystem Isolation enforces read and write restrictions:

  • Read (deny-then-allow pattern): By default, read access is allowed everywhere. You can deny broad regions (e.g., /Users) and then re-allow specific paths within them (e.g., .). allowRead takes precedence over denyRead — the opposite of write, where denyWrite takes precedence over allowWrite. A denyRead entry that is more specific than the allowRead region it falls inside (e.g. denyRead: ["**/.env"] or ["./secrets"] with allowRead: ["."]) still stays denied.
  • Write (allow-only pattern): By default, write access is denied everywhere. You must explicitly allow paths (e.g., ., /tmp). An empty allow list means no write access.

Network Isolation (allow-only pattern): By default, all network access is denied. You must explicitly allow domains. An empty allowedDomains list means no network access. Network traffic is routed through proxy servers running on the host:

  • Linux: Requests are routed via the filesystem over a Unix domain socket. The network namespace of the sandboxed process is removed entirely, so all network traffic must go through the proxies running on the host (listening on Unix sockets that are bind-mounted into the sandbox)

  • macOS: The Seatbelt profile allows communication only to a specific localhost port. The proxies listen on this port, creating a controlled channel for all network access

  • Windows: A machine-wide WFP filter set blocks all outbound connections originating from the srt-sandbox account except loopback to the proxy port range. The proxies listen inside that range, creating a controlled channel for all network access

Both HTTP/HTTPS (via HTTP proxy) and other TCP traffic (via SOCKS5 proxy) are mediated by these proxies, which enforce your domain allowlists and denylists.

For more details on sandboxing in Claude Code, see:

  • Claude Code Sandboxing Documentation
  • Beyond Permission Prompts: Making Claude Code More Secure and Autonomous

Architecture

…

Usage

As a CLI tool

The srt command (Anthropic Sandbox Runtime) wraps any command with security boundaries:

# Run a command in the sandbox
srt echo "hello world"

# With debug logging
srt --debug curl https://example.com

# Specify custom settings file
srt --settings /path/to/srt-settings.json npm install

As a library

…

Violation attribution (commandId / commandText). Violations observed while a wrapped command runs (seatbelt log lines, seccomp events, proxy denies) are stored under an attribution key, and annotateStderrWithSandboxFailures(key, stderr) / getViolationsForCommand(key) look them up by that same key. By default the key is the wrapped string itself. Pass an opaque per-invocation commandId (e.g. a tool-use id) to key by that instead — recommended: keys compare on their first 100 characters, so long commands sharing a prefix would otherwise cross-attribute, and a rerun of the same text would inherit the earlier run's events. If the string you execute is not the command the invocation represents (e.g. you wrap an assembled source <snapshot> && eval '<cmd>'), also pass commandText: '<cmd>': it is what ignoreViolations command patterns match against and what each violation reports as its command.

const wrapped = await SandboxManager.wrapWithSandbox(
  assembledCommand, // what actually runs
  undefined,
  undefined,
  undefined,
  { commandId: invocationId, commandText: rawCommand },
)
// ... run it ...
const annotated = SandboxManager.annotateStderrWithSandboxFailures(
  invocationId,
  stderr,
)

Available exports

// Main sandbox manager
export { SandboxManager } from '@anthropic-ai/sandbox-runtime'

// Violation tracking
export { SandboxViolationStore } from '@anthropic-ai/sandbox-runtime'

// TypeScript types
export type {
  SandboxRuntimeConfig,
  NetworkConfig,
  FilesystemConfig,
  IgnoreViolationsConfig,
  SandboxAskCallback,
  FsReadRestrictionConfig,
  FsWriteRestrictionConfig,
  NetworkRestrictionConfig,
} from '@anthropic-ai/sandbox-runtime'

Configuration

Settings File Location

By default, the sandbox runtime looks for configuration at ~/.srt-settings.json. You can specify a custom path using the --settings flag:

srt --settings /path/to/srt-settings.json <command>

Complete Configuration Example

…

Configuration Options

Network Configuration

Uses an allow-only pattern - all network access is denied by default.

  • network.allowedDomains - Array of allowed domains (supports wildcards like *.example.com). Empty array = no network access. An optional :port suffix (api.example.com:443, *.example.com:8443) restricts an entry to that destination port; entries without a port match any port.
    • IPv6 literals must be bracketed, RFC 3986-style: [::1], [2001:db8::1]:443. An unbracketed multi-colon entry is rejected as ambiguous (2001:db8::1:443 is itself a valid address).
  • network.deniedDomains - Array of denied domains (checked first, takes precedence over allowedDomains). Same :port suffix, and a bare * (or *:22) is accepted for deny-all.
  • network.deniedDomainReasons - Optional map from a deniedDomains entry (matched by exact string) to a model-facing reason that appears in the <sandbox_violations> line when that entry denies a connection — say what is blocked and the sanctioned alternative (e.g. {"github.com:22": "SSH pushes to GitHub are blocked; use an https:// remote"}). Entries without a reason report a generic one. For SSH destinations (port 22), the reason is also delivered in-band: an SSH client tunneled through a no-auth SOCKS ProxyCommand (e.g. BSD nc -X 5) receives a pre-key-exchange SSH disconnect whose description is the reason, which OpenSSH prints verbatim — keep such reasons under ~400 ASCII characters, imperative first, since OpenSSH truncates and escapes non-ASCII.
  • network.allowLocalBinding - Allow binding to local ports (boolean, default: false)

Resolved-address check. The allow/deny lists match by name, but whoever controls a permitted name's DNS (or any label under a permitted wildcard) controls what it resolves to. So before dialing an allowed hostname directly, the proxy resolves it once, drops any address in a denied set, and connects to a surviving address (the address that passed the check is the one dialed — there is no second lookup). If nothing survives, the connection is refused like any other policy denial: HTTP/CONNECT get 403 (X-Proxy-Error: blocked-by-sandbox-runtime, the reason in the body), SOCKS gets "connection not allowed by ruleset", and a deny network-outbound host:port (resolved to a loopback address) line — naming the class of address (loopback, link-local, this host's, cloud metadata, deny-listed, listed, …), not the address itself, which only the debug log carries — is recorded in the violation store.

The denied set is: loopback (127.0.0.0/8, ::1), unspecified (0.0.0.0/8, ::), link-local (169.254.0.0/16, fe80::/10), multicast (224.0.0.0/4, ff00::/8), broadcast, the cloud instance-metadata / platform endpoints that live outside link-local (100.100.100.200, 168.63.129.16, 192.0.0.192, fd00:ec2::/32, fd20:ce::254, fd00:c1::a9fe:a9fe, fd00:42::42), every address currently assigned to one of this host's own network interfaces (a service bound to 0.0.0.0 answers on the LAN or global address exactly as it does on loopback), every IP literal listed in deniedDomains (honouring its :port if it has one), and an

GitHub Issues· 0 open

View all on GitHub

No open issues yet, or sync has not completed.

Highlights

  • •Network restrictions: Control which hosts/domains can be accessed via HTTP/HTTPS and other protocols
  • •Filesystem restrictions: Control which files/directories can be read/written
  • •Unix socket restrictions: Control access to local IPC sockets
  • •Violation monitoring: On macOS, tap into the system's sandbox violation log store for real-time alerts
  • •macOS: Uses sandbox-exec with dynamically generated Seatbelt profiles
  • •Linux: Uses bubblewrap for containerization with network namespace isolation
  • •Write (allow-only pattern): By default, write access is denied everywhere. You must explicitly allow paths (e.g., ., /tmp). An empty allow list means no write access.
  • •macOS: The Seatbelt profile allows communication only to a specific localhost port. The proxies listen on this port, creating a controlled channel for all network access
  • •Claude Code Sandboxing Documentation
  • •Beyond Permission Prompts: Making Claude Code More Secure and Autonomous

> Tags

TypeScript

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言