首页
/ Open Interpreter 沙盒与批准机制完全指南:从 Sandbox Mode 到 Approval Policy 的权限治理实战

Open Interpreter 沙盒与批准机制完全指南:从 Sandbox Mode 到 Approval Policy 的权限治理实战

2026-09-06 18:44:04作者:劳婵绚Shirley

Open Interpreter 将“本地命令能做什么”和“何时停下来征求用户同意”拆分为两套相互独立的控制机制:沙盒模式(Sandbox Mode) 划定命令执行的技术边界,批准策略(Approval Policy) 决定代理在多大幅度内自主行动。本文以仓库中 docs/sandbox.md 为核心骨架,结合 docs/permissions.md、配置参考与 codex-rs 底层 Rust 实现源码,系统讲解三种沙盒模式、三种批准策略、workspace-write 网络与可写根目录的配置方法、受保护路径语义、各操作系统(macOS / Linux / WSL / Windows)的强制实现,以及面向不同使用场景的推荐安全基线。读完你将能够为"审查陌生代码""日常仓库开发""CI 自动化""一次性高权限环境"等场景设计出既可用又克制的本地执行安全策略,并理解背后每一层限制是由哪个源码模块实际落地执行的。

双保险机制:沙盒边界 + 批准策略,缺一不可

官方文档开门见山地给出了安全模型的核心:Open Interpreter 有两条彼此独立的安全控制线(见 docs/sandbox.md):

  • 沙盒模式(Sandbox mode):控制本地命令执行的技术边界——它决定一个进程能读哪些文件、写哪些文件、能不能访问网络,属于操作系统层面的隔离与约束。
  • 批准策略(Approval policy):控制代理何时暂停并询问用户——它决定命令在被执行前是否需要经过人的确认,属于人与代理之间的交互契约。

这两者的职责完全不同:沙盒描述的是"能力上限",批准描述的是"自主程度"。例如在 workspace-write 沙盒里,代理有能力写入工作区,但如果批准策略是 on-request,凡是越出沙盒的"升级操作"仍要先询问你。

在交互式 TUI 中,可以用 /permissions 命令随时查看或变更当前的沙盒与批准姿态(交互命令列表见 docs/interactive.md,TUI 侧的权限弹层实现在 codex-rs/tui/src/chatwidget/permissions_menu.rs)。若某个目录已经有过信任/不信任决策、且配置里没有显式 sandbox_mode,系统还会据此自动推导默认沙盒,这一点在后文"默认值推导"中详细说明。

沙盒模式(Sandbox Modes)详解

docs/sandbox.md 给出了三档模式的核心行为对照:

模式 行为
read-only 命令可以检查被允许的文件,但不能写入。
workspace-write 命令可以在活动工作区根目录内写入。除非显式启用,否则网络关闭。
danger-full-access 没有本地沙盒边界。仅在你有意信任的环境中使用。

在源码层面,三档模式对应协议层定义的三值枚举 SandboxMode,见 codex-rs/protocol/src/config_types.rs

  • ReadOnly:序列化为 read-only,且是该枚举的默认值
  • WorkspaceWrite:序列化为 workspace-write
  • DangerFullAccess:序列化为 danger-full-access

枚举的默认值是 read-only,这与"默认最保守"的安全取向一致。三种模式还会以提示模板的形式注入到代理的系统提示中,告诉模型"自己正处在什么边界里"——模板存放在 codex-rs/prompts/templates/permissions/sandbox_mode/。例如 read_only.md 说明当前沙盒"只允许读取文件",workspace_write.md 说明"允许读取文件、编辑 cwdwritable_roots 内的文件,编辑其他目录需要批准"——这正是 workspace-write 语义的模型侧自述,和下方配置行为完全对应。

如何设置沙盒模式

1. 写入持久化配置(TOML),让它成为会话默认值:

sandbox_mode = "workspace-write"

