Codex Harness 源码课 / 中文
LESSON 09 / 12 30 分钟

命令规则:拆段、前缀匹配与授权合并

一条 shell 请求可能包含多条程序调用,批准范围必须与实际解析结果对应。

公开源码快照 · 2026-10-13 · f82e365922

学完你能做到

本课目录 · 4 节

1. 解析包装后的命令集合

commands_for_exec_policy_for_platform 先尝试解析受支持的 包装,成功且非空才使用多条普通命令;Windows 还有 PowerShell 解析分支。否则保留原 argv 作为一条命令。 匹配的是程序及参数词序列,而不是“整条文本以 git 开头”。

拆段及回退 ↗codex-rs/core/src/exec_policy.rs:872–908

解析每个命令段,合并规则和启发式判断,再转换成执行授权要求;绕过沙箱另有条件。
解析每个命令段,合并规则和启发式判断,再转换成执行授权要求;绕过沙箱另有条件。 · 教学示意,省略次要分支;不是完整调用图。

2. 收集全部匹配,采用最严格决定

check_multiple_with_options 收集各段 RuleMatch。Decision 依次为 Allow、、Forbidden,Evaluation 对匹配决定取 max。未匹配段可以进入调用方的启发式 fallback,不能当作显式规则 Allow。

状态 / 条件结果边界
Allow + AllowAllow仍需检查实际执行边界。
Allow + 当前策略可能接受授权请求,也可能拒绝。
Allow + ForbiddenForbidden允许段不覆盖禁止段。

枚举的顺序 ↗codex-rs/execpolicy/src/decision.rs:7–16

收集匹配 ↗codex-rs/execpolicy/src/policy.rs:265–287

真实源码 · Apache-2.0 · 未改写
    /// Caller is responsible for ensuring that `matched_rules` is non-empty.
    fn from_matches(matched_rules: Vec<RuleMatch>) -> Self {
        let decision = matched_rules.iter().map(RuleMatch::decision).max();
        #[expect(clippy::expect_used)]
        let decision = decision.expect("invariant failed: matched_rules must be non-empty");

        Self {
            decision,
            matched_rules,
        }
    }

使用最严格决定,不是最后一段覆盖前一段。

查看原文及相邻代码 ↗

3. 映射到执行要求,保留来源差异

Forbidden 转成 ::Forbidden; 经当前策略检查后,可能转成 NeedsApproval,也可能被直接拒绝。Allow 转成 Skip,但 Skip.bypass_sandbox 只有每条解析段都明确匹配 policy Allow 才为真。启发式 Allow 与显式 Allow 在这个条件里不同。

决定与执行要求 ↗codex-rs/core/src/exec_policy.rs:394–460

真实源码 · Apache-2.0 · 未改写
            Decision::Allow => ExecApprovalRequirement::Skip {
                // Bypass sandbox only when every parsed command segment is
                // explicitly allowed by execpolicy.
                bypass_sandbox: commands.iter().all(|command| {
                    exec_policy
                        .matches_for_command_with_options(
                            command,
                            /*heuristics_fallback*/ None,
                            &match_options,
                        )
                        .iter()
                        .any(|rule_match| {
                            is_policy_match(rule_match) && rule_match.decision() == Decision::Allow
                        })
                }),
                proposed_execpolicy_amendment: if auto_amendment_allowed {

整体允许仍不足以证明可以脱离。执行协调器还会读取有效权限和审核模式。

查看原文及相邻代码 ↗

4. 可复用建议要先检查覆盖范围

调用方提出的 prefix_rule 必须非空,不能是被禁止的过宽包装建议;已有 policy 匹配时,不再添加可能冲突的建议。实现把建议加到策略副本,重新判断它是否让所有命令段都变成 Allow。

前缀建议模拟 ↗codex-rs/core/src/exec_policy.rs:958–1021

例如 prog1 与 prog2 两段都需要授权,仅允许 prog1 的建议不能说明整条请求已获覆盖。是否 honor prefix rules 的模式也影响能否产生可复用建议。排查时保存每段匹配来源,以及最终 /profile,两份结果不能合并成一个模糊的“已允许”。

可复用规则的模式边界 ↗codex-rs/core/src/exec_policy.rs:356–392

沿着源码读

以下定位均锁定本课程版本。先读注释与分支,再深入类型定义。

READ & VERIFY / 小练习

实现推演

三段命令分别命中显式 Allow、启发式 Allow、显式 。计算整体决定,再把最后一段改为显式 Allow,判断 Skip 是否一定带 bypass_sandbox=true。

阅读练习无需模型账号。示例命令请先确认目录与环境。

自测与边界检查

最后一段 Allow 能覆盖前一段 Forbidden 吗?

展开自测答案

不能,集合结果取最严格决定。

为什么整体 Allow 仍可能在中执行?

展开自测答案

bypass_sandbox 要求所有命令段都有显式 policy Allow;启发式允许并不满足同一个条件。

学习记录保存在本机

搜索课程

输入关键词,搜索全部课程、词典与来源。

就地词典

在完整词典中查看 →

完整架构总图

放大后横向、纵向滚动阅读;聚焦图示区域后可用方向键滚动。

完整架构职责图,内容与正文总图相同