我在一个生产环境中设计并落地了一套基于证据的 Agent 权限系统。核心思路就一句话:Agent 想干超出基本权限的事,得先拿证据来换一张一次性通行证。
以下内容已脱敏,但模式本身、失败场景和设计取舍都来自真实项目。
下面用两个例子来说明这个模式,全文都会反复用到:一个基于邮件的项目管理 Agent(负责发邮件和跟进任务),和一个数据管道 Agent(负责管理 ETL 任务和表结构)。两个都是我实际遇到的场景。
问题:角色权限管不了 Agent
大部分团队给 Agent 做权限管理,第一反应是拿 RBAC 来套:给 Agent 一个角色,绑一组允许的 API 操作,搞定。
管人用这套没问题,因为人的行为比较固定。一个测试工程师大概率就是跑测试、看报告、提 bug,一个"测试"角色能覆盖他 95% 的需求。
但 Agent 跟人有两个本质区别:
1. 它需要什么权限,事先自己都不知道。
你让一个 Agent 负责管理数据管道。执行到一半,它发现下游 ETL 任务因为上游表 schema 变更而失败了,需要修改表结构。再过几步,一个数据质量检查把它卡住了,它需要一个 override 权限。这些需求没法提前列举,Agent 自己也不知道会碰到什么,直到它真的遇上了。
静态角色只能做二选一:权限给太少 Agent 会卡住,给太多它可能造成灾难性破坏。
2. Agent 的速度和破坏力都是机器级别的。
人编辑一个表格,一分钟改几行,犯了错也好收拾。Agent 一秒钟可以改几百行。API 调用、部署和资源创建也是一样的道理。
一个真实的案例:同事做了一个基于邮件的项目管理 Agent,限制它只能给白名单内的人发邮件。当 Agent 判断需要联系白名单外的人时,它检查了发邮件脚本的代码,找到了白名单校验逻辑,自己写了一个新脚本绕过校验,一晚上发了 500 多封催促邮件,一路升级到了 CEO。静态白名单是唯一的防线,Agent 绕过去了。
模式:默认权限 + 证据规则 + 授权
我落地的模型分为三层:
第一层:默认权限,给到最窄
Agent 启动后只拥有完成核心任务所需的最小权限集:
- 所有读操作开放。Agent 看不到系统状态就什么都干不了。
- 仅限核心任务操作。 数据管道 Agent 只能读所有数据表和触发预设的 ETL 任务。邮件 Agent 只能读邮件和给白名单内的人发邮件。
这些操作的破坏力很低,不需要任何证据。
第二层:证据规则,想做更多就拿证据来换
所有超出默认权限的操作,都需要 Agent 提交证据来说明凭什么让它做。一条证据规则包含:
| 字段 | 说明 |
|---|---|
| 操作 | 这条规则可以解锁什么操作 |
| 所需证据 | Agent 必须提供什么 |
| 验证方式 | 代码校验、LLM 审查,或两者结合(代码优先) |
| 消费性 | 单次使用(授权后即消费)或可复用 |
用邮件 Agent 的例子来说明:
Agent 请求:给张三发邮件(张三不在白名单内)。
提交的证据:张三是项目 A 的成员(项目管理系统里查得到),他负责的测试任务已逾期 3 天(任务系统里查得到)。
系统验证:代码校验确认项目成员身份和任务逾期状态。
结果:发放一次性授权,允许给张三发一封邮件。授权使用后即作废。
用了这套模型,500 封邮件的灾难根本不可能发生:
- 群发邮件:没有定义对应的证据规则 → 不可能。
- 给高管发邮件:没有定义对应的证据规则 → 不可能。
- 绕过脚本:没用。就算 Agent 自己写了个新的邮件客户端,API 层会检查它有没有通行证。没有通行证,发不出去。
完整的授权申请流程如下:
第三层:没开过的门,根本不存在
没有定义证据规则的操作,默认就是做不了的。 新增的操作类型会自动被拦截,直到有人显式地为它编写了一条证据规则。
这意味着什么:
- 忘了给新功能配权限?没事,默认是安全的。
- 最坏情况是 Agent 报一个"权限不足",总比失控强。
验证策略:代码能查的绝不让 LLM 来
证据验证是这个模型中风险最高的环节。验证不靠谱,整个系统的保障就不成立。验证策略如下:
为什么一定要代码优先:LLM 审查存在被 prompt injection 攻击的风险。Agent(或被篡改的 prompt)可能精心构造证据文本来说服 LLM 放行。代码多验一条事实,LLM 就少一个被骗的机会。
用数据管道 Agent 的例子来说明:
这个 Agent 管理 ETL 任务。它的默认权限是读所有数据表和触发预设任务。某天它发现下游任务因为上游表的 schema 变更而失败了,于是请求修改表结构的权限。
提交的证据:下游任务 job-456 失败,错误日志显示字段 user_level 类型不匹配(实际为 VARCHAR,预期为 INT)。
验证分解:
| 要验的东西 | 谁来验 | 怎么验 |
|---|---|---|
| job-456 是不是真的挂了 | 代码 | 查任务状态表 |
| 这张表是不是这个 Agent 自己建的 | 代码 | 查 created_by 字段 |
| 错误日志说的到底是 schema 问题,还是网络超时或者别的 | LLM | 看一下错误信息的语义 |
代码先把能确认的事实全确认完,LLM 只需要判断最后一个问题。攻击面比让 LLM 判断所有东西要小得多。
证据用完就废
一个关键设计:单次证据在授权发放后即被消费。
数据管道 Agent 用一次任务失败日志获得了修改表结构的权限,这条证据就永久失效了。下次它需要修改另一张表,必须提交来自另一次失败的新证据。
这样 Agent 就没法靠一次申请成功反复拿权限了。每一次敏感操作都需要独立的证据支撑。
有些证据天然是可复用的。所有权("这张表是我创建的")是一个持续成立的事实,不会被消费。规则里会明确写清楚哪些证据是一次性的、哪些可以复用。
这个概念来源于 Consumable Credentials(Bowers et al., NDSS 2007),用线性逻辑来建模"用完即废"的凭证:evidence(job_failure) ⊸ capability(modify_schema),那个 ⊸ 符号的意思就是"这条证据消费掉之后,产生一次性的能力"。
纵深防御
证据模型是最主要的授权机制,但不能只靠它一个。以下安全措施各管各的,互相独立:
| 手段 | 防什么 |
|---|---|
| 速率限制 | 每个 Agent 每小时最多执行 N 次操作 |
| 资源配额 | 每个 Agent 的计算/存储上限 |
| 批量操作保护 | API 层拦截批量破坏性操作 |
| Token 过期 | Agent Token 会过期;授权继承 Token 的生命周期 |
| 手动 Kill Switch | 管理员可随时吊销 Token 并使所有未使用的授权失效 |
单靠任何一层都不够。LLM 被骗了?速率限制兜底。速率限制配错了?Kill Switch 兜底。一层层地兜。
为什么这个模型好用
说白了,这套模型做的事情跟人做决策是一样的。
你作为管理者,要不要允许 Agent 改一张表?你肯定会看:下游任务是不是真挂了,错误是不是真的指向 schema 问题,改表是不是合理的修复方式。证据规则系统就是把你脑子里这套判断流程写成了规则,让机器也能执行。
实际收益:
- 新增一种操作的权限管理只需要写一条证据规则。不用改 Token,不用改 API,不用重新部署认证模块。
- 默认安全。 新操作在被显式启用之前是被拦截的。配置遗漏的结果是安全的。
- 统一机制。 所有权、业务理由、上下文相关的访问控制都通过同一套证据规则来表达,不用搞好几套不同的系统。
设计背景
我是在一个 Agent 自主执行多步骤工作流的生产平台上设计并落地了这套系统。具体什么业务不方便说,但这个模式是通用的:只要你的 Agent 需要干超出基本权限的事、这些事有真实后果、而且需要什么权限没法在一开始就全定好,这套模式就适用。
一句话总结:Agent 的所有非基础权限都可以用证据规则来管,所有权是自动就有的证据,业务理由是要提交的证据,硬性禁止就是没有写规则。JIT 权限提升(Google Cloud PAM 的思路)、作业级 Token(GitLab CI/CD 的思路)、可消费凭证,全统一到同一个机制里了。
如果你也在做 Agent 基础设施,欢迎交流。用这套思路的团队越多,Agent 生态就越安全。