第 7 / 21 篇

第6章 委托凭据应当收窄权限与受众

把原始令牌一路转发会发生什么

一个客服端令牌先用于 Agent 会话,再转给工具代理,最后原样转给订单系统。每一层都能访问相同的受众和权限,任何中间层泄漏都会扩散到所有下游。更严重的是,订单系统无法知道请求究竟由哪个程序代办,也无法区分用户直接调用与 Agent 执行。这种透明转发看起来减少了认证代码,却扩大了凭据的可用范围。

合理的委托应同时限制目标服务、动作范围、租户、时限和执行者。委托后的权利不应超过委托前的上限,凭据到期时间不应晚于父凭据。上游服务也不能因为自己持有高权限服务密钥,就把一个低权限用户升级成管理员。用户权限与服务权限通常应取交集,并在业务对象层重新检查。

实验中,tool-proxy 受众凭据只能进入代理。代理向固定身份服务提交经过验证的父令牌,身份服务在线确认主体状态,再签发 business-api 受众、三十秒有效的子凭据。scope 从父凭据保留,actor 被设置为固定 agent-demo。调用方不能通过 /delegate 指定 subject、tenant、actor 或新 scope。业务端只接受 business-api,因而原令牌不能直接使用。

本书自定义协议的边界

/delegate 是教学接口。它没有实现 RFC 8693 的 grant_type、subject_token_type、actor_token、resource、requested_token_type 与标准响应语义。字段 actor 也是项目内字段,不等于标准 act 声明。我们使用它说明受众收窄和身份保留,不能据此声称与所有 OAuth Token Exchange 客户端兼容。

RFC 8693 为令牌交换提供通用框架,但授权服务器仍然需要决定哪些客户端可以交换哪些令牌、目标资源是什么、如何表达委托与模拟、是否允许嵌套 actor。使用成熟产品的标准端点,可以减少协议差异,却不会自动生成正确的业务授权政策。迁移时应先写清权利收窄规则,再映射到产品支持的交换能力。

一个具体失败案例是身份代理允许调用方传入 requested_subject,并因调用者是“内部可信服务”直接签发。Agent 只需要把文本中的用户名转换成管理员 subject,就获得管理员令牌。修复是让责任主体来自已经验证的上游凭据,并将任何代表他人的特权模拟能力单独建模、审批和审计,不能藏在通用委托接口里。

凭据生命周期需要和任务生命周期解耦

长任务可能运行十分钟,而业务凭据只活三十秒。正确做法不是无限延长令牌,而是在每次关键执行前重新确认授权并获取短凭据。排队消息应保存任务和授权引用,尽量不保存可直接使用的 bearer。任务恢复时重新检查主体状态和审批,不应让队列中的旧令牌成为离职用户的长期后门。

如果任务跨服务、跨地域或需要脱机执行,需要明确允许的撤权窗口。可以设计有范围的任务授权记录,并让执行器在业务提交前验证记录版本。真正离线的执行无法同时保证即时撤权;这个限制应作为产品与安全设计的事实公开,而不是用“短期令牌”模糊过去。

实验与检查

运行 go test -race -run 'TestSignedHTTPBoundaries|TestTenantScopeAndUntrustedToolInput|TestApprovalBindingsAndReplay' -v ./lab。观察原始令牌直达业务失败、只读 scope 退款失败、不同 actor 使用原审批失败。测试不会证明标准 token exchange 互操作性;它证明的是本书声明的收窄契约。

练习:选择一条现有工具链,列出每一跳必须看到的最小权限。如果下游只读一个订单,却收到“全租户全部资源”的令牌,说明收窄尚未发生。再设计父凭据到期、用户撤权和下游重试三种时序,写出每种情况下是否重新签发、是否重新审批和如何记录责任主体。

委托撤回与父子关系

如果业务凭据的有效期短于父凭据,但不在线检查父授权状态,父权限撤回后子凭据仍可活到自身到期。本书通过主体 epoch 让父子凭据共享撤权版本,缩短这个窗口。更复杂的系统可能需要单任务授权版本,避免撤销一个任务时影响同用户所有任务;也可能需要父授权记录关联,支持针对特定委托链撤回。

不要为了实现父子关系,把所有父令牌完整嵌进子令牌。这样会增加体积、暴露声明,并让存储和日志处理更危险。可以使用不可直接执行的授权引用,由受控服务保存关系;接收方在必要时查询。引用的可猜测性、访问控制和生命周期同样需要设计,不能把随机字符串本身当成全部授权。

实际产品选择 token exchange 时,应测试拒绝错误客户端、拒绝升级 scope、拒绝不允许的目标资源、父凭据到期和 actor 保留。只测一次交换成功,无法知道产品默认策略是否与你的业务一致。协议兼容证明能够交流,授权实验才证明交流后没有获得额外权利。