Agent 短期能力租约:把最小权限绑定到任务、资源与截止时间
Agent 不应持有覆盖整个会话的万能凭证。本文设计由策略代理签发的短期 capability lease,绑定工具、资源、调用次数、执行者密钥与撤销纪元。
本文要点
- 主题聚焦:AI Agent、MCP、DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
很多 Agent 平台已经把模型与长期 API Key 分开,却仍给一次 run 注入一个能访问整个项目、持续数小时的 bearer token。任务只需读取三张工单并创建一个草稿,这枚 token 却可能导出全部客户、调用任意写工具;只要它进入 Prompt、日志或恶意工具,攻击窗口会一直延续到人工轮换。
MCP Server 鉴权边界 解决用户、服务和工具身份不要混用,AI 平台密钥轮换 解决长期凭证生命周期。本篇关注更窄的一层:每次高价值工具调用前,由可信策略代理把身份兑换成短期 capability lease,只授权这次任务需要的工具、资源和次数。
身份证明“是谁”,租约证明“此刻能做什么”
worker 用工作负载身份请求租约,broker 从服务端会话取得用户、租户和 run,不采用模型提交的身份。策略引擎结合工具风险、ACL、审批和预算生成约束。
租约绑定 issuer、subject、代表用户 actor、audience、租户、run、工具、资源约束、调用次数、期限、唯一 capability jti、策略版本和撤销纪元。写操作通常只需几十秒,不能覆盖整个聊天会话。
{
"iss": "capability-broker",
"sub": "agent-worker-17",
"act": { "sub": "user-42" },
"aud": "ticket-service",
"run_id": "run-9f2",
"tenant_id": "tenant-a",
"tool": "ticket.create_draft",
"resource": { "project_id": "p-7", "version": 41, "acl_epoch": 12, "max_items": 1 },
"max_uses": 1,
"exp": 1784362260,
"jti": "cap-01J...",
"cnf": { "jkt": "base64url-jwk-thumbprint" },
"policy_version": "agent-cap-v12",
"revocation_epoch": 38
}
OAuth Token Exchange 可作为协议基础,但结果仍需业务约束。不能转交上游 token 或只写宽泛 write;资源过滤应包含项目、版本、ACL 纪元、字段和数量上限。
把令牌绑定到执行者而不是裸 bearer
短 TTL 仍挡不住窗口内盗用。worker 为 run 生成临时非对称密钥,租约用 cnf.jkt 绑定公钥指纹。每个请求另签一枚 DPoP proof JWT:header 必须为 typ=dpop+jwt、非对称算法 allowlist 和公开 jwk;payload 包含 htm、按服务端同一规则规范化且去掉 query/fragment 的 htu、iat、访问租约哈希 ath、server nonce,以及与 capability jti 不同且每请求唯一的 proof jti。
工具端拒绝 none、对称算法和私钥 JWK,验证 JWK thumbprint 等于 cnf.jkt、method/URI/ath/nonce 全匹配。iat 只接受很小窗口,并以 (jkt, proof_jti) 在窗口期内原子写入 replay cache;重复 proof 即拒绝。HTTP 重试生成新 proof,但沿用同一 execution id 查询原结果,不能再次产生逻辑副作用。临时私钥不进入模型,run 结束即销毁。
编程 Agent 沙箱权限 隔离文件、命令和网络,capability lease 限制服务端业务动作,两者必须同时存在。
每个工具服务独立执行约束
网关验签后,下游仍验证 audience、issuer、时间、租户、工具、约束和撤销纪元,不能信任客户端 header。本地执行器在同一事务锁定 capability、目标和授权版本,重查 ACL、tenant、resource_version 与 acl_epoch;匹配时才更新业务、消费 use count、创建 execution/outbox。不匹配则提交 terminal STALE 且旧 capability 不可再用。
外部副作用必须使用 If-Match/ETag、版本前置条件、reservation 或目标系统等价的条件操作,并传 execution id 作幂等键。412、reservation 失效或 ACL 拒绝都终止该 execution 并使 capability 不可复用;结果未知则进入对账,不凭原租约创建第二次逻辑执行。人工批准只是签发条件,Agent 人工审批门 不能替代这条原子边界。
Agent 不得自行 refresh;新交换必须重查会话、策略、资源和预算。run 取消、权限撤销或策略漏洞时提升 revocation_epoch,立即拒绝旧纪元。
用盗用和边界测试验收
负向矩阵覆盖换 audience/tenant/工具、扩大资源、过期、第二次消费 capability jti、重复 proof jti、错误 ath/nonce/htu、另一 run 私钥、资源版本或 ACL 变化。每项都由服务端拒绝并留下无凭证明文的审计。
压测 broker 不可用和消费存储超时。高风险写操作应 fail closed;少量低风险只读可以使用已签发且仍有效的租约,但不能缓存一个无限期总 token。监控签发率、拒绝原因、平均 TTL、过宽资源约束、重复消费和即将过期重试,发现某 run 高频申请新租约时触发循环护栏。
回滚不能恢复万能凭证
新策略误拒绝时,回滚到上一份已签名的约束模板和验证器版本,而不是关闭 audience、proof 或资源检查。先暂停新租约签发,保留已经验证的只读流量;若怀疑签名密钥或策略泄露,提升 revocation epoch、轮换 broker key,并禁用相关写工具。恢复后用完整负向矩阵验证,逐步开放租户。
若 capability 服务完全不可用,产品应提供只读或草稿模式并明确告知用户,不能把长期服务凭证重新注入 Agent。真正的最小权限不是把一个大 token 保存得更隐蔽,而是让每项能力都拥有短期限、窄资源、指定执行者和可验证的消费记录。这样一次泄露最多影响一个受限动作,而不是整个会话和项目。
延伸阅读
Related