第 25 讲:ExecPolicy 命令策略引擎

Codex 源码解析 · 第 25 讲

Codex 源码解析系列 第 25 讲:ExecPolicy 命令策略引擎 基于 OpenAI Codex 源码 · 2026-10-18 💡 本讲一句话: Codex 不是"每条命令都问用户",而是先查一套可叠加、可追加的规则引擎(execpolicy crate):命中 allow 直接放行、命中 prompt 才弹审批、命中 forbidden 直接拒绝;一条都没命中时再交给启发式兜底。读完你能看懂 ~/.codex/rules/*.rules 里每一行 Starlark 的语义,以及"允许一次"为什么能变成永久规则。 一、ExecPolicy 在审批流里的位置 前面几讲拆了沙箱(bwrap / Landlock / Seatbelt / Windows)和工具审批流,但一直有个问题没回答: 同样是"跑一条 shell 命令",为什么 ls 从不弹窗、而 rm -rf / 必被拦截? 答案就是本讲的 execpolicy crate——一个约 2000 行的独立 Rust crate,职责单一:把"命令前缀 → 决策"的规则解析、匹配、合并成一套可查询的策略。 它在 core 里的调用链是: shell 工具发起执行请求 → ExecPolicyManager.create_exec_approval_requirement_for_command (core/src/exec_policy.rs)→ execpolicy crate 的 Policy::check_multiple_with_options → 得到 Allow / Prompt / Forbidden 三选一 → core 再翻译成"跳过审批 / 弹审批框 / 直接拒绝" 。规则文件本身是 Starlark(Bazel 同款 DSL)写的纯文本,放在各配置层的 rules/ 目录下。 crate 的模块划分非常克制(execpolicy/src/lib.rs,共 33 行): 📄 codex-rs/execpolicy/src/lib.rs (第 1-33 行) pub(crate) mod amend; // 运行时追加规则(用户点"允许"后落盘)——crate 内部可见 pub(crate) mod decision; // Allow / Prompt / Forbidden 三档决策枚举 pub(crate) mod error; // 统一错误类型 + 源码位置信息(行/列) pub(crate) mod execpolicycheck; // CLI 子命令:离线校验一条命令命中哪些规则 mod executable_name; // Windows 下剥 .exe/.cmd 等后缀的查找键归一化 pub(crate) mod parser; // Starlark DSL → Policy 的解析器(本讲重点) pub(crate) mod policy; // Policy 本体:按程序名索引的规则表 + 匹配算法 pub mod rule; // PrefixRule / NetworkRule / PatternToken 等规则数据结构 mod sandbox_migration; // 一次性迁移:清理旧版本遗留的禁用 allow 规则 pub use decision::Decision; // 对外暴露三档决策,core 层直接消费 pub use parser::PolicyParser; // 对外暴露解析器入口 pub use policy::Evaluation; // 匹配结果(decision + matched_rules) pub use policy::MatchOptions; // 匹配选项开关(如是否解析宿主可执行文件路径) pub use policy::Policy; // 策略本体,core 层持有 Arc<Policy> pub use rule::NetworkRuleProtocol; // http/https/socks5 协议枚举 pub use rule::PrefixPattern; // "命令前缀"匹配器(首 token + 后续 token) pub use rule::Pref…

阅读全文:Codex 源码解析 第 25 讲