摘要
draft-ietf-wimse-http-signature-07用 Workload Identity Token 中cnf.jwk绑定的密钥,验证方法、路径、查询、受众、选定标头、内容摘要与签名参数。它认证的是一份请求表示,不是对操作的许可。- 本地 nonce 缓存未命中不等于集群从未处理;服务端打算签响应也不等于客户端能发现签名被剥离。身份、签名、新鲜度、授权、提交与业务结果必须分别留证。
一份请求,两套记忆
设想一项不可逆的自动化操作。请求到达节点 A 时,WIT 仍在有效期内,cnf.jwk 对应的公钥验证成功,Content-Digest 与收到的正文一致,wimse-aud 指向目标工作负载,nonce 也未在 A 的缓存中出现。A 接受请求并记录 nonce。
几秒后,同样的字节抵达节点 B。签名没有变坏,时间窗也没有关闭;但 B 的缓存与 A 分离,于是它同样得到“有效”和“未见过”。这不是密码学矛盾,而是状态拓扑。随后还有两道完全不同的问题:该主体能否执行这项操作?应用是否真的提交了状态变化?
2026 年 9 月 20 日提交的第 07 版 WIMSE HTTP 签名草案,把这个问题写得很直白。其页眉以 Standards Track 为目标,失效日期为 2027 年 3 月 24 日。它不是 RFC,而是一份仍在工作的 IETF 工作组 Internet-Draft;它不证明某个产品已经部署,也不提供采用率。附录中的实现条目只说明有人在运行代码上探索,不是生产普查。
签名覆盖的是重建后的表示
WIMSE 复用 RFC 9421。请求必须覆盖 @method、@path 与 @query。Content-Type、Content-Digest、Authorization、Txn-Token 和 Workload-Identity-Token 只要出现,也必须被覆盖。带正文的消息必须包含 Content-Digest,接收方还要以实际收到的正文重新计算并比较。
这一步阻止了一个常见偷换:只验证“摘要字符串被签过”,却不验证正文确实产生该摘要。RFC 9530 定义摘要字段的语义,WIMSE 要求把它重新接回消息内容。因此,完整凭证应包括重建的签名基、组件清单、摘要重算值与验证结论,而不是一条抽象的 signature_valid。
签名参数还包括 created、较短的 expires、随机 nonce 与标签 wimse-workload-to-workload;请求另带 wimse-aud。该配置不使用 HTTP Message Signatures 常见的 keyid 与 alg 参数,验证密钥和算法来自 WIT 的 cnf.jwk。即使如此,本地策略仍须判断该算法能否用于相应信任域。
同一消息若出现多个带 WIMSE 标签的签名,接收方必须拒绝,而不是挑一个方便的结果。否则,发送方、代理与应用可能各自以不同表示为准,却都声称验证了“那份签名”。
未被覆盖的字段不会因为邻近签名而自动获得完整性。代理重新签名产生的是另一个主体的另一份声明,不能追溯扩张原始签名的范围。
@authority 让位给受众
强制组件没有 @authority,因为终止 TLS 的代理与负载均衡器经常改写它。若要求端到端不变,协议会排除本来就要支持的部署路径。WIMSE 改为签入 wimse-aud,用逻辑受众绑定接收工作负载。
这并不意味着两个值可以随意互换。TLS 中按照 RFC 9525 验证的服务身份、某一跳看到的 HTTP authority、以及 WIMSE 的受众,是三张不同凭证。通道可以正确,受众匹配却过宽;请求签名可以正确,目标服务却因受众策略拒绝。
记录应保留客户端期待的服务名、证书给出的身份、TLS 终止点、发出的受众、接收方解释出的受众和最终交付对象。若系统只保留“已认证”,就无法知道代理在哪一步改写了控制面。
这里还存在一个容易被配置继承掩盖的问题:两个服务即使共用同一入口域名,也不必共享同一业务权限。wimse-aud 的匹配规则若只停留在网关级别,后端扩容、路径重写或多租户合并就可能让原本狭窄的身份获得更宽的可达面。每次变更都应重新证明“受众解析出的服务”与“授权检查所使用的资源边界”一致,而不是把旧网关的成功结果复制给新服务。
这份对应关系也应进入变更评审与回滚记录。
密钥持有者并不自动成为决策者
接收方先验证 WIT,再以其中绑定的公钥核验 HTTP 签名。成功意味着:在既定时间和策略条件下,持有相应私钥的一方形成了受覆盖的请求表示。
它不解释请求为何产生,不证明密钥只存在于一个活跃实例,也不把工作负载身份转换为业务角色。更关键的是,它不批准操作。
第 07 版明确把整个授权子系统放在范围之外,并把它当作可信前提。部署不能把这句话理解成“网关可把签名成功当授权”。正确分工是:认证层交付主体与请求;第一个能够阻止真实效果的组件,依据主体、动作、资源、上下文与策略版本作决定。
授权凭证应写明命中的规则、允许或拒绝、附加义务、例外路径与决策时间。若平台把某个信任域中的所有有效 WIT 都映射成宽泛角色,那份权力来自平台配置;需要审计的是配置、审批与变更历史,不是签名算法。
重放保护的单位不是一句开关
created 与 expires 缩短可接受窗口,却不能阻止窗口内第二次提交。nonce 提供识别材料,前提是某处记住第一次提交。草案允许接收方维护重放缓存,并建议拒绝已经见过的 nonce;同时,它没有要求多个验证器共享缓存,也因分布式同步困难而没有把严格防重放定为协议必达目标。
因此,“缓存未命中”的准确含义是:这个节点在自己的范围与保留期内没有该值。它不能证明其他节点、故障切换区域或更早的一代缓存从未处理,也不能证明应用未用另一请求标识提交同一业务动作。
对于幂等读取,本地缓存可能是合理权衡。对于扣款、证书签发、删除或控制指令,应用层往往还需要幂等键、唯一约束或提交账本。运维界面若只写“已启用重放保护”,却不说明缓存范围、保留时间、故障恢复行为与签名期限的关系,反而制造了过度确信。
响应签名必须由客户端提出
服务器可以主动签响应,但强保证来自请求方。客户端若需要签名响应,就把 wimse-sign-response=true 放进自己签名的请求参数。服务器无法签名时,不得用一份普通的成功响应蒙混过去;客户端收到无签名响应也必须拒绝。
每份签名响应都要包含 wimse-req-nonce,把请求 nonce 纳入响应的签名参数。这样验证的是“这份受覆盖的响应属于这次请求”,而不是服务器在相近时间随便签过一份响应。
若客户端没有提出要求,仅有服务端策略并不提供同样的删除防护。中间设备可以剥离签名,客户端仍必须接受普通响应。于是,“服务器配置为签名”描述能力;“客户端在签名请求中要求并验证了绑定 nonce 的响应”描述交易事实。
后者仍不等于最终结果。签名响应可能只表示异步任务已接收,真正执行可以稍后失败;业务结果需要另一条独立观察。
最后一次可信变换决定授权位置
HTTP 中间层会终止通道、规范字段、路由、解码,甚至重新签名。受覆盖的字段一旦修改,签名就失效;未覆盖字段仍可变化。关键问题不是冻结所有字节,而是找出哪些字段决定效果、谁可以改,以及授权发生时应用看到的究竟是哪一份表示。
若网关只授权“对 /jobs 发 POST”,后端却从未签名的标头决定租户或目标账户,那么决定发生得太早。更可靠的链路把入站签名结果、变换策略、出站签名主体、组件差异与后续授权连接起来。
由此形成六张凭证:WIT 及其密钥指纹;重建的签名与正文摘要;nonce、验证节点和缓存范围;主体、动作、资源与授权策略;幂等键和应用提交;独立观察到的业务结果。六者可以不一致:有效身份可带错误签名,有效签名可以是重放,新请求可以无权限,获准操作可以提交失败,成功提交也可能被补偿撤销。
保留这种不一致,不是系统割裂,而是责任可定位。实现附录、互通演示或采购表格只能证明声称的能力。真正评价运行代码,需要请求捕获、签名基、WIT 结论、缓存拓扑、授权日志和提交记录。未来草案还可能变化,所以架构决定还应固定版本并记录本地偏离。
来源
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
