首页
/ Open Interpreter 执行策略(execpolicy)实战:基于规则把命令分类为安全、风险与阻止

Open Interpreter 执行策略(execpolicy)实战:基于规则把命令分类为安全、风险与阻止

2026-09-06 19:20:10作者:秋泉律Samson

本篇技术指南围绕 Open Interpreter 的 Execution policy(执行策略)展开:它是叠加在沙箱之下的规则层,会在每一条命令真正执行前完成一次"体检"并把命令标记为 safe / unsafe / forbid。读完本文,你将掌握如何在 config.toml 中编写规则、理解它与审批(approval)流程的衔接方式,并能借助仓库自带的引擎与 execpolicy check 命令验证每一条规则是否真正按预期工作。

执行策略:沙箱之下的第一道规则层

Execution policy 位于沙箱(sandbox)之下,是代理执行命令前的第一道过滤。它不像沙箱那样从操作系统层面约束进程能力,而是直接"看"这条命令本身:在命令运行之前检查其内容并打上标签。打标结果决定这条命令后续走哪条路径——直接放行、交由审批,还是一律拒绝。

Open Interpreter 为每条命令分配三类标签:

标签 含义
safe 常规、低风险。无需提示直接通过。
unsafe 可能改变系统状态。需要审批。
forbid 始终阻止。

Open Interpreter 随附一套合理的默认策略,大多数用户从不编辑它。只有当你想获得更严格的控制,或运行在共享系统(shared system)上时,才需要阅读本文并自定义规则。

策略存放位置:config.toml 与规则评估顺序

策略从 config.toml 加载。每一条规则由两部分构成:一个匹配命令的模式(pattern),以及一个动作(action)。规则以 TOML 数组的形式写在 [[execpolicy.rules]] 小节下:

[[execpolicy.rules]]
match = "ls"
action = "safe"

[[execpolicy.rules]]
match = "rm *"
action = "unsafe"

[[execpolicy.rules]]
match = "rm -rf /"
action = "forbid"

评估时有一个极其关键、也是最容易踩坑的语义:规则从上到下逐条评估,第一条命中的规则生效(The first match wins)

这意味着:

  • match = "rm -rf /" 写在其父模式 rm * 之后是安全的——因为 rm -rf / 本身就是 rm * 的子集匹配,从上到下先命中通用规则则后面的 forbid 永不生效;
  • 想让"特例"覆盖"通例",必须把更具体的规则放在更靠前的位置;
  • 模式使用类 shell 的通配符(shell-style globs),例如 rm * 中的 *pnpm test* 中的 * 都属于这类通配符匹配。

三档标签与审批模式的交互方式

执行策略是代理的"第一道过滤"。策略对命令打标之后:

  1. forbid:直接阻止命令,完全不进入后续环节;
  2. safe:在不提示(without prompting)的情况下直接运行;
  3. unsafe:交由你的审批模式(approval mode)处理,参见沙箱与审批

由此可以推出两条非常实用的性质:

  • 一条 safe 规则可以显著减少你一天中弹出的审批次数——你信任的命令(例如测试、lint)不再打扰你;
  • 一条 forbid 规则则提供"兜底"保证:即使你在审批提示中意外按下 y,该命令也永远不会执行forbid 的拦截发生在审批之前,审批根本不会有机会放行它。

从仓库中新一代执行策略引擎的源码可以印证这套语义:核心决策类型 Decision 定义在 codex-rs/execpolicy/src/decision.rs,包含三档:

  • Allow:无需进一步审批即可运行;
  • Prompt:请求用户明确批准;当以 approval_policy = "never"(永不批准)模式运行时会被直接拒绝;
  • Forbidden:不做任何考虑直接阻止。

