Open Interpreter 执行策略(execpolicy)实战:基于规则把命令分类为安全、风险与阻止
【免费下载链接】openinterpreterA coding agent for open models like Kimi K3 and GLM 5.3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter
本篇技术指南围绕 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*中的*都属于这类通配符匹配。
三档标签与审批模式的交互方式
执行策略是代理的"第一道过滤"。策略对命令打标之后:
forbid:直接阻止命令,完全不进入后续环节;safe:在不提示(without prompting)的情况下直接运行;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与上述三档决策在语义上一一对应:safe≈allow(免审批放行)、unsafe≈prompt(交由审批)、forbid≈forbidden(无条件拦截)。此外,当一条命令同时命中多条规则时,引擎会取最严格的严重级别作为最终决策(forbidden>prompt>allow),也就是说只要有任何一条规则把它判为forbidden,命令就不会执行。
常见模式:直接可复用的规则片段
让你信任的 lint 与 test 命令完全不触发提示
把代理会反复执行、且你完全信任的命令标记为safe,可以让日常工作流中的干扰降到最低:
[[execpolicy.rules]] match = "pnpm test*" action = "safe" [[execpolicy.rules]] match = "pnpm lint*" action = "safe"pnpm test*这类前缀模式能同时覆盖pnpm test、pnpm test --run、pnpm 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"], # 必须不命中的示例(加载期校验) )两个值得注意的工程细节:
match/not_match是规则的"单元测试"。在策略文件加载时,这些示例调用就会被校验(字符串会被shlex分词成 token 数组),确保模式表达与预期一致。仓库中的完整示例见 codex-rs/execpolicy/examples/example.codexpolicy,其中ls、cat这类无显式decision的规则默认即allow,而git reset --hard被声明为forbidden并附有justification("destructive operation"),cp则被标为prompt。绝对路径与 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 展示了这套默认策略的典型形态:它针对ls、cat、cp、head、printenv、pwd、rg、sed、which等高频命令分别用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验证目标命令的判定结果再投入到自动化流程。 - 共享系统上宁严勿松:默认策略适用于单人开发机;在共享系统上建议收紧规则面,并对所有可能改写状态的命令显式声明
unsafe或forbid。 - 预览期注意事项:新一代
execpolicy命令目前仍处于 preview 阶段(见 codex-rs/execpolicy/README.md 的说明),其 API 在未来可能发生破坏性变更,将策略文件纳入版本管理、并在升级后回归测试是一个稳妥的做法。
【免费下载链接】openinterpreterA coding agent for open models like Kimi K3 and GLM 5.3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考