Secret Redactor:Claude Code 密钥脱敏,保护提示词与工具输出
在 Claude 看到之前,把 API 密钥、邮箱和公网 IP 换成稳定的占位符,并在工具运行时还原。
权限
- 拦截工具调用能看到 Claude 发起的每一次工具调用(tool.call / tool.check),并可以阻止或修改它。
- 读取你的提示词可以看到你输入的内容和对话记录(prompt.* / session.append / session.messages)。
- 修改界面在 Claude Code 界面中绘制内容:横条、面板、状态文字、弹出通知(ui.render / $.ui.*)。
- 实测版本
- v2.1.291
- 最近实测
- 需要
- Claude Code ≥ 2.1.287
- 显示位置
- 弹出通知
在 Claude Code 中安装:
/plugin install secret-redactor --marketplace ray-amjad/awesome-claude-code-function-hooks这个插件能做什么?
Secret Redactor 是一款实现 Claude Code 密钥脱敏的社区插件,作者是 Ray Amjad(ray-amjad),属于他的 awesome-claude-code-function-hooks 合集。它在三条路径上工作:你输入的内容、工具读回的内容,以及附加在第一条消息上的上下文块。每个密钥、邮箱地址或公网 IP 地址,在模型看到之前都会被换成类似 [REDACTED-SECRET-164d0c98] 的占位符。
原值不会被销毁。同一个值总是得到同一个占位符,所以 Claude 仍然能区分不同的客户或不同的密钥。当 Claude 随后调用工具时,hook 会把占位符换回去,因此 Bash 命令或 Write 仍然带着真实值。cat .env 让 Claude 看到的是占位符,之后用到这些占位符的命令依然能正常运行。
它会隐藏带有厂商特征的密钥(sk-ant-、ghp_、AKIA、sk_live_、JWT、Slack 和 Discord webhook、私钥块、连接字符串里的密码)、高熵令牌、邮箱地址和 IP 地址。127.x、10.x、192.168.x 这样的私有 IP 段默认保持可见。price_、prod_ 这样的 Stripe 对象 id 被视为公开信息。作者的 README 指出,它需要开启函数 hooks;如果看起来什么都没发生,先检查这一项。
演示
录屏中,我们在小型演示项目里启动加载了该插件的 Claude Code,并开启了函数 hooks。我们输入一条提示词,其中包含作者在 test/fixtures/sample.env 里的示例密钥(不是真实凭据)和一个示例邮箱,然后按下 Enter。提交后的提示词在对话记录中变成 KEY=[REDACTED-SECRET-164d0c98] mail [REDACTED-EMAIL-6f096ff7],页脚右侧弹出提示:secret-redactor: hid 2 value(s) from the prompt。片段在 Claude 仍在工作时结束,我们没有录到它的回复。
安装
使用安装区块中的任意一种方式;它们都直接从作者自己的插件市场安装。然后开启函数 hooks:在 ~/.claude/settings.json 中加入 "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" },或者用 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude 启动会话。若想不安装就试用,克隆仓库后运行 claude --plugin-dir ./awesome-claude-code-function-hooks/plugins/secret-redactor。
$ install secret-redactor
需要 Claude Code ≥ 2.1.287
从作者自己的 marketplace 安装: ray-amjad/awesome-claude-code-function-hooks
1.在 Claude Code 中一行安装
/plugin install secret-redactor --marketplace ray-amjad/awesome-claude-code-function-hooks粘贴到正在运行的会话中(v2.1.275+)。Claude Code 会先询问是否添加该插件市场。
2.从终端安装
claude plugin marketplace add ray-amjad/awesome-claude-code-function-hooks claude plugin install secret-redactor@awesome-claude-code-function-hooks然后在所有已打开的会话中运行 /reload-plugins。
3.免安装试用
git clone https://github.com/ray-amjad/awesome-claude-code-function-hooks claude --plugin-dir ./awesome-claude-code-function-hooks/plugins/secret-redactor仅在当前会话中加载该插件,不会写入你的设置。
工作原理
hooks 模块只有一个文件:hooks/redact.ts。模块级的保险库里有两个映射,占位符由类别加上该值的 FNV-1a 哈希组成:
function mint(kind: Kind, value: string): string {
hidden++
const seen = byValue.get(value)
if (seen) return seen
const tag = `[REDACTED-${kind}-${fnv1a(value)}]`
byValue.set(value, tag)
byTag.set(tag, value)
return tag
}prompt.submit 会处理你输入的文本并弹出提示。tool.call 先把工具输入里的占位符还原,用 await next(input) 让工具运行,再处理结果,并在工具行上显示隐藏数量。prompt.context 会处理附加在第一条消息上的内容块中的密钥,但不处理邮箱。
一个值被判定为密钥的条件是:匹配某个厂商特征;或者是长度至少 24、同时含大小写字母和数字、每字符熵高于 3.6 比特的令牌;或者是跟在 API_KEY=、"token":、Bearer 这类名称之后、熵高于 3.0 比特的较短令牌。针对单词、驼峰命名、字母表和纯十六进制的规则,避免 git SHA 和标识符被隐藏。
自定义
插件声明了十二个选项,可以在 /config 中修改,也可以写在用户设置的 pluginConfigs 下:
secrets、pii:分别关闭一类脱敏。restoreInToolInputs:不再在工具运行前把真实值放回去。notify:关闭提示和工具行上的计数。minEntropy(3.6)、minLength(24)、contextMinEntropy(3.0):调高后隐藏得更少。redactPrivateIps:同时隐藏127.x、10.x、192.168.x等保留网段。allow、allowEmails、allowPrefixes、denyPrefixes:用逗号分隔的例外和补充规则。
权限与安全
在运行之前,我们读过了插件可以执行的每一个文件:plugin.json、hooks/hooks.json、hooks/redact.ts(唯一的模块,除类型外没有任何 import)、测试和示例文件。没有 package.json、安装脚本、二进制文件或打包后的代码。
- 网络、命令、文件、环境变量: 都没有。模块不调用
$.http、$.process、$.fs、$.env,也不使用$.store或$.state。保险库在模块内存里,随会话结束而消失。唯一的 API 调用是$.ui.toast和$.ui.notice。 - 拦截工具调用并读取你的提示词。 这正是该插件的目的,也与 README 一致。它改写你的提示词、改写工具输入(占位符变回真实值)、改写工具结果(真实值变成占位符),但从不拒绝调用。
- 还原是一种能力。 工具输入里的任何占位符都会被换成真实值,不论命令是什么。如果工具结果里带有注入的指令,Claude 可能被诱导把占位符写进
curl命令,真实密钥就会被发出去。如果你担心这一点,可以关闭restoreInToolInputs,代价是工具收到的是占位符文本。 - 占位符本身不是秘密。 哈希是 32 位的 FNV-1a,所以邮箱或 IP 这类低熵值的占位符可以通过对候选值求哈希来猜出。它让值不出现在模型的上下文中,但挡不住已经能试猜的人。理论上两个值也可能得到相同的哈希。
- 启发式规则会有疏漏。 熵规则可能漏掉某个密钥,也可能隐藏无害的令牌。它不扫描模型自己写的内容,也不会在重启后保留。
- 没有遥测,也不注入指令。 除占位符外,它不会向提示词添加任何自己的文字。
- 许可证: MIT,仓库中带有 LICENSE 文件。
claude plugin validate 没有报告错误或警告,但它的备注指出有两个没有 .catch 的拦截型 hook(prompt.submit 和 tool.call)。如果 hook 抛出异常,就没有兜底保护,所以 hook 里的 bug 可能让提示词或工具调用失败,而不是直接放行。claude plugin test 没有找到可运行的测试,因为作者的测试是 test/detect.test.mts(普通 Node 脚本),而不是 *.test.ts 文件。我们没有运行它。
- 拦截工具调用
- 能看到 Claude 发起的每一次工具调用(tool.call / tool.check),并可以阻止或修改它。
- 读取你的提示词
- 可以看到你输入的内容和对话记录(prompt.* / session.append / session.messages)。
- 修改界面
- 在 Claude Code 界面中绘制内容:横条、面板、状态文字、弹出通知(ui.render / $.ui.*)。
兼容性与故障排除
已在 macOS 上使用 Claude Code 2.1.291 检查:validate 通过,加载该插件后演示可以运行。如果什么都没有被隐藏:
- 函数 hooks 已开启:在设置里或启动 Claude Code 的 shell 中设置
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1。 - 在已经打开的会话中安装之后,运行
/reload-plugins。 - 这个值在保留名单中:
@example.com这样的文档域名、noreply@地址、私有 IP 段和 Stripe 对象 id 都是有意放过的。 - 输入框里显示的是你输入的原文;提示词提交之后才会出现占位符。
常见问题
- Secret Redactor 会把我的密钥发送到别处吗?
- 不会。我们在代码中没有发现网络调用、shell 命令或文件访问。真实值保存在 hooks 模块内存里的一个映射中,会话结束后就消失。
- 安装后为什么什么都没有被隐藏?
- 作者的 README 说明它是函数 hook,在开启函数 hooks 之前不会起作用。请在 ~/.claude/settings.json 的 env 块中设置 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1,或者在启动某一次会话时带上这个变量。
- Claude 看不到密钥,还能使用它吗?
- 能,在工具输入里可以。工具运行之前,hook 会把 [REDACTED-SECRET-164d0c98] 这样的占位符换回真实值,所以 Bash 命令或 Write 仍然带着真实密钥。模型始终只看到占位符。
- Claude 自己写出的密钥会被隐藏吗?
- 不会。只扫描 Claude 读到的内容,也就是你的提示词、工具结果和附加在第一条消息上的内容块。模型写进命令里的密钥,本来就是它已经拿到的密钥。
- 怎样让某些值保持可见?
- 使用 /config 中的选项。allow 接受精确字符串,allowEmails 接受地址或 @yourdomain.com 这样的域名,allowPrefixes 把额外的 id 前缀标为公开,调高 minEntropy 则隐藏得更少。
# 相关插件
更多 安全防护、为 Claude 添加的工具。