完整可参考仓库自带的 docs/example-config.md(其中沙盒与批准段为 sandbox_mode = "workspace-write"approval_policy = "on-request"),以及顶层配置键汇总表 docs/config-reference.md。持久化配置的存放位置与优先级见 docs/config.md:用户级配置在 ~/.openinterpreter/config.toml,可信项目可在项目根的 .openinterpreter/config.toml 放置项目级配置;命令行 -c key=value 覆盖只对当次调用生效。

2. 单次会话覆盖,用命令行开关强制指定:

interpreter --sandbox read-only "audit the auth flow"

docs/cli-reference.md 中该开关登记为 --sandbox, -s <mode>,可取值正是 read-onlyworkspace-writedanger-full-access。CLI 侧参数解析在 codex-rs/utils/cli/src/shared_options.rs(clap 参数 --sandbox/-s)与 codex-rs/cli/src/main.rs 中完成。

新旧系统的取舍:docs/permissions.md 明确指出,权限配置(Permission Profiles)是比旧 sandbox_mode + sandbox_workspace_write 更细粒度的新体系,两者同一时刻只应使用一套——如果当前生效配置设置了 sandbox_mode 或命令行传了 --sandbox,则旧沙盒配置优先。需要精确到"每个目录可读/可写/禁止、每个域名可通/禁通"时,应迁移到默认权限配置文件(default_permissions),详见后文与 docs/permissions.md

默认值如何被推导:fail-closed 的一个实例

从配置装载逻辑(codex-rs/config/src/config_toml.rs)可以清楚看到默认沙盒的推导规则:如果配置里没有显式 sandbox_mode,但当前项目目录已有信任(trusted/untrusted)决策,那么默认采用 workspace-write唯一例外是在没有启用原生 Windows 沙盒的 Windows 上,会自动降级为 read-only,并且随后还会把解析出的 workspace-write 强制改成 read-only。也就是说:在无法提供等价沙盒保护的平台上,系统宁可把权限降得更低,也不愿意静默地无沙盒运行——这正是文档中"应当 fail closed 而非静默裸奔"原则的具体代码落地(后文"操作系统强制执行"一节继续展开)。

批准策略(Approval Policies)详解

docs/sandbox.md 给出三档批准策略:

策略 行为
untrusted 在可能改变状态的操作之前询问。
on-request 在沙盒内运行,并在升级(escalation)之前询问。
never 不询问。沙盒成为唯一的防护措施。
approval_policy = "on-request"

对应命令行开关为 docs/cli-reference.md 中的 --ask-for-approval, -a <policy>

在底层协议实现中,批准策略是 AskForApproval 枚举,见 codex-rs/protocol/src/protocol.rs,除了文档中的三种取值外还有更细的结构:

  • UnlessTrusted(配置值 untrusted):只有被判定为"已知安全"且仅读取文件的命令(由 is_safe_command() 判定)才会自动放行,其余一律询问;
  • OnRequest:默认值,由模型结合上下文自行决定何时请求批准,并支持别名 on-failure
  • Granular:按命令类别细粒度授权(对应"类别启用/禁用"的精细控制);
  • Never:从不询问,失败立即返回给模型而不会升级到用户。

untrusted/on-request 等策略的模型侧行为说明同样以提示模板形式注入,见 codex-rs/prompts/templates/permissions/approval_policy/,其中 unless_trusted.mdnever.md 分别描述了"大部分命令都要申请升级"与"永远不要传 sandbox_permissions"两种姿态。

on-request 下的"升级请求"协议

