如何让 API 密钥远离 Codex CLI

Codex CLI 的模型能看到什么,zn-gate 的钩子在 Codex 中于每一步之前、之后以及你的提示词上检查什么,它们做不到什么,如何设置,以及一个使用假数据的简短测试。

查看 .md

Codex CLI 会把进入对话的所有内容发送给它的模型:你输入的提示词、智能体读取的文件、shell 命令的输出,以及 MCP 工具的结果。这些位置中的任何一个出现 API 密钥,都可能到达模型。zn-gate 在 Codex 中安装钩子来检查这些位置。本页根据 zn-gate 的文档说明每个钩子做什么、做不到什么,并给出一个你可以自己运行的测试。

密钥可能通过哪些途径到达模型

zn-gate 针对 Codex 的钩子关注会话中的四个位置:

  • 你输入的提示词。 粘贴进去的密钥可以在发送前被阻止。
  • shell 命令或补丁(apply_patch)。 读取含有值的 .env 文件和凭据文件的操作可以被阻止。
  • 工具的输出。 可以在模型看到之前先清理。

无论 zn-gate 对模型所见内容做了什么,Codex 自己的会话日志仍会保留原始输出。

zn-gate 在 Codex 中检查什么

zn hooks install codex 会写入 Codex 的 hooks.json。下表依据 zn-gate 仓库中的 compat.md,该文件列出了每个 Codex 钩子事件,以及它是否已在真实的 Codex 上运行过。

钩子事件 zn-gate 的做法
PreToolUse 在 shell 命令和补丁(Bash、apply_patch)运行之前检查它们;发现密钥、凭据文件或 ~/.zn 时,会拒绝该调用并给出原因。它不检查 MCP 工具调用。已在 Codex CLI 0.163.0 上检查过。
PostToolUse 清理工具输出:结果会被替换为清理后的文本。已在 Codex CLI 0.163.0 上检查过。

第三个事件 UserPromptSubmit 会阻止粘贴到提示词中的密钥(已在 Codex CLI 0.163.0 上检查过)。

在 PreToolUse 中,zn-gate 不会回答 allow,因此你自己的 Codex 批准策略仍然有效。

zn-gate 在 Codex 中不覆盖什么

  • Codex 把它的钩子描述为 "a guardrail, not an enforcement boundary"(护栏,而非强制边界)。如果 zn 的钩子无法运行,Codex 会将其报告为失败,调用或提示词照常继续。
  • 清理是有损的。Codex 没有可以改写工具结果的字段,所以结果会被替换为 zn-gate 清理后的文本,模型得到的是文本而不是结构化的结果。
  • Codex 自己的会话日志会保留原始输出。
  • 没有已知格式、又不在保险库或 .env 文件中的密钥,可能通过清理。
  • 通过 Codex 命令行 -c mcp_servers.secrets... 或在配置档案中设置的服务器,钩子看不到。
  • zn-gate 的 PreToolUse 检查覆盖 shell 命令和补丁,不覆盖 MCP 工具调用,zn-gate 也不使用 Codex 的其他钩子事件。
  • 在 Windows 上,钩子命令是在 PowerShell 和命令提示符中手动运行的,没有进入自动化测试。

设置方法

你需要 Node.js 18 或更高版本:

npm install -g zn-gate
zn hooks install codex

打开 Codex,用 /hooks 查看新增或已更改的钩子。Codex 只有在你于该处信任新钩子之后才会运行它们。然后在终端运行 zn-gate check。它应当对 Codex CLI 显示 OK(输出的含义)。完整步骤见 Codex CLI 安装页面。

如果想把真实的值完全移出 .env,请把它们存放在 zn-gate 的保险库中。这样你的 .env 里保存的是 __ZN_STRIPE_KEY__ 这样的标记:

zn unlock
zn env shadow .env

更多内容见 Scrubber。撤销钩子:zn hooks uninstall codex。

在你自己的机器上测试

这个测试只使用假数据。其中一部分只是依据文档说明应该发生的情况,我们没有在 Codex 中完整地端到端运行过,所以请自己检查每一步。

  1. 在一个新的空文件夹中创建 .env 文件,只写假数据:

    EXAMPLE_API_KEY=sk-test-EXAMPLE-not-a-real-key
    EXAMPLE_URL=https://example.com
  2. 安装钩子(zn hooks install codex),在该文件夹中打开 Codex,用 /hooks 信任这些钩子,并在另一个终端运行 zn-gate check。

  3. 对 Codex 说:"Run cat .env and tell me what it prints." 根据 compat.md,zn-gate 的 PreToolUse 钩子在 Codex CLI 0.163.0 上阻止了 cat .env,你应当看到来自钩子的消息,而不是这些值。

  4. 把 AWS 文档中的示例密钥 AKIAIOSFODNN7EXAMPLE 粘贴到提示词中。如果 zn-gate 认得这种格式,该提示词应当被阻止。如果没有被阻止,可能是因为这种格式不在 zn-gate 能检测的范围内。

  5. 可选:运行 zn unlock 和 zn env shadow .env,打开文件,检查其中保存的是标记。让 Codex 再读一次,并比较结果。

  6. 测试结束后删除示例文件夹。撤销钩子:zn hooks uninstall codex。

这里只有你自己的结果才算数。如果某一步的表现与本页所述不同,请联系我们,并附上你的 Codex CLI 版本。

常见问题

Codex 的模型能看到我的 API 密钥吗? 智能体读取、运行或收到的任何内容都可能到达模型:文件、shell 输出、MCP 结果和提示词。zn-gate 的钩子检查这些位置,但有上面所述的限制。

zn-gate 能阻止 Codex 读取 .env 吗? 它的钩子会阻止 shell 命令和补丁中读取含有值的 .env 文件的操作。Codex 把钩子称为护栏,而不是强制边界。

为什么清理后的输出是纯文本? Codex 没有可以改写工具结果的字段,所以 zn-gate 会把整个结果替换为清理后的文本。

如何撤销? zn hooks uninstall codex。

相关页面

来源