--sandbox 开关会让 CLI 在操作系统级隔离环境中运行,在操作系统层面强制执行当前启用的 Read 和 Write 权限作用域,并可选择限制网络流量。
当沙盒处于启用状态时:
- 可写路径根据已授予的
Write(...) 权限作用域以及工作区目录解析得出
- 可读路径根据已授予的
Read(...) 作用域解析得出 (平台默认路径 (如 /usr/bin) 始终可读)
- 在会话中途授予的作用域会动态扩展沙盒,并应用于后续命令
如果沙盒解析失败 (例如,用户平台上无法使用沙盒工具) ,CLI 将会拒绝启动,而不会在未启用沙盒的情况下运行。无论沙盒是通过团队设置启用,还是由用户直接传入 --sandbox 启用,都会采用这种故障即关闭的行为,以确保安全意图绝不会被悄然绕过。沙盒解析失败的常见原因:
- Windows:Windows 当前不支持操作系统级沙盒。在 Windows 上,当传入
--sandbox 或沙盒强制执行为 必填 时,会话将直接失败;这也包括 CLI 作为 IDE (例如 Devin Desktop) 中的 ACP server 运行时。
- Linux:沙盒化要求已安装
bubblewrap (bwrap) 和 socat。如果缺少这些依赖,会话将直接失败,并显示安装指示。
- 权限作用域错误:权限作用域中的路径无效,无法解析。
沙盒网络过滤目前还不稳定。如果你需要此功能,请联系你的账户代表,了解稳定性时间预期。
在配置文件的 sandbox 部分 (仅用户配置) 中为沙盒配置域名级网络过滤。当 --sandbox 启用且已配置域名过滤时,系统会在回环接口上启动一个受管网络代理,沙盒会将所有子进程流量限制为只能通过该代理路由。
| Option | Type | Default | Description |
|---|
allowed_domains | string[] | [] | 允许通过代理的域名模式。非空时,仅允许匹配的域名 (允许列表模式) |
denied_domains | string[] | [] | 始终阻止的域名模式。拒绝规则优先于允许规则 |
network_mode | string | "full" | "full" 允许所有 HTTP 方法;"limited" 仅允许 GET/HEAD/OPTIONS |
域名模式语法:
| Pattern | Matches |
|---|
example.com | 仅精确匹配 |
*.example.com | 任意子域名 (不包括根域名) |
**.example.com | 根域名及其任意子域名 |
示例:
{
"sandbox": {
"allowed_domains": [
"github.com",
"**.npmjs.org",
"**.crates.io",
"**.pypi.org"
],
"denied_domains": ["evil.example.com"],
"network_mode": "full"
}
}
只有在启用沙盒 (--sandbox) 时,域名过滤才会生效。未启用 --sandbox 时,沙盒部分会被忽略。
有时,某些特定命令需要在沙盒之外运行——例如必须访问凭据的 git 命令,或会被沙盒拦截的钩子。sandbox.excluded 配置部分允许你使用与 permissions 相同的 Exec(...) 规则语法,将匹配的命令排除在沙盒隔离之外:
| 选项 | 类型 | 说明 |
|---|
excluded.allow | string[] | 匹配的命令会自动在沙盒外运行 |
excluded.ask | string[] | 匹配的命令会在用户批准提示后在沙盒外运行 |
excluded.deny | string[] | 匹配的命令永远不会被排除——它们始终会留在沙盒内运行 |
示例:
{
"sandbox": {
"excluded": {
"allow": ["Exec(git status *)"],
"ask": ["Exec(git push *)"],
"deny": ["Exec(git tag *)"]
}
}
}
**规则解析:**对于每条命令,在同一来源内,以最具体的匹配规则为准 (例如,Exec(git push *) 优先于 Exec(git *)) ;如果用户配置和团队设置都匹配,则以限制更严格的判定为准 (deny > ask > allow) 。没有匹配规则的命令——包括完全未配置 sandbox.excluded 的情况——始终在沙盒内运行。
sandbox.excluded 仅支持 Exec(...) 规则;其他任何规则类型 (例如 Read(...)、Write(...)) 都会被忽略,并发出警告。
- 排除机制采用故障关闭原则:如果某条命令无法被安全解析 (例如无法解析) ,它就会保留在沙盒内。
- 排除规则适用于默认的按命令执行路径。通过持久 PTY shell 运行的命令 (交互式会话,或启用
pty_for_noninteractive_exec 时) 始终保留在沙盒内。
Enterprise Admin 可通过团队设置控制整个组织的沙盒行为。
为你的组织中的 --sandbox 开关设置强制执行级别:
- 可选 (默认) — 用户可自行选择是否传递
--sandbox。不强制执行。
- 必填 — 对所有用户强制启用
--sandbox 开关,即使他们没有在命令行中传递该开关也是如此。所有 CLI 会话都会在启用 操作系统级沙盒 的环境中运行,并强制执行读/写权限作用域。
未来的 Strict 模式可能会完全锁定沙盒配置,阻止用户修改沙盒设置。
在将你的组织中的沙盒强制执行模式设置为 必填 之前,请确保所有目标机器都已完成预配。如果有任何用户使用 Windows,那么在 Windows 支持 操作系统级沙盒 之前,或者在策略放宽为 可选 之前,他们将无法运行 CLI。
Admins 还可以配置组织范围内的域名允许列表和拒绝列表:
- 域名允许列表 — 设置后,只有此列表中的域名才能通过沙盒网络代理访问。此列表是最终生效的:它会完全覆盖用户配置的
allowed_domains。用户无法通过添加额外域名来绕过 Admins 的限制。
- 域名拒绝列表 — 始终会被阻止的域名。Enterprise 拒绝域名列表是叠加的:它会与用户本地的
denied_domains 合并,使最终列表的限制更严格。
企业级域名列表与用户域名列表的交互方式:
| 场景 | Enterprise 配置 | 用户配置 | 实际结果 |
|---|
| Admin 设置允许列表 | allowed_domains: ["github.com"] | allowed_domains: ["npmjs.org"] | 仅允许 github.com (enterprise 会覆盖用户列表) |
| Admin 设置拒绝列表 | denied_domains: ["evil.com"] | denied_domains: ["risky.io"] | evil.com 和 risky.io 都会被阻止 (合并后生效) |
| 没有 Admin 允许列表 | allowed_domains: [] | allowed_domains: ["github.com"] | 使用用户的允许列表 |
由于用户本地的 denied_domains 会被保留并以叠加方式合并,用户可能会拒绝某个已出现在 Enterprise 允许列表中的域名。这是有意设计的:最终效果只会更严格,不会更宽松。如果因此导致访问问题,用户应从本地配置中移除冲突条目。
Admins 也可以在团队设置中设置适用于整个组织的排除命令规则:
- 排除 allow / ask — 用于可在整个组织中于沙盒外运行的命令的
Exec(...) 规则,可自动运行或在提示后运行。
- 排除 deny — 用于绝不能在沙盒外运行的命令的
Exec(...) 规则。团队级 deny 会覆盖任何用户级、针对匹配命令的 allow 或 ask,因此用户无法排除其 admins 已锁定的命令。
团队规则和用户规则会一并解析:在每个来源内,以最具体的匹配规则为准;跨来源时,以限制更严格的判定为准 (deny > ask > allow) 。
示例:锁定除 gh 之外的所有排除。 使用带 allow 例外的通配符 deny 后,除 gh 外的所有命令都会保留在沙盒内,无论用户在本地如何配置。这些值应填入 team-settings 的 excluded-commands 配置中 (不是用户配置文件,因此没有外层 sandbox 键) :
{
"excluded": {
"deny": ["Exec(**)"],
"allow": ["Exec(gh *)"]
}
}
由于更具体的 Exec(gh *) 规则优先于通配符 Exec(**),gh 命令会在沙盒外运行,而其他所有命令都留在沙盒内——并且团队级的通配符 deny 会覆盖其他命令的任何用户级 allow 或 ask 规则。
- 团队设置 — 企业级沙盒强制执行与域名过滤
- 配置文件参考 — 用户级
sandbox 配置部分
- 权限 — 用于确定沙盒路径解析的权限作用域