
sandbox-runtime v0.0.74
一个轻量级沙箱工具,用于在操作系统层面强制执行任意进程的文件系统和网络限制,而无需使用容器。
Anthropic Sandbox Runtime (srt)
一款轻量级沙箱工具,可在操作系统层面为任意进程强制执行文件系统和网络限制,无需依赖容器。
srt 使用操作系统原生的沙箱原语(macOS 上的 sandbox-exec、Linux 上的 bubblewrap)以及基于代理的网络过滤。它可用于对智能体、本地 MCP 服务器、bash 命令和任意进程的行为进行沙箱隔离。
Beta 研究预览版
Sandbox Runtime 是为 Claude Code 开发的研究预览版,旨在实现更安全的 AI 智能体。它作为早期开源预览版发布,以帮助更广泛的生态系统构建更安全的智能体系统。由于这是早期研究预览版,API 和配置格式可能会发生变化。我们欢迎反馈和贡献,让 AI 智能体默认更安全!
安装
npm install -g @anthropic-ai/sandbox-runtime
基本用法
# 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
概述
此包提供了一个独立的沙箱实现,既可作为 CLI 工具使用,也可作为库使用。它遵循默认安全的设计理念,针对常见的开发者使用场景量身定制:进程以最小权限启动,你只需显式地打开所需的权限缺口。
主要能力:
- 网络限制:控制可通过 HTTP/HTTPS 及其他协议访问的主机/域名
- 文件系统限制:控制可读取/写入的文件/目录
- Unix 套接字限制:控制对本地 IPC 套接字的访问
- 违规监控:在 macOS 上,接入系统的沙箱违规日志存储以获取实时警报
示例用例:沙箱化 MCP 服务器
一个关键用例是对 Model Context Protocol (MCP) 服务器进行沙箱化,以限制其能力。例如,对文件系统 MCP 服务器进行沙箱化:
不使用沙箱(.mcp.json):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem"]
}
}
}
启用沙箱(.mcp.json):
{
"mcpServers": {
"filesystem": {
"command": "srt",
"args": ["npx", "-y", "@modelcontextprotocol/server-filesystem"]
}
}
}
然后在 ~/.srt-settings.json 中配置限制:
{
"filesystem": {
"denyRead": [],
"allowWrite": ["."],
"denyWrite": ["~/sensitive-folder"]
},
"network": {
"allowedDomains": [],
"deniedDomains": []
}
}
现在 MCP 服务器将被阻止写入被拒绝的路径:
> Write a file to ~/sensitive-folder
✗ Error: EPERM: operation not permitted, open '/Users/ollie/sensitive-folder/test.txt'
工作原理
该沙箱使用操作系统级原语来强制执行适用于整个进程树的限制:
- macOS:使用
sandbox-exec配合动态生成的 Seatbelt 配置文件 - Linux:使用 bubblewrap 进行容器化,并实现网络命名空间隔离
- Windows:在专用的
srt-sandbox本地用户账户下运行沙箱进程,使用以该账户 SID 为键的 Windows 筛选平台 出站防护、写入受限令牌,以及工作树上的显式 ACE
0d1c612947c798aef48e6ab4beb7e8544da9d41a-4096x2305
双重隔离模型
文件系统隔离和网络隔离对于有效的沙箱化都是必需的。没有文件隔离,被攻陷的进程可能窃取 SSH 密钥或其他敏感文件。没有网络隔离,进程可能逃逸沙箱并获得不受限制的网络访问。
文件系统隔离强制执行读和写限制:
- 读(先拒绝后允许模式):默认情况下,所有位置都允许读取。你可以拒绝较大的区域(例如
/Users),然后重新允许其中的特定路径(例如.)。allowRead优先于denyRead——这与写相反,写操作中denyWrite优先于allowWrite。如果denyRead条目比其所在的allowRead区域更具体(例如denyRead: ["**/.env"]或["./secrets"]配合allowRead: ["."]),则仍然保持拒绝。 - 写(仅允许模式):默认情况下,所有位置都拒绝写入。你必须显式允许路径(例如
.、/tmp)。空的允许列表意味着没有写入权限。
网络隔离(仅允许模式):默认情况下,所有网络访问都被拒绝。你必须显式允许域名。空的 allowedDomains 列表意味着没有网络访问。网络流量通过运行在主机上的代理服务器进行路由:
-
Linux:请求通过 Unix 域套接字经由文件系统进行路由。沙箱进程的网络命名空间被完全移除,因此所有网络流量都必须经过运行在主机上的代理(监听绑定挂载到沙箱中的 Unix 套接字)
-
macOS:Seatbelt 配置文件仅允许与特定 localhost 端口通信。代理监听该端口,为所有网络访问创建受控通道
-
Windows:机器范围的 WFP 筛选器集阻止以
srt-sandbox账户运行的进程发起的出站连接,但到代理端口范围的环回连接除外。代理在该范围内监听,为所有网络访问创建受控通道。这些筛选器不会跟随在创建套接字之前将不同令牌放到线程上的沙箱进程,也不会跟随系统服务代表其承载的流量;请参阅 Windows 已知限制
HTTP/HTTPS(通过 HTTP 代理)和其他 TCP 流量(通过 SOCKS5 代理)都由这些代理进行中介,代理会强制执行你的域名允许列表和拒绝列表。
有关 Claude Code 中沙箱化的更多详细信息,请参阅:
架构
src/
├── index.ts # Library exports
├── cli.ts # CLI entrypoint (srt command)
├── utils/ # Shared utilities
│ ├── debug.ts # Debug logging
│ ├── settings.ts # Settings reader (permissions + sandbox config)
│ ├── platform.ts # Platform detection
│ └── exec.ts # Command execution utilities
└── sandbox/ # Sandbox implementation
├── sandbox-manager.ts # Main sandbox manager
├── sandbox-schemas.ts # Zod schemas for validation
├── sandbox-violation-store.ts # Violation tracking
├── sandbox-utils.ts # Shared sandbox utilities
├── http-proxy.ts # HTTP/HTTPS proxy for network filtering
├── socks-proxy.ts # SOCKS5 proxy for network filtering
├── linux-sandbox-utils.ts # Linux bubblewrap sandboxing
├── macos-sandbox-utils.ts # macOS sandbox-exec sandboxing
└── windows-sandbox-utils.ts # Windows srt-win sandboxing
用法
作为 CLI 工具
srt 命令(Anthropic Sandbox Runtime)会用安全边界封装任意命令:
# 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
设置文件是可选的——如果 ~/.srt-settings.json 处没有文件,srt 会使用内置默认值运行:无网络访问、不在默认写入路径之外写入,且读取不受限制。如果设置文件_确实_存在但为空、无法读取或未通过校验,则视为错误:srt 会报告该错误并退出,而不是回退到那些默认值,因为默认值是一种不同的配置,而非更弱的配置——回退会丢弃文件中的 denyRead、allowRead 和凭据规则以及它声明的其他所有内容。通过 --settings 指定的文件同样如此,该文件也必须存在。
在命令运行期间更新配置:--control-fd
--control-fd <fd> 从调用方已打开的描述符读取配置更新,每行一个 JSON 对象,其结构与设置文件相同。每一行都会替换整个配置,并按照相同的 schema 进行校验,因此一行是一个完整配置而非补丁:network 和 filesystem 为必填项,某行省略的键会恢复为其默认值。
# fd 3 is the read end of a pipe the caller writes lines to
srt --control-fd 3 -- npm test
命令运行后,被接受的配置行会改变以下内容:
- 网络列表——
network.allowedDomains、deniedDomains(含deniedDomainReasons)和deniedResolvedAddresses——会在下一次连接时 生效,且在所有平台上均如此:代理会按请求查询这些列表,解析地址检查也会 根据同一配置行重建。network.mitmProxy和network.tlsTerminate.excludeDomains同样如此,它们也是按请求读取的。 credentials.sigv4会在下一次请求时生效,前提是 srt 启动时带有credentials块:签名钩子仅在这种情况下才会安装,并且会按请求读取策略, 而不是在安装时捕获策略。- 其他内容不会改变。文件系统规则已经写入 seatbelt 配置文件、bubblewrap
argv 或 Windows ACE 中,凭据掩码在命令被包装时就已经构建完成,而正在运行的
代理服务器在启动时就已经捕获了
network.parentProxy以及是否终止 TLS 的 设置。 - 在 Windows 上,如果某配置行的文件访问集合(
filesystem.*与credentials.files的并集)与启动时应用的集合不同,srt 会注意到这一点, 但仅在SRT_DEBUG下才会提示:ACL 授权是会话级的,因此启动时应用的集合 会继续生效。配置行的其余部分按上述方式应用。
srt 如何读取通道,以及它会拒绝什么:
- 描述符必须是 3 或以上 的整数且可读——
0-2是标准流。当 srt 无法 读取给定的描述符时,它会报错退出而不是运行命令,因此失效的通道永远不会被 当作有效通道。如果在传递任何更新之前通道就失效,命令会随之终止;如果在 传递更新之后失效,srt 会报告该情况,并让命令在最后应用的配置下继续运行。 - 不是有效配置的行会在 stderr 上报告并被丢弃;之前的配置继续生效。该行本身 会写入调试日志而不是终端,空行会被静默忽略。
- srt 仅在沙箱启动后才开始读取,因此在此之前写入的更新会在通道中等待而不会 丢失——也不会被沙箱启动时使用的配置覆盖。这样的行可能会在命令仍在被包装 时被读取,此时它就成为包装命令所用的配置,包括文件系统规则。是否会被那么早 读取取决于包装耗时(在 Linux 上,对大型目录树执行 deny glob 就足够长), 因此命令必须在其下启动的规则应放在设置文件中。
- srt 会随被包装的命令一起退出,不会等待写入方关闭描述符。输入结束也不是 错误:命令会在最后应用的配置下继续运行。
- 给 srt 一个专用的、只读的端。srt 会将管道或套接字置于非阻塞模式,而该
标志存在于打开的文件描述上,因此任何其他持有同一描述的对象——shell 的
exec 3<fifo、父进程继续使用的描述符的pass_fds——从此以后其自身的阻塞 读取都会得到EAGAIN。 - 在 macOS 和 Linux 上,沙箱内的命令不会获得该描述符:srt 会将该槽位指向
/dev/null,因此沙箱内的任何内容都无法读取更新或写入自己的配置。在 Windows 上,命令仅以三个标准流启动,因此控制描述符不在传递给它的描述符 之中。
作为带外部决策器的独立代理:srt proxy
srt proxy(或由 bun run build:srt-proxy 构建的单文件 srt-proxy 可执行
文件)仅运行 SRT 的 HTTP 代理,不包含沙箱子进程,适用于在别处运行工作负载的
主机。它在主机传入的监听套接字上接受连接,在进程内终止每个 CONNECT,并且仅当
通过另一个继承描述符访问的独立决策器进程允许时,才转发请求。有关命令行、决策器
协议和安全模型,请参阅 docs/srt-proxy.md。
作为库使用
import {
SandboxManager,
type SandboxRuntimeConfig,
} from '@anthropic-ai/sandbox-runtime'
import { spawn } from 'child_process'
// Define your sandbox configuration
const config: SandboxRuntimeConfig = {
network: {
allowedDomains: ['example.com', 'api.github.com'],
deniedDomains: [],
},
filesystem: {
denyRead: ['~/.ssh'],
allowWrite: ['.', '/tmp'],
denyWrite: ['.env'],
},
}