摘要
draft-mcguinness-oauth-client-attesters-00建议用client_attesters元数据列出可为某个client_id作证的证明者及其 JWK Set 位置;第 00 版仍是个人互联网草案,不是 RFC 或 IETF 已采纳标准。- 发布者认可与授权服务器信任是两道独立同意:前者限定“谁可以作证”,后者决定“是否相信、从哪里取验证密钥”。任何一方都不能替代另一方。
- 删除认可项只会在缓存收敛后阻止未来认证,不会自动撤销已发放的 grant 或 token,也不会影响自行验证证明的资源服务器。
凌晨的处置会上,安全团队看到三个彼此冲突的状态:客户端网站已经删掉某个证明者,授权服务器仍在使用尚未过期的缓存,一枚此前签发的 access token 仍能访问业务 API。面板上“认可已撤回”是事实,“访问已终止”却不是事实。真正的问题不是哪盏灯错了,而是系统把四种不同权力压缩成了一盏灯。
《OAuth 2.0 Client Attester Endorsement》试图补上一个明确缺口。ATTEST 能规定 Client Attester 如何对 Client Instance 及其持有的密钥作出签名声明,却没有规定授权服务器如何知道这个证明者有权替特定客户端说话。新草案把这层关系放进权威客户端元数据:client_attesters 数组中的每项包含精确的 issuer 与 HTTPS jwks_uri。
这份记录表达的是发布者意图。它不是信任锚,不是客户端凭证,不是用户授权,也不是资源访问许可。证明者被列入名单,只获得“可被考虑”的资格。
一项认证必须得到两种主体的同意
草案要求同时满足两个条件。第一,针对请求中 client_id 选定的权威元数据,当前必须认可 attestation 的 iss。第二,授权服务器自己的策略必须允许该证明者为这个客户端作证,并决定验证密钥如何获得信任。
发布者不能靠写入名单强迫授权服务器信任某个证明者;授权服务器也不能因为平时信任某个证明者,就替没有认可它的客户端补上关系。在该 profile 生效的请求中,授权服务器可以缩小发布名单,不能把名单扩大。
这种双重同意保护了权力的复数性。客户端发布者管理自己的代理关系,授权服务器保留安全门槛,证明者只对实例事实负责,grant policy 再独立决定访问。若界面只显示“签名有效”,前两层权力都会被加密结果借走。
两种密钥来源策略带来不同保证
在 publisher-authorized key selection 模式下,授权服务器事先允许某个发布者选择证明者及其密钥来源。此时 jwks_uri 真正提供 JWK Set。它适合一个授权服务器面对大量独立客户端的场景,但保证上限就是发布者本身:发布者或 CIMD 主机一旦被控制,攻击者可以同时选择证明者与密钥服务。即使声明写着“硬件完整性”,也不因此获得独立于发布者的可信度。
在 AS-configured attester trust 模式下,授权服务器为精确 issuer 独立配置密钥来源。认可项中的 jwks_uri 只能与配置值或显式 alias 比较,不能被读取来覆盖配置。两边不一致时必须失败,不能默认相信发布者,也不能悄悄用服务器配置替发布者修正。
优先级规则扩大了变更半径:只要某个精确 issuer 曾被授权服务器为任何客户端配置,该模式就对所有引用此 issuer 的客户端生效。删除配置也不会自动把选择权交给发布者;运营者必须另作决定。一次看似属于单个租户的 alias 或密钥源调整,可能实际改变整个 issuer 的验证路径。
验证顺序是防止权力串位的结构
授权服务器先根据注册或发现策略,为请求中的 client_id 选择唯一权威元数据源。它不能把注册数据与可访问的 CIMD 合并,也不能因认可验证失败而换一个来源重试。随后匹配唯一的 issuer == iss 项,检查客户端到证明者的策略,选择密钥来源,再把 kid 解析成恰好一把合格的非对称公钥。
真正的绑定包含客户端标识、issuer、密钥来源与信任策略四部分。kid 自身不是全局身份,把多个来源的密钥并成一个集合也不合格。该 profile 会忽略 attestation 自带的 jku、x5u、x5c 与 jwk 选钥提示,之后才验证签名、sub == client_id、其余 attestation 字段与持钥证明。
最后一步仍不是授权完成。grant 与资源策略必须另行评估。证明“这是被认可证明者认可的实例”与决定“它能读取哪个资源、执行哪项业务”是两个问题。
撤回不是一个瞬间,而是四只时钟
发布者删除认可项后,授权服务器可以继续使用未过期的缓存。草案要求设置有限最大缓存年龄,却不规定统一上限,所以发布者无法仅凭协议推算何时完全失效。明确的时间界限必须写进 trust agreement 并接受演练。
若服务器实际观察到 CIMD 或 JWK Set 返回 404 或 410,就必须停止使用此前缓存;timeout 或 5xx 不会使仍在新鲜期内的缓存自动失效。正在依赖缓存的服务器甚至看不见远端删除。
换钥还需要重叠窗口:先发布新钥匙,等待 JWK Set 缓存寿命,再开始签名;旧钥匙要保留到用它签发的证明全部过期。换 URL 还要等待客户端元数据刷新。在 AS-configured 模式下,授权服务器还需接受新的配置或 alias。
第四只时钟属于已发放权限。删除 endorsement 只影响未来认证,不撤销既有 grant、access token 或 refresh token。真正的“终止访问”要另行撤销 grant 与 token,阻止刷新,让 introspection 返回 inactive,并处理本地验证 token 的资源服务器直到 token 过期。
还有一类系统根本不在此撤回链上:直接接收 Client Attestation 的资源服务器依赖自己的配置。草案不要求它发现客户端认可名单。因此,授权服务器侧删除元数据不会影响它。资产清单若没有标出 direct validation,撤回报告就是不完整的。
决策收据应记录谁授权了哪一步
一份可审计的收据首先记录 client_id、唯一元数据来源、内容哈希、获取时间、缓存状态和到期点;随后保存精确 endorsement,以及发布者为何有权设置它。接着记录授权服务器采用哪种选钥策略、为何该策略优先、配置来源或发布者来源、alias、JWK Set 哈希与新鲜度、唯一 kid、算法和公钥。
收据还要写明 attestation 在该 endpoint 是必需还是可选。发布 client_attesters 本身并不会强制客户端提交 attestation;如果它只是另一种认证方式旁的可选信号,策略可能在证明失败后继续处理请求。
签名与持钥验证之后,收据单独记录 grant 结论。撤回时追加:首次观察删除的时间、缓存收敛、最后一次接受、证明到期、token 撤销、刷新拒绝、introspection 状态、离线验证窗口和已检查的 direct validator。这是 Daniel Kade 提出的运营模型,不是草案规范文字。
对外错误仍应保持含糊。invalid_client_attestation 不应泄露是名单缺失、发布者无权选钥、来源冲突、kid 歧义还是暂时抓取失败。客户端不能靠不断重发新证明解决策略冲突。内部遥测必须保留精确原因,线上协议则保留最小披露。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