可以推断,本文面向的 config.toml 三档标签 safe / unsafe / forbid 与上述三档决策在语义上一一对应:safeallow(免审批放行)、unsafeprompt(交由审批)、forbidforbidden(无条件拦截)。此外,当一条命令同时命中多条规则时,引擎会取最严格的严重级别作为最终决策(forbidden > prompt > allow),也就是说只要有任何一条规则把它判为 forbidden,命令就不会执行。

常见模式:直接可复用的规则片段

让你信任的 lint 与 test 命令完全不触发提示

把代理会反复执行、且你完全信任的命令标记为 safe,可以让日常工作流中的干扰降到最低:

[[execpolicy.rules]]
match = "pnpm test*"
action = "safe"

[[execpolicy.rules]]
match = "pnpm lint*"
action = "safe"

pnpm test* 这类前缀模式能同时覆盖 pnpm testpnpm test --runpnpm test:watch 等各种变体。

对所有破坏性操作强制确认

对可能改变远端状态或造成不可逆后果的命令,用 unsafe 强制人工确认,用 forbid 直接封死:

[[execpolicy.rules]]
match = "git push --force*"
action = "unsafe"

[[execpolicy.rules]]
match = "drop database*"
action = "forbid"

drop database 这类操作即便是开发库也几乎不该由代理自动执行,因此用 forbid 而不是 unsafe 是更稳妥的默认选择——毕竟 unsafe 只代表"需要审批",而审批仍可能被人为放行。

验证规则:execpolicy check 命令

模式采用类 shell 通配符,手写时容易出偏差。在把这些规则用于自动化之前,务必先用内置命令实测。文档给出的用法是:

interpreter execpolicy check '<command>'

例如:

interpreter execpolicy check 'pnpm test --run unit'
interpreter execpolicy check 'rm -rf /'

结合仓库实现可以进一步理解这条命令的机制。对应的子命令参数定义在 codex-rs/execpolicy/src/execpolicycheck.rs:它支持一个或多个 --rules <PATH> 策略文件、--pretty(美化 JSON 输出)以及 --resolve-host-executables(解析宿主可执行文件的绝对路径),命令本身以 trailing_var_arg 方式接收完整命令行 token。从 CLI 运行同样效果的检查:

codex execpolicy check --rules path/to/policy.rules git status

传入多个 --rules 时,多个策略文件会按传入顺序合并评估;加上 --pretty 可以获得格式化 JSON:

codex execpolicy check \
  --rules path/to/policy.rules \
  --pretty \
  git push --force origin main

检查结果以 JSON 形式输出,包含命中的规则与最终决策:

{
  "matchedRules": [
    {
      "prefixRuleMatch": {
        "matchedPrefix": ["git", "push", "--force"],
        "decision": "prompt",
        "justification": "force push rewrites remote history"
      }
    }
  ],
  "decision": "prompt"
}

关键字段的含义(与策略文件评估一一对应):

  • matchedRules:列出所有前缀命中了该命令的规则;一条命令可能命中多条规则,最终决策取最严格者;
  • matchedPrefix:实际命中的命令前缀 token;
  • resolvedProgram:仅当通过 basename 回退命中绝对可执行路径时才出现;
  • decision:整体有效决策(allow / prompt / forbidden)。当没有任何规则命中时,matchedRules 为空数组,decision 字段被省略。

开发期间也可以直接用独立 dev 二进制运行:

cargo run -p codex-execpolicy -- check --rules path/to/policy.rules git status

源码透视:新一代 execpolicy 引擎与规则格式

仓库中的 codex-rs/execpolicy 是这个执行策略能力的新一代 Rust 实现(其使用说明见 codex-rs/execpolicy/README.md),旧式规则匹配器则位于 codex-execpolicy-legacy。新一代引擎以 prefix_rule 前缀规则 + host_executable 宿主可执行文件元数据为最小抽象:

