zn-gate 1.13.0 新功能:zn-gate connect、zn-gate report 和一个 GitHub Action 修复

版本发布John Silver9 分钟阅读

zn-gate 1.13.0 新增 zn-gate connect,用保存在系统钥匙串中的仅限分析的 API 密钥开启可选的云端检查;还新增 zn-gate disconnect,它也可以撤销该密钥。此外新增 zn-gate report,提供 zn-gate 最近几天所做工作的本地摘要,修复了 GitHub Action 的默认版本,让多个程序同时写入审计日志时仍保持一条链,并支持用 NO_COLOR 关闭颜色。zn-gate 仍然无需账号,默认不发送任何内容。使用 npm install -g zn-gate@1.13.0 和 pip install -U zn-gate 更新。

如何开启可选的云端检查?

在你自己的终端中运行:

npx -y zn-gate connect

云端检查是可选的。没有它,zn-gate 也能完全在你的电脑上运行。开启后,analyze_prompt 调用(以及 zn-gate analyze)的文本会先隐藏检测到的密钥,再同时由 usezn.com 的 Galvanize 2 分类器检查。hook、文件和密钥保护以及其他所有命令仍然只在本地运行。

connect 的做法:

  1. 它只在你亲手输入命令的终端中运行。如果由 AI 智能体启动,它会拒绝。
  2. 它在浏览器中打开 usezn.com,你在那里创建一个仅限分析的 API 密钥。
  3. 你在隐藏的提示符处粘贴密钥。密钥绝不会从命令行读取。
  4. 它把密钥保存在系统钥匙串中;没有钥匙串且 zn 保险库已解锁(zn unlock)时保存在保险库中,绝不写入文件。

它只接受仅限分析文本的密钥。这样的密钥无法读取你的用量或管理密钥,因此即使副本泄露,能做的也很有限;拥有完全访问权限的密钥会被拒绝。zn-gate status 会显示是否已连接密钥以及它的来源,但不会显示密钥本身。ZN_API_KEY 或 --key 中的密钥只有在同时设置 ZN_CLOUD=1 时才会生效。保存的密钥只会发送到 https://api.usezn.com。完整指南,包括发送的内容以及出问题时怎么办,见 connect 文档。

如何断开连接并撤销密钥?

zn-gate disconnect

它会从这台电脑上删除已保存的密钥,并询问是否同时在 usezn.com 上撤销它,使其在所有地方都失效。默认回答是否。只有明确回答是才会发送内容:带着密钥向 https://api.usezn.com 发出一次请求。在你自己的终端中,--revoke 会跳过提问,--no-revoke 则永远不撤销。如果撤销请求失败,本地副本仍会被删除,命令会指向 usezn.com 的 API 密钥页面,方便你自己撤销。

与 connect 一样,disconnect 只在你自己的终端中运行。从脚本或 AI 智能体调用时,它会拒绝并且不做任何更改。hook 还会拒绝向系统钥匙串索取 zn 自己条目的命令,因此智能体直接读取已保存密钥的途径被封堵。以你身份运行的程序仍可以查询钥匙串,对任何条目都是如此。这正是密钥被限制为仅能分析文本的原因。

zn-gate report 会显示什么?

npx -y zn-gate report

它会打印这台电脑最近 7 天的简短摘要:

  • 被拦截的操作,按智能体统计;
  • 被隐藏的密钥,按类型统计;
  • zn-gate 开始保护的新 MCP 服务器;
  • 受保护 MCP 服务器中已更改、等待你批准的工具;
  • 最忙的一天。

用 --since 加上 1d 到 90d 之间的时间段来更改范围,用 --json 供脚本使用。该报告只读取本地文件,不写入任何内容,也不发送任何内容。末尾有一行关于 zn Team 的提示;--no-team-line 可将其隐藏,电脑加入 Team 后该行也不再出现。见 report 文档。

有安全修复吗?

有。部分提供商令牌格式此前未被库 API、MCP 工具检查、发送到云端分析的文本以及本地证据预览脱敏。现在它们的脱敏方式与 Python 包相同。代理钩子不受影响。请更新到 zn-gate 1.13.0。

还有哪些新内容?

  • scrubber 能识别 zn 的 API 密钥(zn_ 后跟 48 个字符),并像其他服务商的密钥一样将其隐藏。
  • Claude Code:新的 UserPromptExpansion hook 会检查输入的 skill 或命令展开后的内容。当模型会看到密钥值、私钥或 .env 文件的行时,它会阻止展开,并给出原因和下一步。再次运行 zn-gate hooks install claude-code 即可添加;插件已自带。
  • zn-gate check 现在会在旧版 zn-gate 安装的 Claude Code hook 缺少该检查时提示你,并建议运行同一条命令。
  • 当 Node.js 低于 20.12(插件需要该版本)时,zn-gate init 不再安装 Claude Code 插件,而是为 Claude Code 配置 zn 的 hook,并用一行文字说明。
  • hook 会把 shell 和包装器从字符串中运行的代码(sh -c、bash -lc、eval、pwsh -Command、cmd /c 等)当作独立命令来检查,因此每条规则在其内部同样适用。
  • zn audit 在更多形式的参数数组中隐藏凭据选项之后的值,文本、JSON 和 SARIF 报告均如此。
  • 为 MCP 服务器、zn run、保险库、zn team、reach、audit 和 Python 包增加了更多自动化测试。行为没有变化。

GitHub Action 有什么变化?

