具体问题与边界
规则决策、人工授权与操作系统隔离为什么必须是三层独立机制?
ExecPolicy 对 argv 产生 allow/prompt/forbid;ApprovalPolicy 处理 prompt;ExecutionEnvironment/Sandbox Adapter 执行命令。WorkspacePolicy 只做应用层路径检查。 本节区分“从官方源码得到的生产事实”和“为教学实现作出的 Python 选择”,不会把后一种包装成 Codex 的等价实现。
状态所有权
| 对象 | 所有者 | 生命周期 | 持久化 |
|---|---|---|---|
| ExecRule list | ExecPolicy | 配置生命周期 | Mini 不持久化 |
| ExecDecision | ExecPolicy.decide | 一个 argv | 否 |
| Approval response | Host/ApprovalPolicy | 一个动作或会话 | Mini 仅返回 bool |
| Sandbox Adapter | Session | Session 生命周期 | 否 |
| OS enforcement | 具体 sandbox backend | 进程生命周期 | 外部安全边界 |
正常路径
- ExecPolicy 用 argv token prefix 匹配,匹配多个规则时 Mini 取最长 prefix;未匹配走 default。它不解析 shell script 内部语义。
- forbid 不询问用户,直接拒绝;prompt 才进入 Approval;allow 只表示应用策略许可。
- Approval 是用户/Host 决策,不会给进程增加文件系统或网络隔离能力。
- Session 注入 ExecutionEnvironment Protocol。LocalSandboxAdapter 只是委托本地环境,类文档明确声明无 OS isolation;DenyAll adapter 用于证明边界可替换。
- WorkspacePolicy.resolve 防止 Patch path 和 cwd 逃出根目录,但命令仍可自行打开绝对路径或联网。
顺序为什么不能交换
ExecPolicy 用 argv token prefix 匹配,匹配多个规则时 Mini 取最长 prefix;未匹配走 default
→ forbid 不询问用户,直接拒绝;prompt 才进入 Approval;allow 只表示应用策略许可
→ Approval 是用户/Host 决策,不会给进程增加文件系统或网络隔离能力
→ Session 注入 ExecutionEnvironment Protocol
→ WorkspacePolicy.resolve 防止 Patch path 和 cwd 逃出根目录,但命令仍可自行打开绝对路径或联网
箭头代表可见性与所有权转移,不是松散依赖。Policy、Approval、外部副作用、规范 Item 和 durability 各自有提交点,后一步不能替前一步作更强承诺。
Python 风格伪代码
decision = exec_policy.decide(argv)
match decision:
case FORBID:
return error_result("forbidden by exec policy")
case PROMPT:
if not await approval.approve(ActionRequest(argv, cwd)):
return error_result("rejected by approval")
case ALLOW:
pass
# Approval is finished; enforcement is still a separate boundary.
result = await sandbox_adapter.run(
argv,
cwd=workspace_policy.resolve(cwd),
timeout_seconds=timeout,
cancellation=token,
)
return encode_tool_result(result)
class LocalSandboxAdapter:
async def run(...):
return await local_environment.run(...) # deliberately no isolation
失败、取消与恢复
| 故障点 | 已留下的状态 | 处理 |
|---|---|---|
| 规则 forbid | 不进入 Approval/执行 | 模型可见 policy denial |
| Approval deny/timeout | 不执行命令 | 模型可见 rejection |
| Local adapter 被误叫 sandbox | 形成虚假安全结论 | 文档/类型明确 no isolation |
| 真实 sandbox deny | 进程未创建或被限制 | 编码具体 sandbox error |
| path check 通过但命令越权 | 应用层无法阻止 | 必须由 OS sandbox/remote executor 负责 |
不变量
Policy allow 与用户 approve 都不能被表述为 OS 隔离;只有实际执行 backend 能强制文件系统、网络和进程边界。
设计思路与限制
三层分离增加配置与错误类型,却能精确回答“谁允许了动作”和“谁真正阻止越权”。Mini 没有 Linux Seatbelt/bubblewrap、macOS Seatbelt、Windows restricted token/WFP。
测试与复现
cd examples/mini-codex
uv run pytest -q -k 'test_exec_policy_uses_longest_argv_prefix or test_approval_rejection_becomes_model_visible_result or test_workspace_policy_rejects_parent_traversal'
uv run mypy src
test_exec_policy_uses_longest_argv_prefixtest_approval_rejection_becomes_model_visible_resulttest_workspace_policy_rejects_parent_traversal
官方源码导航
- codex-rs/execpolicy/src/decision.rs:Allow/Prompt/Forbidden 决策
- codex-rs/execpolicy/src/policy.rs:规则匹配与合并
- codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs:Policy、Approval 与 escalation 顺序
- codex-rs/sandboxing/src/lib.rs:平台 Sandbox 类型与命令变换
- codex-rs/protocol/src/protocol.rs:SandboxPolicy 与 ReviewDecision
Mini Codex 对照
src/mini_codex/policy/exec_policy.py:最长 argv prefix 决策src/mini_codex/policy/approval.py:可替换人工授权 Protocolsrc/mini_codex/execution/sandbox.py:Local/DenyAll Adaptersrc/mini_codex/policy/workspace.py:应用层路径边界
本节结论
Policy allow 与用户 approve 都不能被表述为 OS 隔离;只有实际执行 backend 能强制文件系统、网络和进程边界。
评论
登录后即可评论