命令规则:拆段、前缀匹配与授权合并
一条 shell 请求可能包含多条程序调用,批准范围必须与实际解析结果对应。
学完你能做到
- 能区分字符串与词序列前缀
- 能计算多段规则的合并结果
- 能解释 Allow 与绕过的额外条件
本课目录 · 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 + Allow | Allow | 仍需检查实际执行边界。 |
| Allow + | 当前策略可能接受授权请求,也可能拒绝。 | |
| Allow + Forbidden | Forbidden | 允许段不覆盖禁止段。 |
枚举的顺序 ↗codex-rs/execpolicy/src/decision.rs:7–16
收集匹配 ↗codex-rs/execpolicy/src/policy.rs:265–287
/// 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
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
沿着源码读
以下定位均锁定本课程版本。先读注释与分支,再深入类型定义。
实现推演
三段命令分别命中显式 Allow、启发式 Allow、显式 。计算整体决定,再把最后一段改为显式 Allow,判断 Skip 是否一定带 bypass_sandbox=true。
阅读练习无需模型账号。示例命令请先确认目录与环境。
自测与边界检查
最后一段 Allow 能覆盖前一段 Forbidden 吗?
展开自测答案
不能,集合结果取最严格决定。
为什么整体 Allow 仍可能在中执行?
展开自测答案
bypass_sandbox 要求所有命令段都有显式 policy Allow;启发式允许并不满足同一个条件。