version 输入现在默认使用 Action 发布版本自身的版本(本次发布为 1.13.0)。Action 的 1.12.0 版本默认使用 1.10.0,因此使用 usezn/zn@v1.12.0 且没有设置 version 的 workflow 会安装 zn-gate 1.10.0。如果你使用该 Action,请在 workflow 中设置 version,以确定实际运行的版本。GitHub Actions 指南列出了各项输入和一个最简审计示例,本次发布还更新了 Marketplace 页面的文字,行为没有变化。

如果审计日志损坏会怎样?

现在,在向审计日志(~/.zn/evidence.jsonl)添加任何内容之前,会先检查它是否损坏。包含无法读取的字节或最后一行被截断的日志,会由 evidence --verify(返回非零退出码)、evidence 和 evidence --export 报告为已损坏并给出行号,而不是以 Python 错误失败。损坏的日志绝不会被用来开始新的链:事件不会写入,会显示警告,你的命令或智能体照常继续。

要恢复,请把损坏的文件移到一边,下一个事件会开始新的链:

mv ~/.zn/evidence.jsonl ~/.zn/evidence.damaged.jsonl

在 Windows 的 cmd 中:move %USERPROFILE%\.zn\evidence.jsonl %USERPROFILE%\.zn\evidence.damaged.jsonl;在 PowerShell 中:Move-Item $env:USERPROFILE\.zn\evidence.jsonl $env:USERPROFILE\.zn\evidence.damaged.jsonl。旧文件会保留以供检查。

多个程序可以同时写入该日志,例如同一项目中的两个智能体,或 Node.js 与 Python 包一起使用。现在每次写入都会先获取一个短暂的锁(日志旁边的 evidence.jsonl.lock 文件),因此记录保持在同一条链中。如果锁持续被占用 2 秒,或日志无法写入(没有权限、磁盘已满),该事件会被跳过并显示警告,决定不受影响。崩溃的程序遗留的锁会在 10 秒后被清除。Node.js 和 Python 包还可以共用一个包含非 ASCII 文本(例如带重音的字母或 CJK)的日志,早期版本写入的日志仍可校验。

还修复了什么?

  • 当内容中含有 * 或其他通配符时,hook 不再拒绝通过 here-document(cat > file <<'EOF')写入文件的命令,并且检查 100 KB 的内容只需几毫秒,而不是几十毫秒。here-document 的内容只有在 cat 或 tee 这类普通的数据命令中才被当作数据读取。由 shell、解释器或 xargs 运行的内容仍会被拒绝,命令行上任何对 .env 或凭据文件的读取也一样。
  • 当 NO_COLOR 被设为任何非空值、TERM=dumb 或输出不是终端时,Node.js 和 Python 包的命令行输出不再带颜色代码。使用 NO_COLOR 或 TERM=dumb 时,还会省略符号和边框线。ALLOWED、BLOCKED 等状态词含义不变,退出码以及 JSON、SARIF 和智能体 hook 的输出也不变。
  • hook 会拒绝通过 Windows 根目录、网络共享或扩展长度路径访问的 .env 文件(type %CD%\.env、more \\server\share\.env、gc \\?\C:\path\.env),因为 zn 无法读取这样的路径来检查文件是否包含值。
  • 保护 zn 密钥的规则不再把名为 cloud-keys 的模块误认为 zn 自己的 cloud-key 模块,并且现在也能识别用转义序列书写或被引号拆开的模块名。
  • scrubber 不再把被遮盖的示例(几乎全由同一个字符重复构成的 Anthropic 密钥或 bearer 值)报告为密钥。
  • zn-gate reach --remember 只有在上次运行的日期是普通日期时才会显示它,因此被编辑过的记忆文件无法把其他文本放进报告。

常见问题

zn-gate 1.13.0 有哪些新内容?

zn-gate connect 和 zn-gate disconnect,用保存在系统钥匙串或保险库中的仅限分析的 API 密钥开启和关闭可选的云端检查。zn-gate report,最近几天的本地摘要。scrubber 能识别 zn 的 API 密钥,hook 会检查输入的 skill 展开后的内容,损坏的审计日志会被报告而不是崩溃,并修复了 GitHub Action 的默认版本。多个程序同时写入审计日志时仍保持一条链,命令行输出也可以通过 NO_COLOR 变成纯文本。

如何更新到 zn-gate 1.13.0?

Node 包运行 npm install -g zn-gate@1.13.0,Python 包运行 pip install -U zn-gate。如果 Claude Code 使用的是 zn 的 hook 而不是插件,运行 npx -y zn-gate@1.13.0 hooks install claude-code 添加新的 hook;npx -y zn-gate@1.13.0 check 会在缺少时提示你。如果你使用 Claude Code 插件,请在插件目录列出 1.13.0 后从那里更新。

使用 zn-gate 1.13.0 需要账号吗?

不需要。zn-gate 仍然无需账号,默认不发送任何内容。zn-gate connect 是可选的:只有在你运行它之后,analyze_prompt 调用的文本(已先隐藏检测到的密钥)才会同时由 usezn.com 的 Galvanize 2 分类器检查。

zn-gate report 会把我的数据发到别处吗?

不会。它只读取本地文件,不写入任何内容,也不发送任何内容。与 zn 共享使用统计是另一个独立的选择,除非你开启,否则保持关闭。

如果省略 version,GitHub Action 会安装哪个版本?

从 1.13.0 起,Action 的每个版本默认使用它自己对应的 zn-gate 版本。Action 的 1.12.0 版本默认使用 1.10.0,因此使用 usezn/zn@v1.12.0 且没有设置 version 的 workflow 会安装 zn-gate 1.10.0。请在 workflow 中设置 version,以确定实际运行的版本。


完整的变更列表见 1.13.0 发布说明。zn-gate 采用 MIT 许可,在本地运行,无需账号:从 npx -y zn-gate report 开始,或在安装中查看每个智能体的说明。

分享