on-request 是官方推荐度最高的批准策略,它的精髓在于区分"申请额外沙盒内权限"与"完全越出沙盒执行"两种升级路径,代理的行为协议沉淀在 on_request_rule_request_permission.md 中:

  1. 首选:申请沙盒内的额外权限sandbox_permissions: "with_additional_permissions"),通过 additional_permissions 逐条声明需要的 network.enabledfile_system.readfile_system.write 路径,让命令留在原沙盒策略内执行;
  2. 其次:完全升级sandbox_permissions: "require_escalated"),仅在沙盒内额外权限仍无法满足任务时才使用,且必须附带 justification 参数向用户提问,可选提供可复用的 prefix_rule(例如 ["npm", "run", "dev"] 这类有界前缀)供用户选择"记住放行";
  3. 命令分段评估:复合命令会按 shell 控制符(|&&||;(...)$(...) 等)切分成独立段,每一段单独做沙盒限制与批准评估——例如 git pull | tee output.txt 会分别评估 ["git", "pull"]["tee", "output.txt"]。使用了重定向、命令替换、环境变量、通配符等高级 shell 特性的命令则不参与规则匹配,以限制被放行规则的波及面。

这套协议同样体现在测试套件中,例如 codex-rs/exec/tests/suite/approval_policy.rscodex-rs/core/tests/suite/approvals.rs 会覆盖批准策略在真实执行链路中的行为。

--yolo 与"危险绕过"旗标的边界

docs/sandbox.md 特别警告了两个会同时拆除"批准 + 沙盒"两套护栏的开关:

  • --yolo
  • --dangerously-bypass-approvals-and-sandbox

它们会同时移除批准提示与沙盒化,官方明确要求只在外部沙盒(例如一次性虚拟机、隔离容器)中使用。CLI 定义见 codex-rs/utils/cli/src/shared_options.rs--yolo 是长旗标的别名),其执行效果在 codex-rs/cli/src/main.rs 中体现为:一旦设置该旗标,批准策略强制为 never、沙盒模式强制为 danger-full-access。也就是说"不询问 + 无边界"永远是捆绑生效的,不允许只绕过一半。注意还有一个相对温和的 --approve-for-me(历史别名 --not-so-yolo,默认隐藏),它路由到自动审核而不是完全关闭护栏:会同时把 approvals_reviewer 置为 auto_reviewapproval_policy 置为 on-request、沙盒置为 workspace-write,可参见 codex-rs/utils/cli/src/shared_options.rs 与主程序测试中的别名断言。

workspace-write 的深化配置:可写根目录与网络

workspace-write 允许写入的是工作区根目录(workspace roots),而非整台机器。docs/sandbox.md 给出了两个关键的扩展开关。

为单个会话追加可写根目录

默认工作区根之外的目录是不可写的,需要时可以明确追加:

interpreter --add-dir ../shared-lib

--add-dir <path>docs/cli-reference.md 中登记为"Add a writable workspace root",会在当前会话的可写根目录列表里加入 ../shared-lib。多个目录可以重复传参,CLI 层会做父子命令之间的合并(见 codex-rs/utils/cli/src/shared_options.rsadd_dir 的合并逻辑)。

为旧式 workspace-write 沙盒开启网络

workspace-write 的默认网络姿态是关闭的,需要显式开启:

[sandbox_workspace_write]
network_access = true

docs/config-reference.md 的沙盒表中,[sandbox_workspace_write] 一张表即可看全可调项(默认值以官方配置示例 docs/example-config.md 与 schema 为准):

[sandbox_workspace_write]
network_access = false        # 是否放行网络
exclude_tmpdir_env_var = false # 是否排除 TMPDIR 类临时目录环境变量
exclude_slash_tmp = false      # 是否排除 /tmp 本身
writable_roots = ["/tmp/project-cache"]  # 额外的可写根目录(等价于 --add-dir 的持久化形态)

配置装载逻辑(codex-rs/config/src/config_toml.rs)会把该表的 writable_rootsnetwork_access 等字段翻译成对应的权限策略:network_access = true 时网络策略为 Enabled,否则为 Restricted

需要精确到域名的网络白名单时,docs/sandbox.md 明确指出应使用权限配置体系:在 [permissions.<profile>.network]enabled = true,再用 [permissions.<profile>.network.domains] 逐域名 allow/deny。域名通配规则(example.com 精确主机、*.example.com 仅子域、**.example.com 含根域与子域、* 宽放行)以及 localhost/127.0.0.1 这类本地目标需单独显式放行等细节,请参见 docs/permissions.md。从代码看,这类策略会被翻译为更底层的网络沙盒策略(含代理路由、Unix socket 白名单等),[permissions.project-edit.network.unix_sockets]"/var/run/docker.sock" = "allow" 即是为 Docker 这类需要本地服务的工作流预留的"逃生口",务必按需最小化开启。

