Appearance
调研:AI agent 怎样安全地使用密钥(2026-11-16)
来源:各项目的 README、文档,用 gh 读了部分关键源码。没有 clone 运行。
各项目要点
| 项目 | 许可证 | agent 怎么拿到密钥 | 明文会进入模型上下文吗 | 人工审批 | 主要问题 |
|---|---|---|---|---|---|
| varlock(约 5k★) | MIT | 读 .env.schema,varlock run -- cmd 注入环境变量 | schema 里没有值;@sensitive 的值在日志里打码 | 交给后端(比如 1Password 生物识别) | 注入后照样能 printenv |
| Rowel | 应用是 GPL-3.0;rowel-core、rowel-broker、rowel-autofill 这几个 crate 是 MIT/Apache | MCP、run --env K=rowel://…、本地 HTTP 代理替换占位符、浏览器填充、hook | 任何路径都不把值返回给 agent。MCP 的密钥本身解不出密钥值;代理只放行带占位符的请求,而且不跟随重定向 | 桌面弹窗:本次 / 本次运行(最长 8 小时)/ N 天 / 拒绝。卡片和身份信息还要 Touch ID 或 Windows Hello | env 模式下,被批准的命令能拿到明文 |
| agent-secrets (joelhooks) | MIT | secrets lease 带过期时间 | 会,直接打印原值 | 无 | 撤销租约只是记一笔账,收不回已经打印出去的值 |
| OpenKeylet | MIT(星数存疑) | MCP 的填充 / ssh / http 工具 | 默认隐藏 | 无 | 目标主机由 agent 自己选,还跟随重定向,很容易把密钥发到别处 |
| agent-secrets (zalan159) | 无许可证 | secret-exec | 输出会被清洗 | 一次性解锁 | 解锁凭据就放在 agent 能读的文件里;base64 只匹配从开头对齐的情况 |
| mcp-secrets-vault | MIT | MCP 代发 HTTP 请求 | 返回前会清洗 | 无 | 密钥以明文放在环境变量里 |
| tsm | MIT(仅 macOS) | Swift 后台进程 + run --env | get 会打印原值 | Touch ID 解锁 30 分钟;按调用方进程树区分会话;[confirm] 标记的条目每次都要验证 | 插件会自动批准 get |
| LEASH | CC-BY | 只是一份提案 | 默认"代 agent 执行操作","取出原值"属于例外 | 主人用 Ed25519 签发授权,并带短期状态声明 | 没有实现 |
| 1Password | 闭源;agent-hooks 是 MIT | op run 默认打码;MCP 只返回名字;agentic autofill | 官方立场是不用 MCP 暴露原始凭据 | 在桌面 App 里批准 | 本地 .env FIFO 解锁后任何进程都能读 |
| Bitwarden agent-access | Apache-2.0 | 经中继建 Noise 隧道,在 TUI 里逐条审批 | connect --output json 会返回明文 | 每次请求审批,可在一段时间内缓存 | 还是预览版 |
值得采用的做法
- 面向模型的那一侧解不出密钥。 MCP 只能申请授权,拿回的是授权编号和执行结果,从来不是值。
- 尽量由我们替 agent 使用密钥。 方式有三种:本地注入代理,绑定 host + path + method,不跟随重定向;浏览器代填;SSH 代签。环境变量注入是最弱的一档,要单独审批。
- 授权要绑定到具体用途。 档位分为一次、本次运行、N 天。授权绑定到精确的命令行或接口。调用方身份由内核给出的对端 PID 和进程树确定,不信 agent 自报的 client-id。保险库一锁,所有授权全部作废;另外有一键切断。
- 审计日志用哈希链,防篡改。 agent 只能访问专门给它开的保险库。共享时共享这个库,不共享整个保险库。
- 跨平台审批: 主路径是桌面 App 弹窗,再加一步系统验证:macOS 用 LAContext,Windows 用 Windows Hello(UserConsentVerifier),Linux 用 polkit 或主密码。远程或无界面的场景用手机推送。
要避免的坑
get或lease把原值直接打印到 stdout。- 用环境变量注入却不逐条命令审批。
- 依赖输出打码。base64 偏移、拆分、
rev、XOR 都能绕过,打码只能当最后一道保险。 - 把 host 当成默认值而不是白名单;跟随重定向。
- 解锁凭据放在 agent 能
cat到的地方。 - 一解锁任何进程都能读;没有区分各个 agent 的身份。
可以复用的代码(许可证兼容)
- Rowel 的 broker 和 autofill crate(MIT/Apache)
- Bitwarden agent-access(Apache-2.0)
- tsm(MIT)
- 1Password agent-hooks(MIT)