脱敏
exec_with_secrets 返回给模型的所有内容(stdout 和 stderr)都会先经过清洗。注入的密钥每出现一次,就会被替换成一个占位符,标明密钥名称以及发现它时所用的编码:
Authorization: Bearer [STRIPE_KEY:REDACTED]
QXV0aG9yaXphdGlvbjogQmVhcmVyIH[STRIPE_KEY:base64:REDACTED]Ao=
按值匹配,而不是按模式匹配
keygrant 知道它注入的每个密钥的真实值,因此它直接匹配这个值,而不是去猜“看起来像 key 的东西”。这里没有前缀黑名单(sk-、ghp_、AKIA……),也就不会在服务商推出新格式时跟不上。
匹配的形式:
- 明文;
- base64,包括 URL 安全的 base64,覆盖所有字节对齐方式:同一个 key 的编码结果取决于它前面是什么,所以三种对齐方式都会检查;
- hex,大写和小写;
- URL 编码。
在 CLI 中
keygrant exec 只有加上 --redact 才会脱敏:
keygrant exec --redact STRIPE_KEY -- sh -c 'echo "$STRIPE_KEY"' # 输出 [STRIPE_KEY:REDACTED]
keygrant exec STRIPE_KEY -- ./deploy.sh # 输出原样显示在你的终端
不加该参数时,输出直接流向你的终端,这正是你自己运行命令时想要的效果。如果由 agent 调用 CLI,它必须传入 --redact;MCP 工具则始终会脱敏。
局限
脱敏是兜底手段,而不是安全边界。真正的边界是:密钥值从一开始就不会进入模型的上下文。
- 它不认识的编码可以绕过它:压缩、加密,或者把值拆分到多行。
- 文件不在覆盖范围内。如果某条命令把密钥写进文件,之后 agent 又用其他工具读取了这个文件,keygrant 根本看不到。
- 派生值不在覆盖范围内。基于你的 key 签发的 token 是另一个不同的字符串。