受保护路径:即使可写根目录内也有禁区

即便目录位于可写根之内,docs/sandbox.md 仍强调:诸如 .git/代理配置目录这类"敏感控制目录"应被视为受保护。代理如果确实需要改动它们,务必仔细审查请求。

这条规则不只是文档建议,而是有真实的底层强制背书。在 Linux bubblewrap 实现中(见 codex-rs/linux-sandbox/README.md),可写根目录通过 --bind 挂载为可写,但位于可写根之下的受保护子路径——例如 .git、解析后的 gitdir: 目标、以及 .codex 这类代理/配置目录——会被--ro-bind 重新挂载回只读;对于路径中的符号链接或尚不存在的受保护路径组件,则会挂载 /dev/null 加以阻断,防止通过链接或"先建目录再写入"的手法绕过。可见"受保护路径"是写在沙盒构造器里的硬规则,而不是依赖代理自觉的软约定。

另外值得一提的是,工作区根本身靠"项目根标记"识别:默认以 .git 目录为标记向上查找项目根(配置项 project_root_markers 默认 [".git"]),见 codex-rs/config/src/config_toml.rs。把".git 是项目根信号"与".git 是受保护路径"放在一起看,就能理解为什么 .git 会被同时赋予"定位工作区"与"禁止篡改"的双重语义。

操作系统层面的强制执行:同一架构、三套后端

docs/sandbox.md 明确指出:Open Interpreter 与 Codex CLI 共用同一套本地沙盒架构,具体采用哪种强制模型由宿主操作系统决定:

平台 强制模型
macOS Seatbelt 配置文件。
Linux / WSL Bubblewrap、seccomp 及可用的相关内核沙盒。
Windows 配置了原生沙盒时使用原生 Windows 沙盒;WSL 走 Linux 模型。

沙盒后端的选型与能力检测代码集中在 codex-rs/sandboxing/src/(含 bwrap.rslandlock.rsseatbelt.rswindows.rs 等模块)。

macOS:Seatbelt

macOS 上通过 Seatbelt 实现沙盒,其策略文件以 .sbpl 形式随源码分发,例如 seatbelt_base_policy.sbplseatbelt_network_policy.sbpl。调试 CLI 会借助系统 /usr/bin/sandbox-exec 来实际运行受约束命令,并通过"拒绝日志"捕获 Seatbelt 的拒绝事件(实现见 codex-rs/cli/src/debug_sandbox.rs,含 run_command_under_seatbelt)。

Linux / WSL:Bubblewrap + seccomp

Linux 的默认文件系统沙盒是 Bubblewrap。按 codex-rs/linux-sandbox/README.md 的实现说明,沙盒辅助进程会:

  • 优先使用 PATH 上的系统 bwrap,缺失或过旧时回退到随包分发的 codex-resources/bwrap,缺失时还会在启动时给出告警;
  • 通过 --ro-bind / / 让整个文件系统默认只读,再把可写根目录用 --bind 叠加上去(即"默认全只读、按目录放开"的写模型);
  • 显式隔离用户命名空间(--unshare-user)与 PID 命名空间(--unshare-pid);网络受限且无代理路由时还会隔离网络命名空间(--unshare-net);
  • 在进程内施加 PR_SET_NO_NEW_PRIVSseccomp 网络过滤器,受管代理模式下还会在 TCP→UDS→TCP 桥建立后用 seccomp 禁止新建 AF_UNIX/socketpair;
  • 重新挂载只读受保护子路径(.gitgitdir:.codex),并按"路径特异性"顺序应用重叠的读写/拒绝策略。