prefix_rule(
    pattern = ["cmd", ["alt1", "alt2"]], # 按序匹配的 token;列表表示可选项
    decision = "allow",                  # allow | prompt | forbidden,默认 allow
    justification = "explain why this rule exists",
    match = [["cmd", "alt1"], "cmd alt2"],      # 必须能命中的示例(加载期校验)
    not_match = [["cmd", "oops"], "cmd alt3"],  # 必须不命中的示例(加载期校验)
)

两个值得注意的工程细节:

  1. match / not_match 是规则的"单元测试"。在策略文件加载时,这些示例调用就会被校验(字符串会被 shlex 分词成 token 数组),确保模式表达与预期一致。仓库中的完整示例见 codex-rs/execpolicy/examples/example.codexpolicy,其中 lscat 这类无显式 decision 的规则默认即 allow,而 git reset --hard 被声明为 forbidden 并附有 justification("destructive operation"),cp 则被标为 prompt

  2. 绝对路径与 basename 的匹配策略。引擎总是优先尝试精确的"首 token"匹配;在未开启宿主可执行文件解析时,/usr/bin/git status 只会命中首 token 为 /usr/bin/git 的规则;开启后则可能回退到针对 git 的 basename 规则。若存在 host_executable(name = "git", paths = [...]) 声明,则 basename 回退只允许命中列表中列出的绝对路径;若某 basename 没有任何 host_executable() 条目,则 basename 回退不受限制。这种设计把"机器上到底哪个 git 被调用"也纳入了策略考量,适合共享/多用户环境。

另外,引擎还内置了针对 approval_policy="never" 等运行模式的行为(prompt 在该模式下直接被拒绝),这也解释了为什么 unsafe/prompt 在"永不批准"场景下等效于被拦截,而 forbid/forbidden 在任何场景下都无法绕开。

随附的默认策略长什么样

前面提到"Open Interpreter 随附一个合理的默认策略",仓库中旧式引擎的默认策略文件 codex-rs/execpolicy-legacy/src/default.policy 展示了这套默认策略的典型形态:它针对 lscatcpheadprintenvpwdrgsedwhich 等高频命令分别用 define_program(...) 描述其合法 flag、参数类型与可接受的调用形态(should_match / should_not_match),例如:

  • ls 只放行 -1 / -a / -l 与"文件或当前目录"类参数;
  • cat 允许读取文件、-n / -b 等常规 flag,但不放行无参数读 stdin 的形态;
  • sed 由于 GNU 实现存在 s/.../.../e 会执行 shell 命令的潜在风险,仅支持被白名单化的"已知安全"命令子集(如 -n-u,刻意不支持 -i-f)。

从这套策略可以看出默认策略的取向:让"读操作类"命令尽量静默放行,让可能改变状态或产生副作用的用法退回到人工审批,从根上排除高危形态。理解这一点,有助于你在自定义规则时把握 safe / unsafe / forbid 的分寸。

编写策略时的注意事项

  • 顺序即优先级:规则从上到下评估、第一条命中生效。书写时把最具体、最想"特判"的规则(尤其 forbid)放在最前面,防止被前置的宽泛 safe 规则吞掉。
  • forbid 提供替代建议:仓库的新格式规范建议,当 decision = "forbidden" 时,在 justification 中附上推荐的替代命令(例如 "Use jj instead of git.")。这让代理在被拒绝时知道下一步该怎么走,而不是僵在原地。
  • 用自动化测试心态写模式:把规则的 match / not_match 示例当成测试用例维护——每次改动策略后,都用 execpolicy check 验证目标命令的判定结果再投入到自动化流程。
  • 共享系统上宁严勿松:默认策略适用于单人开发机;在共享系统上建议收紧规则面,并对所有可能改写状态的命令显式声明 unsafeforbid
  • 预览期注意事项:新一代 execpolicy 命令目前仍处于 preview 阶段(见 codex-rs/execpolicy/README.md 的说明),其 API 在未来可能发生破坏性变更,将策略文件纳入版本管理、并在升级后回归测试是一个稳妥的做法。
登录后查看全文
热门项目推荐
相关项目推荐