Codex 源码解析 · 第 26 讲
Codex 源码解析系列 第 26 讲:Guardian 安全审查 v1+v2 基于 OpenAI Codex 源码 · 2026-10-19 💡 本讲一句话: Guardian 是 Codex 里"执行前审查动作"的第二大脑——v1 每次审批都跑一轮完整 LLM 评审(90 秒截止、最多重试 3 次、失败即拒绝),v2 再加一条异步打分快车道:低风险动作直接放行,不唤醒评审模型。本讲把决策路由、会话池复用、提示词预算、输出契约和熔断器逐行拆开。 一、Guardian 是什么:执行前的"第二大脑" 前几讲我们拆过沙箱(bwrap/Landlock/Seatbelt)和 ExecPolicy——它们管的是"能不能跑"。但还有一类风险是静态规则覆盖不了的:一条命令语法完全合法、权限也在范围内, 意图 却可能是数据外泄或破坏性操作。这类判断需要理解上下文,只能交给模型来做。 Guardian 就是干这件事的:当 agent 提出一个需要审批的动作(执行命令、写 stdin、打补丁、访问网络、调 MCP 工具)时,Codex 会 另起一个隔离的评审会话 ,把"父会话的对话记录 + 这个动作的完整 JSON + 安全策略"喂给模型,让它输出结构化的 allow/deny 裁决。源码分布在三个 crate: 🔹 core/src/guardian/ (约 9700 行):宿主侧——审批请求模型、决策路由、评审会话池的宿主适配、提示词组装 🔹 ext/guardian-reviewer/ (约 3500 行):与宿主解耦的审查策略——重试预算、截止时间、熔断器、输出契约解析 🔹 ext/guardian-v2/ (约 4600 行):异步打分器(LunaSampler),给快车道供能 先看所有审批请求的统一模型—— GuardianApprovalRequest (core/src/guardian/approval_request.rs,第 18-85 行): 📄 codex-rs/core/src/guardian/approval_request.rs (第 18-85 行) pub(crate) enum GuardianApprovalRequest { // 统一审批请求模型:所有需要审查的动作都归一化成这七种 ExecCommand { // shell 命令执行(unified exec / shell 工具) id: String, // 审批 ID,用于去重、追踪和事件关联 environment_id: String, // 命令跑在哪个执行环境(本地/远程/cloud),评审要判断"哪台机器" command: Vec<String>, // shlex 切分后的 argv——评审看到的是精确参数,不是拼接字符串 cwd: PathUri, // 工作目录:决定这条命令属于哪个仓库、哪个项目 sandbox_permissions: crate::sandboxing::SandboxPermissions, // 请求的沙箱权限级别(只读/读写/提权) additional_permissions: Option<AdditionalPermissionProfile>, // 基线之外的额外权限(如网络出口),是风险放大器 justification: Option<String>, // agent 自述"为什么需要这条命令"——评审判断意图的关键证据 tty: bool, // 是否需要 TTY:影响能否后台运行,也暗示交互式操作 }, WriteStdin { /* ... */ }, // 向交互进程写 stdin(如回答密码提示)——审查的是"输入内容+目标进程" #[cfg(unix)] Execve { /* ... */ }, // execve 系统调用拦截:抓住绕过 shell 解析直接起进程的命令 ApplyPatch { /* ... */ }, // 文件补丁应用:files + 完整 patch 文本就是审查对象 NetworkAccess { /* ... */ }, // 网络出口请求:host/port/protocol,外加 trigger(是哪条命令触发的) McpToolCall …
阅读全文:Codex 源码解析 第 26 讲