Skip to content

安全与分享

Chronicle 会扫描你的会话以查找密钥,可以从一开始就阻止编码 agent 读取到它们,并让你把一个会话以经过脱敏的、自托管的链接形式分享出去——全部在本地完成,你的原始日志绝不会被修改。

AI 编码会话里满是你不想泄露的东西:粘贴进提示词的 API 密钥、某个工具读取过的 .env、堆栈跟踪里的一个数据库 URL。Chronicle 分三层来处理这些——检测(detection)(扫描一个会话并预览哪些内容是敏感的)、预防(prevention)(一个 pre-tool-use 守卫,从根本上阻止密钥到达模型),以及安全分享(safe sharing)(一个经过脱敏的、会过期的、从你自己机器上提供的链接)。这三层全都基于本地启发式方法运行,没有任何 LLM 调用,而且脱敏是单向的:Chronicle 生成的副本是经过脱敏的,你的源日志绝不会被触动。

本地优先: 脱敏在一次分享被创建或一份导出被写入的那一刻就已固化。日后编辑某条规则,或者有人读取 Chronicle 的数据库,都无法把一份已经分享出去的副本反脱敏——原件从一开始就没离开过你的机器。

安全检查(Security Check)

在一个会话中,打开 🛡 Security Check 以扫描其中的敏感内容。Chronicle 会拿每条消息的文本和工具输入去比对它的内置规则(server/security.js),并展示一个并排预览:Detected(原文,每处命中都高亮显示)紧挨着 Redacted output(一份分享或导出的副本会包含的内容)。

内置规则(BUILTIN_RULES)无需任何配置,涵盖:

规则捕捉对象
API 密钥sk-…anthropic-…、AWS AKIA…、GitHub ghp_/gho_、Slack xox…、Google AIza…
密码password/passwd/pwd/secret = 值 的赋值
Bearer / JWT 令牌Bearer … 头和 eyJ… JWT
数据库连接字符串postgres://mysql://mongodb+srv://redis://amqp://mssql://
电子邮箱name@host.tld
电话号码国际格式和带短横线的格式
私有 IP 地址10.x127.x192.168.x172.16–31.x

在植入的测试密钥上,这些规则命中 13 中的 13。一次扫描会汇总总的命中数和按规则的分项统计,因此在你对一个会话做任何操作之前,就能一眼看清它包含什么。

自定义规则

内置规则不会知道你所在组织的密钥前缀,因此 Rules 面板让你可以用简单的通配符添加自己的规则——* 匹配任意一段非空白字符,? 匹配单个字符:

  • 一条像 KITE-* 这样的 redact(脱敏)规则会遮蔽任何符合该形态的内容。
  • 一条像 *@company.com 这样的 allow(放行)规则会保护匹配项不被脱敏——当一条宽泛的内置规则(例如邮箱规则)本来会抹掉某些你想保留的内容时很有用。

优先级是确定性的(scanText()):自定义规则先于内置规则运行,放行规则保护其覆盖范围,而在任何重叠处,更早的匹配胜出。实际上这意味着具体的、自定义的和放行的规则优先于宽泛的内置脱敏。规则可以被启用、禁用或删除,并且它们会应用于每一次扫描、导出和分享。

脱敏导出

Export redacted copy 会下载一份单向脱敏的 Markdown 记录(GET /api/sessions/:id/export-redacted)。它是可以安全地附到 bug 报告里或粘进文档中的产物。整个过程中会话已存储的消息始终是只读的——导出是一份全新的脱敏渲染,而非一次编辑。

实时保护

事后检测是有用的,但更强的保证是在一个工具运行之前就阻止密钥到达模型。Chronicle 附带一个 Claude Code PreToolUse hook,即 hooks/chronicle-guard.mjs,它正是做这件事的。

Security → Real-time protection setup 安装它。Chronicle 会先把 ~/.claude/settings.json 备份到 ~/.chronicle/backups/hooks/,然后为 Read | Grep | Bash | WebFetch 这些工具注册该守卫。此后,在 Claude Code 运行其中一个工具之前,守卫会请求 Chronicle 扫描工具内容(preToolUseCheck()):

  • 对于携带文件路径的类 Read 工具ReadGrepread_fileViewNotebookRead),Chronicle 会扫描文件的实际内容——这样一来,agent 即将打开的某个文件中的密钥就会被捕捉到,而不只是那些敲进提示词里的密钥。
  • 对于其他工具,它会扫描工具输入本身(Bash 命令、WebFetch URL 等等)。

高风险命中——API 密钥、密码、令牌、数据库连接字符串,以及任何自定义规则——会阻止该调用(hook 以 2 退出,并把它的解释展示给模型,好让它知道原因并作出调整)。较低风险的匹配会被标记但放行。无论哪种情况,该事件都会被写入 Security → Interception records,为你提供一份运行中的日志,记录什么被阻止或标记了、在哪个工具和文件上,以帮助你调整规则。

失败即放行,且默认关闭。 守卫通过 http://localhost:4173 与 Chronicle 通信,超时为 3 秒。如果 Chronicle 没有运行,它会干净利落地退出并让工具调用继续进行——它绝不会打断你的编码会话。它默认不安装;你要在 Security 页面主动选择开启。其他支持命令 hook 的 agent 可以指向 node hooks/chronicle-guard.mjs(它从 stdin 读取工具载荷;退出码 2 表示阻止)。

分享链接

要分享一个会话——发给队友、放进某个 issue——请打开 🛡 Security Check → Create share link。Chronicle 会铸造一个由本地应用提供服务的带令牌 URL:

http://localhost:4173/share/<token>

让它安全的关键在于它存储了什么createShare() 会把会话跑一遍脱敏,并只保存那份脱敏后的、在创建时刻被冻结的副本,外加一个随机令牌和一个过期时间(默认 7 天)。原始消息永远不会离开你的机器,而且因为脱敏快照是被冻结的,日后的规则变更无法追溯性地暴露任何内容。分享页面是一个自包含的深色 HTML 视图,被标记为 noindex,带有一条横幅,注明内容在分享时已被脱敏以及它何时过期。链接 URL 会被复制到你的剪贴板,按钮还会报告应用了多少处脱敏。

分享管理

Security → Share management 会列出你创建过的每一个链接——无论有效还是已过期——附带其标题、创建日期和过期日期,以及查看次数。Revoke 会立即删除一个链接;访问一个被撤销或已过期的令牌会返回一个朴素的“expired or been revoked”(已过期或已被撤销)页面。由于整套东西都由你自己的 Chronicle 实例提供服务,一个分享只有在你的应用运行时才可达,且只在你所允许的期限内可达。

三层合力

  • Detect(检测)——扫描任意会话,预览检测到的内容与脱敏后的对照,用自定义通配符规则来微调。
  • Prevent(预防)——主动开启 pre-tool-use 守卫,在 agent 读取密钥之前将其阻止;审阅拦截日志。
  • Share(分享)——发布一个经过脱敏、会过期、自托管的链接;随时可撤销。

有关脱敏规则引擎、拦截数据模型,以及分享页面如何渲染,请参见下面的架构说明。

相关内容

Released under the MIT License.