摘要

  • 9 月 1 日,IESG 对 SD-JWT VC 第 19 版启动 IETF 范围 Last Call。OAuth 工作组请求把它发布为 Proposed Standard,评论截止日为 9 月 15 日;目前没有批准决定。
  • 草案用必填的 vct 标识主要凭证类型;发行者可用 aka_vcts 声明其他类型;Type Metadata 则可用 extends 建立继承链。
  • 这些机制可以复用规则、完成类型匹配,却不能证明发行者有权发行已知类型。草案要求另行核验发行者身份、信任状态及适用的认证或登记。
  • Type Metadata 发布者也有独立的权威问题。文档能被取回、哈希一致,不等于发布者有权定义这个类型。
  • 各生态可以在格式之外维护一份精简的“授权回执”,分别连接发行者与元数据发布者的权力来源,而不要求 IETF 建立全球信任名录。

Last Call 检查的是草案,不是宣布结果

9 月 1 日的 IETF 公告把 draft-ietf-oauth-sd-jwt-vc-19 送入全社区 Last Call。OAuth 工作组请求将其列为 Proposed Standard。评论窗口到 9 月 15 日结束。证据截止时,Datatracker 仍显示“In Last Call”,没有 IESG telechat 日期,IANA review 仍待完成。

这个程序状态必须保留。IESG 的公开指引把 Last Call 描述为通常情况下最后一次开放社区审查;它不是批准仪式,也不是未来 RFC 的发布日期。现在能够确认的,是草案的文本和审查入口,而不是它最终会以何种内容通过。

技术底座是 RFC 9901。发行者对 JSON 载荷签名,其中一部分声明可以保持明文,另一部分以摘要表示,持有者在出示时自行选择披露哪些内容。验证者检查发行者签名、披露项摘要,并在政策要求时检查持有者的密钥绑定。SD-JWT VC 在此之上补充数字凭证的数据格式、验证与处理规则。

每张凭证必须带一个区分大小写、抗碰撞的 vct。它让软件知道自己面对何种凭证,应适用哪些声明和选择披露规则。不过,草案没有定义任何具体 vct 值。具体语义,以及格式之外的发行、验证政策,都交给采用它的生态。

这不是遗漏,而是边界。IETF 格式不应替各国决定谁能签发身份证件,也不应替大学、行业协会或雇主决定谁能授予资格。共同格式解决“怎样表达和验证”;机构授权解决“谁有权作出这种表达”。

extends 与 aka_vcts 能连接类型

第 19 版提供两种不同的类型连接方式。Type Metadata 中的 extends 允许一个类型继承另一个类型。处理者先读取上层类型,再应用下层的扩展。子类型可以补充或覆盖部分显示信息与声明元数据,但不能把上层标记为必填的声明改成可选,也不能反转上层已经确定的选择披露约束。

这种继承有实际价值。一个地方性或行业性子类型无需复制一整套公共规则,验证者也能沿链条复原约束来源。

aka_vcts 则写在凭证内,由发行者自己声明。它是一个可选的附加类型列表,可让验证者在请求通用类型而收到更具体凭证时完成匹配。它不依赖 Type Metadata 是否存在;列表顺序没有意义;所列类型也不必通过 extends 相连。第 18 版引入这个字段,第 19 版进一步解释它与 Type Metadata 的关系。

两种机制都在回答“这张凭证宣称属于哪些类型”。它们没有回答“谁允许这个发行者发行这些类型”。草案专门警告,攻击者可以模仿或继承一个合法类型。持有者和验证者不得只因类型层级看起来熟悉就接受凭证,必须独立核验发行者身份、信任状态以及相关认证或名录记录。aka_vcts 只是发行者断言,其可信程度不会高于发行者本身。

因此,“类型被识别”和“发行者获授权”应成为两个独立的结果。若钱包界面把二者压成一个绿色对勾,格式里最重要的治理分隔就会在产品层消失。

元数据背后还有第二条授权边

草案还定义了 Publisher,即发布 Type Metadata 或其他辅助文档的主体。它可能是标准组织、社区或生态权威,也可能是其他定义凭证类型的机构;它不一定就是凭证发行者。

发布者可以说明类型名称、显示方式、声明结构和 extends 关系。验证者也可以通过 HTTPS 获取文档,并用完整性信息确认内容没有在途中被替换。但“取回成功”和“哈希一致”只说明传输与版本,没有回答发布者为何有权定义这个类型。

