如何让 API 密钥远离 OpenCode
OpenCode 的模型能看到什么,zn-gate 的 OpenCode 插件在每次工具调用之前、之后以及对你的提示词会阻止或清理什么,它不覆盖什么,如何设置,以及一个使用假数据的简短测试。
OpenCode 会把进入对话的所有内容发送给它的模型:你输入的提示词、智能体读取的文件、shell 命令的输出,以及 MCP 工具的结果。这些位置中的任何一个出现 API 密钥,都可能到达模型。zn-gate 在 OpenCode 中安装一个插件来检查这些位置。本页根据 zn-gate 的文档说明该插件做什么、做不到什么,并给出一个你可以自己运行的测试。
密钥可能通过哪些途径到达模型
zn-gate 针对 OpenCode 的插件关注会话中的三个时刻:
- 你输入的提示词。 粘贴进去的密钥可以在发送前被阻止。OpenCode 会将其显示为错误。
- 工具调用,在它运行之前。 无论使用哪个工具,读取含有值的
.env文件、凭据文件以及 zn-gate 自己的~/.zn文件夹的操作都可以被阻止。对~/.zn以及各智能体的钩子和插件配置的写入也可以被阻止。 - 工具的输出,在模型看到之前。 其中的密钥值会被替换为标记。这适用于所有工具(包括 MCP 工具),也适用于 OpenCode 在终端界面中显示的预览。
该插件不会检查模型的最终回答。而且 OpenCode 会在本地保存自己的会话副本,所以 zn-gate 对模型所见内容的处理,并不会清理 OpenCode 存储的全部内容(见下文的限制)。
zn-gate 在 OpenCode 中检查什么
zn hooks install opencode 会把一个小插件 zn-gate.js 写入 OpenCode 的插件文件夹。下表依据 zn-gate 仓库中的 compat.md,对应当前已发布的版本。
| 位置 | zn-gate 在 OpenCode 中的做法 |
|---|---|
读取含有值的 .env 文件、凭据文件和 ~/.zn |
在所有工具中被阻止。 |
写入 ~/.zn 以及各智能体的钩子和插件配置 |
被阻止(write、edit、apply_patch 和 shell)。 |
| 工具输出 | 在模型看到之前,在所有工具中被清理,终端预览中也是如此。 |
| 粘贴到提示词中的密钥 | 被阻止。OpenCode 将其显示为错误。 |
使用 __ZN_<NAME>__ 标记的命令 |
自动改写为通过 zn run 运行。OpenCode 自己的权限规则仍然适用。 |
secrets MCP 服务器 |
可选。zn hooks install opencode 会打印需要添加到 opencode.json 的片段。 |
| zn-gate 与 OpenCode 的端到端运行 | 是:发送给模型提供商的值为 0 个。 |
改写本身不会批准任何操作,OpenCode 自己的权限规则仍然适用。
在 OpenCode 中,zn-gate 不会把检测到的值还原到命令里:标记保持原样,因为 OpenCode 会在会话中保留工具运行时使用的参数,而模型可以读到它们。
zn-gate 在 OpenCode 中不覆盖什么
- 如果 zn 插件无法运行,OpenCode 的调用和消息会被阻止,而不是放行。项目级安装使用 PATH 中的
zn,所以在没有安装 zn 的机器上,插件无法运行,调用会在那里被阻止。 - 没有已知格式、又不在保险库或
.env文件中的密钥,可能通过清理。 - 模型会在自己的历史记录中看到被包装后的命令,包括
node和 zn 的本地路径(不含任何密钥值)。 - 命令仍在运行时 OpenCode 存储的实时输出会留在它的本地数据库中,因为它是在插件能够清理之前就已存储的。
- 超过 100 KB 的 shell 命令或补丁会被阻止,因为 zn-gate 无法在 OpenCode 等待插件的时间内完成检查。
- 在 Windows 上尚未测试。命令包装是为 bash 编写的:如果 OpenCode 的 shell 是 PowerShell,带标记的命令会失败而不是运行(不会暴露任何值)。
- OpenCode 的文档没有列出任何能在智能体中不留痕迹地关闭插件的设置,所以 zn-gate 在这方面没有可检测的内容(zn-gate 于 2026-10-17 检查)。
设置方法
你需要 Node.js 18 或更高版本。如果你之前已经为 OpenCode 安装过 zn-gate,请先更新,再重新运行第二行:
npm install -g zn-gate
zn hooks install opencode
重启 OpenCode。然后在终端运行 zn-gate check。它应当对 OpenCode 显示 OK(输出的含义)。zn-gate check 会确认 zn 针对 OpenCode 的规则,但不会启动 OpenCode。完整步骤见 OpenCode 安装页面。
如果想把真实的值完全移出 .env,请把它们存放在 zn-gate 的保险库中。这样你的 .env 里保存的是 __ZN_STRIPE_KEY__ 这样的标记:
zn unlock
zn env shadow .env
更多内容见 Scrubber。撤销插件:zn hooks uninstall opencode。
在你自己的机器上测试
这个测试只使用假数据。其中一部分只是依据文档说明应该发生的情况,我们没有在你使用的 OpenCode 版本上完整地端到端运行过,所以请自己检查每一步。
-
在一个新的空文件夹中创建
.env文件,只写假数据:EXAMPLE_API_KEY=sk-test-EXAMPLE-not-a-real-key EXAMPLE_URL=https://example.com -
安装插件(
zn hooks install opencode),在该文件夹中重启 OpenCode,并在另一个终端运行zn-gate check。 -
对 OpenCode 说:"Read the file .env and tell me what it contains." 根据 compat.md,zn-gate 会在所有工具中阻止读取含有值的
.env文件,所以你应当看到来自 zn-gate 的消息,而不是这些值。 -
把 AWS 文档中的示例密钥
AKIAIOSFODNN7EXAMPLE粘贴到提示词中。如果 zn-gate 认得这种格式,OpenCode 应当显示错误,并且不发送该提示词。如果没有被阻止,可能是因为这种格式不在 zn-gate 能检测的范围内。 -
可选:运行
zn unlock和zn env shadow .env,打开文件,检查其中保存的是标记。让 OpenCode 再读一次,并比较结果。在 zn-gate 自己的端到端运行中,OpenCode 得到的是标记,而不是值。 -
测试结束后删除示例文件夹。移除插件:
zn hooks uninstall opencode。
这里只有你自己的结果才算数。如果某一步的表现与本页所述不同,请联系我们,并附上你的 OpenCode 版本。
常见问题
OpenCode 的模型能看到我的 API 密钥吗? 智能体读取、运行或收到的任何内容都可能到达模型:文件、shell 输出、MCP 结果和提示词。zn-gate 的插件检查这些位置,但有上面所述的限制。
zn-gate 能阻止 OpenCode 读取 .env 吗? 它的插件会在所有工具中阻止读取含有值的 .env 文件。
它会检查模型的回答吗? 不会。插件检查的是你的提示词、工具调用和工具输出。
插件出故障了会怎样? 在你修复之前,OpenCode 的调用和消息都会被阻止。运行 zn-gate check 查看该怎么做。
如何撤销? 运行 zn hooks uninstall opencode,然后重启 OpenCode。
相关页面
来源
- zn-gate,各智能体兼容性与 OpenCode 插件:compat.md
- zn-gate,OpenCode 安装页面:/zh/docs/install/opencode/
- OpenCode,插件文档:https://opencode.ai/docs/plugins