同一 README 也体现了文档中"无法强制时宁可失败"的取向:例如 WSL1 因无法创建用户命名空间,会在调用 bwrap 之前就拒绝需要走 bubblewrap 路径的沙盒命令;glob 展开失败会中止沙盒构造而不是放行。这些都属于"fail closed"而不是"降级裸奔"。

Windows:原生沙盒 / WSL 复用 Linux 模型

Windows 上(docs/windows.md 的"Sandbox Notes"也提醒)原生 Windows 沙盒的强制细节与 macOS/Linux 不同:只有在配置启用时才使用原生 Windows 沙盒,具体能力由 codex-rs/windows-sandbox-rs/ 承载;若追求与 Linux 一致的沙盒行为,官方建议在 WSL 中运行——WSL2 走正常 bubblewrap 路径,WSL1 不被支持。Windows 上还有"提升级沙盒"的预置流程:codex sandbox setup --elevated(指定 --user/--current-user--codex-home),见 codex-rs/cli/src/sandbox_setup.rs,成功后会持久化 windows_sandbox_mode = "elevated"。前文提到"无原生 Windows 沙盒时把 workspace-write 自动降为 read-only"(codex-rs/config/src/config_toml.rs),正是这套 Windows 分支在默认值层面的 fail-closed 呼应。

验证沙盒是否就绪

执行前可以先运行 interpreter doctor(或在 TUI 内查看相关状态)确认后端是否可用。CLI 的诊断逻辑位于 codex-rs/cli/src/doctor.rs,它会检查文件系统沙盒策略种类、网络沙盒策略、以及 Linux 辅助程序 codex-linux-sandbox 的路径是否存在——辅助程序缺失会直接给出警示,这正是"发现沙盒不可用就提醒你,而不是静默裸奔"的运维侧配套。

推荐默认值:给四种典型场景的配置处方

docs/sandbox.md 最后给出了一组可直接照抄的推荐矩阵:

场景 建议配置
审查不熟悉的代码 sandbox_mode = "read-only", approval_policy = "on-request"
日常受信任仓库开发 workspace-write + on-request
隔离运行器中的 CI workspace-write + never
一次性全访问环境 danger-full-access + never

如果不确定,从 workspace-write + on-request 开始。 这套矩阵的规律性很强,可以归纳为三条可迁移的判断准则:

  1. 信任决定沙盒:对代码越不熟悉(陌生/未审阅代码),沙盒边界就越紧——read-only 保证代理"能看不能改",配合 on-request 让任何需要落盘的动作都经过你;
  2. 人的在场程度决定批准策略:交互式开发(你在场)用 on-request,CI(无人值守)用 never——注意 CI 场景下 never 之所以安全,前提是沙盒仍在(workspace-write),沙盒替代了人的把关;
  3. "双无"只在隔离环境出现danger-full-access + never 意味着既无边界也不询问,它只能配给一次性、可丢弃、本身就在外部沙盒中的执行环境,这是唯一允许同时拆掉两道护栏的场景。

在共享/多环境场景中,可把不同姿态固化到命名 profile 里按需切换——例如给 review profile 单独配 sandbox_mode = "read-only"(见 docs/config.md 的 Profiles 示例与 docs/config-reference.md 中 agent 级 sandbox_mode = "read-only" 的写法),需要时用 interpreter --profile review 一键进入审查姿态。

从配置到源码的完整链路回顾

为了让以上配置"可追踪、可验证",最后串一下整条实现链路,方便你在仓库中继续深挖:

当你需要比"三档模式 + 三类策略"更细的控制时,请切到权限配置体系(default_permissions,见 docs/permissions.md):文件系统规则 read/write/deny、根别名 :minimal/:workspace_roots/:tmpdir/:root**/*.env 这类密钥文件 deny glob、域名 allow/deny 白名单、Unix socket 放行——它们本质上是把本文所述的沙盒边界抽象成了可复用的"最小权限档案",帮助你在复杂项目里真正做到"默认拒绝、按需放开"。

登录后查看全文
热门项目推荐
相关项目推荐