第 7.8 节因此要求:除非消费者承认发布者对该类型具有权威,否则不得假定 Type Metadata 准确或有意义。草案还建议,各生态应明确治理或认证机制,写清哪些发布者可以为哪些凭证类型提供元数据,以及在什么条件下可以依赖。

由此产生两条独立的授权边。第一条把发行者连接到发行许可、登记、法律、合同或信任名单;第二条把元数据发布者连接到其定义或描述类型的权威来源。实践中可能由同一机构持有两种资格,但两项资格仍应分别记录,因为它们的范围、期限和撤销机制未必相同。

有效签名证明控制密钥,不证明取得委任

草案对密码学验证的要求很严格。验证者必须使用适用政策允许的发现与验证方法,确认签名密钥属于所声称的发行者;无法确认就应拒绝凭证。这项检查回答的是:在当前方法与密钥材料下,谁控制了保护这些数据的签名密钥?

授权问题并不会随之消失。一个主体完全可以真实地控制自己的密钥,却没有资格发行某国证件。一个未获认可的发布者也能提供内部一致的 Type Metadata。完整性哈希甚至可以非常准确地保存一份未经授权的文档。密码学使断言及来源可核验,却不会创造断言背后的制度权力。

Heng Lu 所说的“委任清洗”正发生在这种跳跃中:技术或机构外壳被当成它本来只应引用的权力来源。对普通用户而言,跳跃往往只有三步——熟悉的类型、正确的签名、“已验证”的徽标。若最后一个词没有说明究竟核验了密钥、类型还是授权,界面就制造了一条不存在的委任链。

第 19 版的价值,是用规范性语言阻止这种推断。部署者下一步要做的,是让停止线在日志、政策和用户界面中仍然可见。

给接受决定配一份授权回执

无需另造一套全球名录。每个采用 SD-JWT VC 的生态,都可以为它接受的“发行者—类型”组合维护一份版本化的授权回执。

回执首先记录本次处理的精确 vct、被政策接受的 aka_vcts 以及完整 extends 链。随后记录发行者标识、密钥发现与验证方法,以及真正授权其发行的外部依据:名录条目、认证决定、法律条款、合同或信任名单记录。

另一组字段单独记录 Type Metadata 发布者、文档版本和完整性引用,再列出发布者对该类型具有权威的来源。最后加上适用生态或司法范围、有效期、验证者政策版本、决策时间,以及一条明确的“非结论”:签名有效、类型匹配、别名存在、继承成功或元数据完整,都不能单独证明机构授权。

回执还应区分不同失败状态。“未检查”“未找到”“已过期”“超出范围”和“已确认无授权”不是同义词。缺少公开回执并不能反证某个发行者违法或无权。

这份回执是本文的编辑建议,不是第 19 版内容。它不改写凭证载荷,只把草案有意留给外部政策的决定保留下来。

把治理放在生态层,而不是塞回线格式

最有力的反对意见是:政府证件、职业资格、校园凭证和私人会员体系的授权结构差异巨大。若把这些规则写进一个 IETF 格式,全球互通将反而依赖新的中心机构,OAuth 工作组也会越过技术职责。

这个反对意见是成立的。授权回执应属于生态配置、验证政策、钱包信任设置或方案名录。IETF 需要维护共同的表达、处理规则和清晰边界,不需要成为“发行者的发行者”。aka_vcts 仍可在没有 Type Metadata 时帮助匹配,extends 仍可避免规则复制;只是每项机制都必须停在它能证明的命题上。

隐私同样不能被治理补丁破坏。vct 和 aka_vcts 不能选择性隐藏,可能泄露凭证上下文。草案还指出,如果发行者为每个持有者设置不同标识,而验证者又为取得密钥材料向发行者发起请求,恶意发行者就可能知道凭证在哪里、以何频率出示。授权回执应绑定稳定的发行者—类型组合,支持缓存或固定,不应在每次出示时用持有者专属标识回访发行者。

来源

  1. IETF — SD-JWT VC 第 19 版 Last Call
  2. IETF Datatracker — SD-JWT VC 文档记录
  3. IETF Internet-Draft — SD-JWT VC 第 19 版
  4. RFC 9901 — Selective Disclosure for JSON Web Tokens
  5. IESG — Last Call 社区指引
  6. IETF — OAuth 工作组章程
  7. Heng Lu — Mandate Laundering