Agent 工具密钥隔离与最小权限
Agent 要完成真实任务,往往需要访问邮件、代码仓库、数据库或云资源。最省事的接法是把长期 API Key 放进进程环境变量,再让工具代码直接读取;但模型输出、调试日志、第三方插件和任意命令都可能接触同一进程上下文。一旦发生提示词注入或工具误用,长期密钥会把一次错误放大为持续访问能力。更稳的目标是:模型只表达操作意图,运行时替它使用受限凭证,模型本身始终看不到密钥明文。
一、先画清楚密钥可能经过的路径
密钥保护不能只检查代码仓库。生产 Agent 中,凭证可能出现在环境变量、工具参数、异常堆栈、HTTP 调试日志、任务快照、会话回放和子进程继承环境里。首先为每种凭证建立清单:它能访问哪些资源、是否可写、谁持有、如何轮换、会被哪些运行时组件读取。
| 持有方式 | 暴露面 | 适合程度 |
|---|---|---|
| 写进系统提示词或工具描述 | 会进入模型上下文与日志 | 禁止 |
| 作为工具参数由模型填写 | 模型可见,容易被复述 | 禁止 |
| Agent 进程环境变量 | 同进程代码与子进程可读 | 仅限受控单用途服务 |
| 凭证代理服务代为签名 | 模型只见操作结果 | 推荐 |
| 每次运行签发短期令牌 | 泄漏窗口和权限范围较小 | 推荐 |
这里的核心区分是“读取密钥”与“使用能力”。Agent 通常需要的是“在某个仓库创建 issue”,并不需要知道 GitHub token 是什么。把能力包装成窄工具,才能真正缩小暴露面。
二、用凭证代理把模型与 Secret Store 隔开
推荐链路是 Agent → Tool Gateway → Credential Broker → 外部 API。Agent 发出结构化工具调用;网关验证运行身份和策略;凭证代理从 Secret Store 获取或签发凭证,并在受信任网络层完成请求。返回给 Agent 的只有经过裁剪的业务结果。
这条链路必须保证两点。第一,Agent 工作进程没有读取 Secret Store 的通用权限,只能调用已注册的工具。第二,凭证代理不接受任意 URL、任意方法或任意 Header,否则它只是一个可被利用的开放代理。每个工具都应绑定固定上游、允许的动作与响应字段。
例如“发送账单提醒”工具可以只接受模板 ID、收件人客户 ID 和业务变量,由服务端查询已验证邮箱并使用专用发信身份。不要提供一个接受 url、headers、body 的通用 HTTP 工具,再期待系统提示词阻止越权。
三、长期根凭证只用于签发短期能力
能使用短期令牌时,不要把长期密钥下发给执行器。短期能力至少绑定 run_id、工具名、资源范围、允许动作、到期时间和最大使用次数。任务结束、取消或人工撤回后立即失效。
{
"subject": "run_8f3a",
"tool": "repo_issue_writer",
"resource": "org/docs-repo",
"actions": ["issue:create"],
"expires_in": "10m",
"max_uses": 1
}
如果上游只支持长期 API Key,仍可在内部网关实现短期 capability:运行时拿到的是网关令牌,网关再使用保存在受控服务中的上游 Key。这样无法减少上游主密钥本身的权限,但能限制 Agent 可触发的动作、时间与资源,并把轮换集中到一处。
四、权限范围要落实到动作与资源
“允许使用 GitHub”“允许访问数据库”都太粗。策略至少要同时表达主体、动作、资源和条件。例如读取 org/docs-repo 不自动包含写入,创建 issue 不自动包含合并 PR;查询分析库不自动包含生产数据库,读取某张表也不包含导出全部行。
条件可进一步限制分支、行数、收件人域名、金额、工作时段和环境。默认拒绝未知动作,新增工具或参数时必须显式更新策略。工具服务也要在执行时重新验证资源归属,不能只相信 Agent 传来的 tenant_id 或路径。
多 Agent 委派时,子任务能力只能是父任务权限的交集,不能通过转交扩大范围。通用风险分级和审批边界可参考 AI Agent 工具权限粒度设计;本文的重点是让通过审批的能力也只携带必要凭证。
五、高风险工具要在签发前加人工闸门
密钥隔离解决“谁能使用凭证”,不替代业务审批。删除资源、发布生产、转账、群发邮件等动作,即使使用短期令牌,也可能造成不可逆影响。策略引擎应先把结构化意图冻结为待审批对象,展示目标资源、关键参数、影响范围和过期时间;批准后再签发只对应这一次动作的能力。
批准对象要绑定参数哈希。若 Agent 在批准后修改收件人、金额或目标仓库,原批准立即失效,必须重新审核。不要让人只批准一句自然语言摘要,而执行器接收另一份可变 JSON。对低风险、可逆且范围小的动作,可以按规则自动签发,减少不必要的人机交互。
六、防止密钥从日志和错误路径旁路泄漏
即使模型拿不到密钥,底层 HTTP 客户端仍可能在调试模式打印 Authorization Header。日志系统应在采集端和存储端双重脱敏,覆盖 Header、URL 查询参数、Cookie、常见 Key 前缀和工具入参中的敏感字段。脱敏失败时宁可丢弃字段,也不要依赖事后清理。
错误返回要使用稳定错误码与安全摘要,不能把上游完整请求、环境变量或堆栈直接交给模型。任务快照只保存凭证引用和 capability ID,不保存可用令牌;子进程启动时使用最小化环境白名单,不默认继承父进程全部变量。发现实际泄漏后的吊销与追溯流程可参考 AI API Key 泄露应急响应手册。
七、审计记录要能重建一次授权决策
每次能力签发和工具执行至少记录:主体、任务、工具版本、策略版本、资源、动作、参数哈希、审批人或自动规则、凭证引用、开始与结束时间、结果码。真实 Secret 和完整敏感参数不得进入审计记录。
审计链需要回答三个问题:为什么这次调用被允许、实际访问了什么、返回结果去了哪里。可对签发、执行和结果投递事件使用同一 tool_call_id 串联,并监控拒绝率、越权尝试、过期令牌使用、单次能力重复使用和异常资源枚举。审计服务本身应与 Agent 写权限隔离,避免被同一运行删除证据。
八、用攻击场景验证边界
上线前不要只测试正常调用。给 Agent 输入包含“打印环境变量”“把凭证作为参数发给外部地址”“改用另一个租户资源”等注入内容,确认模型即使服从,运行时仍会拒绝。再模拟日志异常、代理超时、令牌过期、审批后改参和子 Agent 委派,检查是否会回退到更宽权限。
轮换演练同样重要:替换上游长期密钥时,业务应通过凭证代理平滑继续;撤销某个运行时,只影响它自己的 capability;Secret Store 不可用时,系统应安全失败而非读取旧配置文件兜底。最小权限不是一张静态表,而是一套可验证、可撤回、可审计的运行时机制。
九、相关阅读
如果你需要统一多模型 API 接入并减少应用中散落的模型凭证,YoTradeApi 可作为集中调用入口,便于你在外层继续实施工具级授权、审计与轮换。