最小权限与凭据管理
身份、令牌、作用域、数据隔离与审计日志。
一句话理解:Agent 被骗、犯错都是迟早的事,最小权限决定了出事时的损失上限——给它一个清楚的身份、只够完成任务的短期令牌、看不见的凭据、隔离好的数据,以及每一步都留痕的审计日志。
前面几课反复出现一个结论:无论提示词写得多好、检测模型多先进,都不能保证 Agent 永远不被误导。既然如此,最现实的问题就变成了:万一它被误导了,它最多能做成多大的坏事?
这个上限,就是它拥有的权限。一个只能查询本区域订单的 Agent,被注入后最多泄露本区域的订单信息;一个拿着数据库管理员账号的 Agent,被注入后可能清空整个库。OWASP 把“过度代理”(Excessive Agency)列为 LLM 应用的十大风险之一,其中一个根因就是 权限过大:比如只需要读取,却拿到了删除权限。
第一个问题:Agent 以谁的身份行动?
| 身份模式 | 含义 | 优点 | 风险 | 适合 |
|---|---|---|---|---|
| 代表用户 | Agent 使用用户授权的令牌,权限等于或小于该用户 | 天然继承用户的数据权限,审计时能对应到人 | 用户权限很大时,Agent 也很大 | 个人助理、Coding Agent、办公 Agent |
| 独立服务身份 | Agent 有自己的服务账号,权限单独配置 | 权限可以精确收敛,不随用户变化 | 容易给多,且可能让低权限用户借 Agent 越权 | 后台队列处理、定时任务 |
| 两者结合 | 服务身份执行,同时校验发起用户的权限 | 既能收敛能力,又不让用户越权 | 实现更复杂 | 企业级业务 Agent |
最容易出问题的是第二种:“混淆代理人”(confused deputy)问题。假设「销售分析 Agent」用一个能读全公司数据的服务账号,而实习生问它“把所有大客户的合同金额列出来”,Agent 就可能替一个没有权限的人拿到了数据。所以企业级 Agent 通常采用第三种模式:执行动作时,既检查 Agent 自己的权限,也检查发起人的权限,取两者的交集。
把第三种模式画出来,关键就是中间那一步“取交集”:
令牌:范围要小、时间要短
授权的基础知识见 认证、授权与 OAuth。落到 Agent 上,令牌设计有四个原则:
| 原则 | 反例 | 正例 |
|---|---|---|
| 作用域最小 | 为了省事申请 admin、*、“完全访问” |
只申请 orders:read、tickets:write |
| 渐进授权 | 一开始就把所有可能用到的权限都申请了 | 先给只读权限,第一次需要写入时再请用户授权 |
| 有效期短 | 长期有效的 API Key 写在配置文件里 | 按任务签发、几分钟到几小时过期的临时令牌 |
| 可撤销 | 撤销一个令牌会让所有功能一起失效 | 每个 Agent、每个任务独立令牌,可单独吊销 |
MCP 的安全最佳实践文档也给出了同样的建议:初始只给低风险的基础权限,在第一次尝试特权操作时再申请提升,避免使用通配或“全部权限”式的作用域。MCP 场景下还有“令牌透传”等特有问题,见 MCP 的认证与安全。
对于资金类动作,令牌之外还要叠加 业务额度:例如「订单售后 Agent」的退款权限设置单笔上限、每日累计上限和每客户每月次数上限,超过任何一项就必须走人工审批。
凭据:Agent 用得到,但看不见
一个常被忽视的原则是:凭据不应该出现在模型的上下文里。凡是进入上下文的内容,都可能被模型复述、写进日志、或者在注入攻击下被发往外部。
常见的做法是让凭据停留在 Agent 之外,由执行层代为使用:
真实产品中可以看到同样的思路(据官方文档):
- Claude Code 的云端会话中,Git 凭据和签名密钥留在沙箱之外,由代理使用有作用域限制的凭据代为认证。
- Claude Code 的本地沙箱支持“掩码”凭据:沙箱内的命令看到的是占位符,只有在请求发往允许的域名时,由沙箱代理替换成真实值。
- 同时文档也提醒,沙箱内命令默认会继承父进程的环境变量,默认也能读到
~/.ssh/这类凭据文件,需要主动配置屏蔽。
这意味着:凭据安全不是默认就有的,要在设计时显式考虑。
数据隔离:能访问的数据也要分区
权限不只是“能调什么接口”,还包括“能看到哪些数据”:
- 租户隔离:SaaS 产品中,Agent 查询时的租户 ID 必须由系统从会话中注入,绝不能由模型填写。否则一句“查一下租户 B 的数据”就可能越界。
- 行级权限:「销售分析 Agent」连接的是只读副本,并通过数据库的行级权限,保证华东区销售只能查到华东区数据。
- 字段脱敏:客户手机号、身份证号等字段在返回给模型前就脱敏,Agent 分析不需要这些字段。
- 知识库权限:检索时按用户权限过滤文档,见 知识保鲜与权限。
审计日志:出事之后能说清楚
最小权限限制了损失,审计日志让你知道损失是怎么发生的。每一次有副作用的动作,至少记录:
| 字段 | 说明 |
|---|---|
| 发起人 | 哪个用户发起的任务,Agent 代表谁行动 |
| Agent 身份 | 哪个 Agent、哪个版本、使用的令牌标识(不记录令牌本身) |
| 动作与参数 | 调用了什么工具、参数是什么 |
| 决策依据 | 当时读取了哪些数据、引用了哪些证据 |
| 校验与审批 | 通过了哪些校验、谁在什么时间批准 |
| 结果 | 执行成功与否、回读验证的结果 |
| 关联 ID | 串联同一任务所有步骤的追踪 ID |
审计日志应该写入 Agent 无法修改的存储。技术实现上它和 Tracing 高度重合,但审计日志更强调完整、不可篡改和长期保留。
常见误区
- “先给大权限跑起来,以后再收。” 权限一旦给出去,业务就会依赖它,收回来比一开始就收紧难得多。
- “用用户的身份就安全了。” 用户本人可能权限很大,而用户并不期望 Agent 在一次简单查询里动用他的全部权限。
- “凭据放在环境变量里就算隐藏了。” 如果 Agent 能执行 Shell 命令,打印一下环境变量就能看到。
产品经理检查清单
- Agent 以谁的身份行动?是否同时校验了发起人的权限?
- 每个令牌的作用域是什么?是否存在通配或“全部权限”的作用域?
- 令牌有效期多长?能否按 Agent 或按任务单独吊销?
- 凭据是否会出现在模型上下文、日志或 Agent 可执行的环境中?
- 租户 ID、用户 ID 等关键参数是否由系统注入而非模型生成?
- 资金类动作是否有单笔、累计和频次上限?
- 审计日志是否记录了发起人、依据、审批和结果,且 Agent 无法修改?
练习
为「订单售后 Agent」设计一份权限说明书,用 45–60 分钟完成:
- 列出它需要访问的所有系统,以及每个系统需要的最小作用域(区分读与写)。
- 决定身份模式,并说明如何防止低权限客服借 Agent 越权。
- 为退款权限设计额度上限。
- 画出凭据从密钥管理服务到目标系统的流转路径,确认模型在任何环节都看不到凭据。
延伸阅读
- OWASP:LLM06:2025 Excessive Agency
- MCP:Security Best Practices——其中“Scope Minimization”一节讨论了渐进式授权。
- Claude Code:Configure the sandboxed Bash tool——凭据保护与掩码的实现方式。
下一步
权限最小化之后,仍有一些动作必须授权给 Agent,而且一旦做错就无法挽回。最后一课「不可逆操作」讨论如何通过预演、二次确认、延迟执行和回滚设计来管理这类动作。