VCALM v1.0

用于生命周期管理的可验证凭证 API

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-vcalm-1.0-20260630/
最新发布版本:
https://www.w3.org/TR/vcalm-1.0/
最新编辑草案:
https://w3c.github.io/vcalm/
历史:
https://www.w3.org/standards/history/vcalm-1.0/
提交历史
编辑:
Patrick St. Louis (Open Security and Identity)
Kayode Ezike (Gobekli)
Manu Sporny (Digital Bazaar)
Ted Thibodeau Jr (OpenLink Software)
作者:
Dave Longley (Digital Bazaar)
Joe Andrieu (Legendary Requirements)
Markus Sabadello (Danube Tech)
Kayode Ezike (Gobekli)
Nate Otto (Skybridge Skills)
Eric Schuh (Legendary Requirements)
Patrick St. Louis (Open Security and Identity)
反馈:
GitHub w3c/vcalm (拉取请求新议题未关闭议题)
public-vc-wg@w3.org 主题行请使用 [vcalm-1.0] … 消息主题 …归档
会议:
查看下一场 已安排的会议

摘要

可验证凭证提供了一种在 Web 上表达凭证的机制, 这种方式具有加密安全性、尊重隐私, 并且可由机器验证。本规范提供了数据模型和 HTTP 协议,用于签发、验证、出示和管理此类 生态系统中使用的数据。

本文档状态

本节描述本文档在发布时的状态。 当前 W3C 出版物列表以及本技术报告的最新修订版可在 W3C 标准和草案 索引中找到。

本规范正在积极开发中。除非你正在参加每周会议, 以协调围绕本规范开展的活动,否则不建议在生产系统中部署。

本文档由 可验证凭证工作组作为 工作草案发布,使用 推荐标准 轨道

作为 工作草案发布并不意味着 获得 W3C 及其成员的认可。

这是一个草案文档,可能随时被其他 文档更新、替换或废弃。除了将其作为正在进行中的工作引用之外, 不宜以其他方式引用本文档。

本文档由一个在 W3C 专利 政策下运作的工作组产出。 W3C 维护着一份 与该工作组交付物相关的任何专利披露的公开列表; 该页面还包含 披露专利的说明。任何实际 知晓某项专利,并且认为该专利包含 必要权利要求的个人, 必须按照 W3C 专利政策第 6 节 披露相关信息。

本文档受 2025 年 8 月 18 日 W3C 流程文档管辖。

1. 引言

本节为非规范性内容。

可验证凭证规范 [VC-DATA-MODEL-2.0] 提供了一种数据 模型和序列化方式,用于以加密安全、尊重隐私且 可由机器验证的方式表达数字凭证。本 规范提供了一组 HTTP 应用程序编程接口(HTTP API)和协议,用于签发、验证、出示和管理可验证 凭证。

在管理 可验证凭证时, 通常会考虑两大类 API。 第一类 API 设计为在 单一安全域内使用。第二类 API 可用于 跨不同安全域进行通信。本规范定义了 这两类 API。

设计为在单一安全域内使用的 API,由代表 某一单一角色运行的系统使用,例如签发者验证者持有者。这些 API 对可验证凭证生态系统的一个 好处是,它们为管理可验证凭证定义了一种有用、通用且 经过审查的模块化架构。例如,这种方法有助于软件 架构师与通用组件集成,并在实现签发 可验证凭证的系统时使用共同语言。 对于并不专门从事可验证凭证工作的架构师来说, 知道某个特定架构已经过审查也很有益。文档化的架构和 API 能增加市场竞争,并降低供应商锁定和迁移 成本。

设计为跨多个安全域运行的 API, 由在可验证 凭证交互中两个不同角色之间进行通信的系统使用, 例如用于在持有者验证者之间 传达表达的 API。为了在可验证凭证 交互中 实现协议互操作性,对这些 API 进行标准化至关重要。 文档化这些 API 的额外好处与文档化 单一安全域 API 相同:通用且经过审查的架构和 API、更高的 市场竞争,以及更低的供应商锁定和迁移成本。

本规范包含以下软件架构师 和实现者可能会觉得有用的章节:

1.1 设计目标和原理

本节为非规范性内容。

可验证凭证 API 针对以下设计目标进行了优化:

目标 描述
模块化 实现者只需实现其用例所需的 API, 从而在签发、验证和出示之间实现模块化。
简单性 API 数量和可选性保持在最低限度,以确保它们 易于从安全角度实现和审计。
可组合性 API 被设计为可组合的,使复杂流程能够 通过少量简单的 API 原语实现。
可扩展性 API 设计预期并支持对 API 端点的扩展, 以便在基础 API 平台之上进行实验并添加增值 服务。

HTTP API 设计指南

本规范以 RESTful API 方法为基础。 某些端点使用所谓的 “controller”资源命名风格。JSON Schema:用于描述 JSON 文档的媒体类型用于定义 API 可接受的输入。

1.2 架构概述

本节为非规范性内容。

可验证凭证数据模型定义了三个基本角色: 签发者验证者持有者


显示签发者、持有者和验证者这些可验证凭证角色的图示
1 可验证凭证数据模型规范定义的角色。

履行这些角色的行为者可以使用若干软件或服务 组件来实现用于交换可验证凭证的 API。

每个角色都关联一个特定于角色的 Coordinator、Service 和 Admin, 以及其自己的专用 Storage Service。此外,签发者还可以 管理由该签发者签发的可撤销凭证的 Status Service。

签发者、验证者和持有者的 Coordinator、Service 和 Admin 的 API 组件
2 API 组件。箭头表示流程的发起。

任一给定实现可以选择将任意或全部这些 组件组合成一个单一的功能性应用。这些组件之间的边界和接口 在本规范中定义,以确保整个可验证凭证 一致性生态系统的互操作性和可替换性。

议题 1: 标准化架构至关重要;组件标准次之

基于这种架构思考,我们可能希望将此 API 描述为一份 相关规范路线图,以可扩展方式集成,从而获得最大的 可替换性。若干技术,例如 EDV 和 WebKMS,可能会从用于可验证 凭证证明的密码套件方法中 受益。定义一种可由任何功能上一致的技术实现的通用 机制,可以在以现有当前功能奠定基础的同时实现 灵活性。通过这种方式,我们也许能够承认 Key Services、 Storage 和 Status 等元素是此 API 的必要部分,同时将 这些元素如何工作的定义推迟给已在开发中的规范, 以及尚待编写的规范。

除了将组件聚合到单个应用中,实现者还可以选择 在任意数量的已部署软件活动实例上运行任一给定角色。 例如,基于浏览器的持有者 协调器应被视为 一个 Web 浏览器、运行在该浏览器中的各种代码、一个或 多个 Web 服务器(在跨源 AJAX 或远程嵌入内容的情况下), 以及运行在该服务器上的代码的组合体。这些元素分别作为不同 配置中的不同软件包运行,各自只执行该组件 整体功能的一部分。就此 API 而言,每个 组件作为整体满足其所有必需功能,无论其 部署架构如何。

1.3 一致性

除标记为非规范性的章节外,本规范中的所有编写指南、图示、示例和注释 均为非规范性内容。本规范中的其他所有内容均为规范性内容。

本文档中的关键词 MAYMUSTMUST NOTOPTIONALRECOMMENDEDREQUIREDSHOULDSHOULD NOT 在且仅在它们如这里所示全部以大写形式出现时, 应按照 BCP 14 [RFC2119] [RFC8174] 中所述进行解释。

一致的签发者服务实现MUST 提供 第 3.2.1 签发凭证节所述的接口。第 3.2 签发节中描述的其他接口也MAY被提供。

一致的验证者服务实现MUST 提供 第 3.3.1 验证凭证节和第 3.3.2 验证表达节所述的 接口。第 3.3 验证节中描述的其他接口也MAY被提供。

一致的持有者服务实现MUST 提供 第 3.6.4 获取交换协议节和第 3.6.5 参与交换节所述的 接口。对第 3.7 发起交互节、第 3.4 请求表达节、第 3.5.2 创建表达节、第 3.5 出示节,以及第 3.6 工作流和交换节中描述的协议、查询语言 和数据格式的一致性也MAY 被提供。

一致的状态服务实现MUST 提供 第 C.3 更新状态节所述的接口。

一致的工作流服务实现MUST 提供 第 3.6 工作流和交换节中的所有 接口。

一致的服务客户端实现MUST 提供 与相应服务实现所提供的所有REQUIRED接口 进行通信的手段。也就是说, 状态客户端实现提供与状态服务实现所暴露的所有强制接口 进行通信的手段。

所有实现都MAY提供超出本规范的功能。

1.4 术语

本节为非规范性内容。

本文档全文使用的术语定义在 可验证凭证数据模型 v2.0 规范的 术语章节中。

2. 架构

这些软件组件的一种可能架构由下面的 架构说明以及1.2 架构概述一节中的图示表示。选择这些表示形式 是为了清楚地对规范中的不同功能进行分类, 使每个组件都可以被独立对待,既便于阅读上的清晰性, 也强调每个组件可以独立于任何其他组件实现。 但是,这并不是一种规定性架构;实现者可以根据需要使用 任意多或任意少的软件包来服务多个角色;角色并不 要求由单个库或其他软件包来服务,软件库或软件包也不 要求只为特定角色单独提供功能。 还可以预期,软件或系统组件的单次部署可以根据 给定用例的需要用于多个角色。

2.1 协调器

协调器执行相关角色所设定的业务规则和策略。 这通常是专为扮演该角色的单一方开发的自定义或专有 协调器; 它是将控制方连接到可验证凭证 生态系统的集成胶水。

协调器可以根据 实现提供可视化用户界面。纯命令行或持续运行的服务也可以 实现此组件。

状态服务外,所有角色到角色的 通信都发生在代表其特定行为者行事以履行其 角色的协调器之间。

签发者协调器执行关于谁 获得哪些凭证的规则,包括创建或接收这些凭证的各方 如何被认证和授权。通常,签发者 协调器签发者的后端系统与签发者服务集成。这种 集成使用任何适当的技术;签发者协调器和后端服务之间的接口 不在本规范范围内。签发者协调器驱动签发者服务

验证者 协调器验证者 服务通信,以 首先检查给定可验证凭证可验证 表达的真实性和时效性,然后应用验证者的业务规则, 最终接受或拒绝该可验证凭证可验证 表达。这类业务规则可能包括评估 特定声明的签发者, 或仅检查配置的允许列表。验证者协调器公开一个 API,用于按照 验证者的策略向 验证者 提交可验证凭证。 例如,验证者协调器可能只接受来自 验证者其他服务的当前用户的 可验证凭证。这些 规则通常需要与验证者现有后端进行定制集成。

持有者 协调器执行用于批准在持有者控制下的 凭证流动的业务规则,从签发者验证者。 在某些部署中,这意味着公开一个用户界面, 使各个持有者能够以可视化方式授权或 批准可验证凭证 的存储或传输。持有者 协调器的某些功能通常称为数字钱包。在此 API 中,持有者协调器发起所有流程。它们从 签发者请求可验证凭证。 它们决定是否以及何时与验证者共享这些 可验证凭证。 在此 API 中,签发者验证者均无法 发起 可验证凭证的传输。 在许多场景中,持有者协调器预期 由个体人类控制,以确保有人直接参与可验证 凭证的通信,即便 只是在授权传输这一步参与。不过,有些可验证凭证 关于的是组织,而非个人。使用与组织相关的 持有者协调器的个人如何操作,尤其是 组织凭证如何安全地与这些组织的(法律)代理人共享并由其出示, 不在本规范范围内。

2.2 服务

服务提供 由其关联的协调器驱动的较低层级 API 功能, 并设计为使基础设施提供商能够通过 软件即服务等服务交付架构提供可验证凭证 能力。所有服务都会向其授权的协调器公开 HTTP 端点, 而这些协调器本身代表关联角色运行。尽管已部署的服务 可能提供其自己的 HTML 界面,但此类界面不在本规范范围内。 本文仅定义服务的 HTTP 端点。

签发者 服务接收来自授权签发者协调器的签发可验证凭证 请求,并返回一致的可验证 凭证。该服务可以访问密码材料,例如 私钥或利用私钥的密钥服务,以便为可验证 凭证创建证明。签发者服务 与其关联的密码密钥管理服务之间的 API 不在本 规范范围内。

验证者服务接收验证可验证凭证可验证 表达的请求,并返回 检查其证明和状态(若存在)的结果。该服务只检查 可验证凭证的真实性和时效性, 将任何必要业务规则的最终应用留给 验证者协调器完成。

持有者 服务接收从一组可选的可验证凭证 创建 Verifiable Presentations 的请求, 并返回格式良好、已签名且包含这些 VC 的 Verifiable Presentations。这些可验证 表达签发者一起使用, 用于在可验证凭证 签发之前证明对 DID 的控制,也与验证者一起使用,以出示 特定 VC。

状态 服务提供一种保护隐私的方式,用于发布 和检查签发者签发的任何 Verifiable Credentials 的状态。 鼓励验证者服务的实现者通过参考可验证凭证所使用的相应状态 规范,理解检查状态的隐私 影响。关于管理可验证凭证 状态的具体机制,建议参考 知名外部规范,例如 [VC-BITSTRING-STATUS-LIST]。

存储服务由系统中的每个行为者使用, 按需存储其自己的可验证凭证 和相应数据。若干已知 实现使用安全数据存储,例如加密数据保管库, 来存储持有者可验证凭证, 并使用加密授权按照持有者的指示, 授予验证者协调器访问 这些可验证凭证的权限。 在浏览器内 检索这类已存储凭证,可以使基于 Web 的验证者协调器持有者处集成数据,而无需 与验证者共享该数据——该数据只会 出现在浏览器中。授权第三方远程访问持有者存储很可能属于此 API 的范围, 尽管我们预计这将使用可扩展机制来定义,以支持 各种存储和授权方法。

签发者验证者 存储解决方案可以使用也可以不使用安全数据 存储。由于所有这类存储交互都由定制的签发者 和 Storage Coordinators 调解,任何必要集成都可以只是该 定制化的一部分。我们预计不同实现会在 易于集成到各种后端存储平台方面展开竞争。

工作流 服务为协调器提供一种方式,用于为特定用户自动化 特定交互。每个角色(持有者签发者验证者)都可以 运行自己的工作流服务,用于创建和管理实现 特定工作流的交换。管理员配置工作流系统以 支持特定流程。然后,当业务规则证明其合理时,协调器 在其工作流服务处创建交换,并向任何授权方授予 访问这些交换的权限。

管理服务承认每个其他 组件都需要某种方式来配置和管理,而不规定 该配置的接口或手段。某些组件可能使用 JSON 文件 来驱动命令行界面。其他组件可能公开 HTML 页面。可以 预期,不同实现将在其管理的能力、易用性和 灵活性方面展开竞争,因此,配置在很大程度上不在 本规范范围内。有些地方提供了一些配置 机制,例如第 3.6.1 创建 工作流节,其中 对标准化一些配置参数有广泛共识。随着市场 成熟,其他配置标准化领域可能会在本规范未来 版本中出现。

2.3 实例

本规范定义的 API 假定它们附加到一个 具有相关配置的特定实例上,该配置已由系统管理员 放置就绪。当客户端调用某个特定实例上的端点时,实例使用客户端提供的 配置和选项 来执行该操作。

例如,/credentials/issue 端点可以提供在 更长 URL 的末尾,例如 /instances/12345/credentials/issue。在这种情况下,是 实例被配置为知道应使用哪个密码密钥进行 签发、是否涉及状态列表、要签发的凭证类型、凭证格式, 以及端点上可能有哪些附加选项。

调用特定实例的软件客户端可能没有 配置实例的能力,也可能不了解管理员在该实例上所做的设置, 除了适当使用它所需的必要细节之外。 用于配置实例的管理端点 可以由实现提供,但不一定作为 HTTP API 暴露;配置也可以通过配置文件或图形 界面完成。

:协调器 可以使用多个服务实例

协调器实例可以访问多个服务实例,以 支持不同用例或具有复杂流程的用例。服务实例配置的 运行时发现不由本规范定义,因为 服务预期在部署时已为协调器所知。

2.4 配置

每个协调器服务实例都与 驱动其行为的特定配置相关联。本节包含 其中一些配置可能如何执行的说明。

基准 URL

对任一特定实例的基准 URL 不施加限制。 本规范全文使用的 URL 路径以绝对路径显示, 其基准 URL MAY 是服务器的主机名(例如 website.example)、子域名(例如 api.website.example),或 该域内的路径(例如 website.example/api)。

授权

此 API 可以部署在多种网络环境中,其中可能 包含敌对行为者。因此,一致的服务实现要求 一致的服务客户端 实现在执行某些类型的请求时使用安全授权 技术。本文档中定义的每个 HTTP 端点都规定了 执行请求时是否需要授权。除本节稍后讨论的 被禁止授权协议类别之外,此 API 对 授权机制保持不可知。

此 API 旨在成为通用且可用于许多需要 签发、持有、出示和/或验证 Verifiable Credentials 的场景。为此,建议实现者考虑以下 用例分类:

  • 公开。公开 API 是无需授权即可调用的 API。 示例包括开放见证或时间戳服务(能够 为审计追踪目的使用时间戳对消息进行数字签名的可信服务),或 开放零售优惠券端点(“买一送一”)。公开验证者也 可能存在,用于在信任场景中充当不可知第三方。
  • 许可型。许可型授权要求进行 API 调用的实体例如拥有访问控制令牌或能力 URL,或 从相互信任的来源调用某项能力。这些权限授予 对 API 的访问,但不对凭证主体、先前 交互或类似事项作任何假设。许可型访问在 基于服务到服务的工作流中特别有用,其中凭证主体并不直接 参与。
  • 绑定型。绑定型授权涉及这样的场景:API 调用 与另一个通常是带外的流程紧密耦合、链接或绑定, 而该流程已经认证了 API 交互的持有者/主体。这些用例 包括但不限于,将特定于主体的身份声明 直接签发给相关主体,或验证凭证以使 持有者获得验证者服务资格。将一个通道上的 活动绑定到 API 调用的方法示例包括 CHAPICredential Handler API)、OIDC(OpenID Connect) 和 GNAP(Grant Negotiation and Authorization Protocol)。实现 绑定型授权的开发者需要采取步骤,确保 在流程中达到适当的保证级别,以正确保护该 绑定。

本节其余部分给出了已被考虑用于一致实现的授权技术示例。 其他等效的授权技术也可以使用。实现者应谨慎, 避免使用非标准或遗留授权技术。

被禁止的授权

对此 API 的请求MUST NOT使用任何在 请求中包含长期静态凭据(例如用户名和密码或类似值)的授权协议。 这种被禁止协议的一个示例是 HTTP Basic Authentication [RFC7617]。

OAuth 2.0

如果 OAuth 2.0 Authorization Framework [RFC6749] 用于 授权, 客户端使用的访问令牌MAY是 OAuth 2.0 Bearer Tokens [RFC6750],或 任何其他有效的 OAuth 2.0 令牌类型。任何有效的 OAuth 2.0 授权类型 都MAY用于 请求访问令牌。

VCALM OAuth 2.0 作用域语法
scope = operation ":" path-absolute(定义于 [RFC3986])
operation = "read" / "write"

read 操作使系统中不创建或更新资源的操作 能够在所提供路径上执行,或在任何以所提供路径为前缀的路径上执行。 write 操作使在系统中创建 和/或更新资源的操作能够在所提供路径上执行,或 在任何以所提供路径为前缀的路径上执行。

OAuth 2.0 作用域示例如下:

  • read:/ 将允许通过任意特定实例上的任何 API 进行读取。
  • write:/ 将允许通过任意特定实例上的任何 API 进行创建和修改。
  • read:/exchanges 将允许从任意特定 工作流实例读取交换。
  • write:/credentials/issue 将允许写入任意特定签发者实例上的凭证签发 API。

宽泛的 OAuth 2.0 作用域,例如 read:/write:/, 在多租户环境中可能导致安全漏洞,例如当多个签发者协调器可能使用托管在同一 签发者服务上的不同签发者 实例时。 建议实现者确保 表示为 JSON Web Tokens 的访问令牌包含 aud(audience)声明, 该声明标识访问令牌适用的特定实例,从而允许将访问 令牌固定到某个特定实例。建议 OAuth 2.0 作用域尽可能 保持狭窄,同时不要给安全 管理员造成过重负担。

选项

以下章节定义的一些端点接受 options 对象。在配置 每个实例时,options 对象的所有属性均为OPTIONAL, 因为这些属性旨在满足可能因部署而异的部署级需求。 因此,任一给定实例配置MAY禁止客户端使用 某些 options 属性,以防止客户端向该实例传递某些 数据。同样,实例配置MAY要求 客户端包含某些 options 属性。

实现MAY用附加属性扩展 options 对象。

由于扩展属性是特定于实现的,因此它们不应是 强制性的。这是为了通过避免客户端需要 修改才能使用特定实现来保持互操作性。

添加扩展 options 属性时,请考虑 是否有必要向客户端提供可选性。如果没有,使用实例配置来 改变 API 功能可能是一种更可取的方法。

如果端点接收到它不理解或不知道如何处理的数据、选项 或选项值,实现MUST抛出错误。

内容序列化

发送到本规范所定义 API 端点或从这些端点接收的 请求和响应中的所有实体主体MUST序列化为 JSON,并且 包含 Content-Type 标头,其媒体类型值为 application/json

载荷大小

鼓励实现者关注其实现所处理的 Verifiable Credentials 的载荷大小。

表达可以捆绑大量凭证,这可能导致 请求大小高于实现者预期。这会增加 互操作性问题的风险。

建议将每个可验证 凭证的默认最大大小设为 10MB,作为 互操作性基线,并可在需要时配置更大的大小。 这也适应了大多数基于文档的数据库存储解决方案 16MB 的大小限制。

默认情况下,大型二进制值预期应被链接,并包含哈希 (除非有隐私方面的理由不这样做)。

3. HTTP API

本节包含在创建一致 实现时应遵循的 HTTP API 端点定义和实现 指南。

3.1 组件概述

本节按预期可调用端点的组件, 概述 VC-API 中的所有端点。如果某个组件下面没有 列表,则意味着 VC-API 当前未为 该组件指定任何端点。

签发者协调器

下面列出了预期由签发者 协调器公开的所有端点,以及 预期调用该端点的组件。

端点 预期调用方 定义
GET /interactions/{interactionId} 持有所提供 URL 的任何人 3.7.1 交互 URL 格式
POST /callbacks/{localCallbackId} 工作流服务 3.6.7 交换步骤回调

签发者服务

下面列出了预期由签发者 服务公开的所有端点,以及 预期调用该端点的组件。

端点 预期调用方 定义
POST /credentials/issue 签发者协调器、工作流服务 3.2.1 签发凭证
GET /credentials/{id} 签发者协调器、持有者协调器、工作流服务 3.2.2 获取特定凭证
DELETE /credentials/{id} 签发者协调器、持有者协调器 3.2.3 删除特定凭证

验证者协调器

下面列出了预期由验证者协调器公开的所有端点,以及预期 调用该端点的组件。

端点 预期调用方 定义
GET /interactions/{interactionId} 持有所提供 URL 的任何人 3.7.1 交互 URL 格式
POST /callbacks/{localCallbackId} 工作流服务 3.6.7 交换步骤回调

验证者服务

下面列出了预期由验证者 服务公开的所有端点, 以及预期调用该端点的组件。

端点 预期调用方 定义
POST /credentials/verify 验证者协调器、工作流服务 3.3.1 验证凭证
POST /presentations/verify 验证者协调器、工作流服务 3.3.2 验证表达
POST /challenges 验证者协调器、工作流服务 3.3.3 创建质询

持有者协调器

下面列出了预期由持有者 协调器公开的所有端点,以及 预期调用该端点的组件。

端点 预期调用方 定义
GET /interactions/{interactionId} 持有所提供 URL 的任何人 3.7.1 交互 URL 格式
POST /callbacks/{localCallbackId} 工作流服务 3.6.7 交换步骤回调

持有者服务

下面列出了预期由持有者 服务公开的所有端点,以及 预期调用该端点的组件。

端点 预期调用方 定义
POST /credentials/derive 持有者协调器、工作流服务 3.5.1 派生凭证
GET /credentials/{id} 签发者协调器、持有者协调器、工作流服务 3.2.2 获取特定凭证
DELETE /credentials/{id} 签发者协调器、持有者协调器 3.2.3 删除特定凭证
GET /presentations 持有者协调器、工作流服务 3.5.3 获取表达
POST /presentations 持有者协调器、工作流服务 3.5.2 创建表达
GET /presentations/{id} 持有者协调器、工作流服务 3.5.4 获取特定表达
DELETE /presentations/{id} 持有者协调器 3.5.5 删除特定表达

状态服务

下面列出了预期由状态 服务公开的所有端点,以及 预期调用该端点的组件。

端点 预期调用方 定义
POST /status-lists 签发者服务 C.1 创建状态列表
GET /status-lists/{id} 公开 C.2 获取状态列表
POST /credentials/status 签发者服务 C.3 更新状态

工作流服务

下面列出了预期由工作流服务公开的所有端点, 以及预期调用该端点的组件。

端点 预期调用方 定义
POST /workflows 管理员 3.6.1 创建工作流
GET /workflows/{localWorkflowId} 管理员 3.6.2 获取工作流配置
POST /workflows/{localWorkflowId}/exchanges 协调器 3.6.3 创建交换
GET /workflows/{localWorkflowId}/exchanges/{localExchangeId} 协调器 3.6.6 获取交换状态
POST /workflows/{localWorkflowId}/exchanges/{localExchangeId} 任何人 3.6.5 参与交换
GET /workflows/{localWorkflowId}/exchanges/{localExchangeId}/protocols 验证者协调器、持有者协调器 3.6.4 获取交换协议
POST /{inviteId}/invite-request/response POST 到包含 /interactions/{interactionId} 的 URL 的任何人 3.7.4 交互协议响应

3.2 签发

以下 API 被定义用于签发 Verifiable Credential:

端点 描述
GET /credentials/{id} 按 ID 获取 credential 或 verifiable credential。若要获取未设置 credential.id 但具有相关 credentialId 值的 credential,请改为传递 credentialId。
DELETE /credentials/{id} 按 ID 删除 credential 或 verifiable credential。若要删除未 设置 credential.id 但具有相关 credentialId 值的 credential,请改为传递 credentialId。
POST /credentials/issue 签发 credential,并在响应主体中返回它。
POST /credentials/status 更新已签发 credential 的状态
POST /status-lists 创建新的状态列表
GET /status-lists/{id} 检索状态列表凭证

3.2.1 签发凭证

此端点用于签发可验证 凭证

:已签发 credential 的媒体类型

若要签发媒体类型不是 application/vc 的 credentials,例如 application/mdocapplication/vc+sd-jwtapplication/vcb;barcode-format=qr_codeapplication/vcb;barcode-format=pdf417,可以在响应中 返回一个 EnvelopedVerifiableCredential

POST /credentials/issue - 签发 credential,并在响应主体中返回它。

/credentials/issue 端点在接收 POST 时使用以下模式:

属性 描述
credential [object] 拟签发的 W3C Verifiable Credential。它MUST是如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项MUST是字符串。
id [string]
credential 的 ID。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
对象,或
{
  "type": "array",
  "items": {
    "type": "object"
  }
}
options [object] 用于指定如何签发 credential 的选项。它MUST是如下形式的对象:
mandatoryPointers [array]
与选择性披露方案一起使用,用于指定必须披露的 语句。mandatoryPointers 数组中的每一项MUST是 字符串。
credentialId [string]
可用于标识 credential 的 URI,可在 API 中 用于引用已签发的 verifiable credential。如果 issuer coordinator 未 提供 credentialId,issuer service 将从 credential.id 自动填充 其值。如果既未提供 credentialId,也未提供 credential.id, 则在该 credential 签发后将无法引用它, 也无法处理重复错误。如果设置了 credential.id 属性, issuer coordinator SHOULD NOT设置 credentialId,也不应 使用 credentialId 替代 credential.id;相反, credentialId 是一种在未设置 id 属性 (即 credential.id)时标识 credential 的方式。如果 issuer coordinator 未提供 credentialId,issuer service SHOULD NOT自动生成 credentialId,因为如果客户端从未收到结果, 这样做可能会造成分区错误。

/credentials/issue 端点在接收 POST 时可能产生以下任一响应:

响应 主体
201 Credential 已成功签发!
content-type: application/json
如下形式的对象:
IssueCredentialResponse [object]
成功请求 verifiable credential 后返回的格式。 它MUST是如下形式的对象:
verifiableCredential [object]
如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST是字符串。
id [string]
credential 的 ID。此属性MAY为 空。如果未提供 id 属性,issuer SHOULD NOT自动生成该属性, 因为 Verifiable Credential 不要求 id 属性 才有效,并且存在无法设置 id 属性的 用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项MUST是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。 它MUST是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的 随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
,或一个用于在 verifiable presentation 中将 enveloped verifiable credential 与 verifiableCredential 属性关联的对象。 它MUST是如下形式的对象:
@context [array]
enveloped verifiable credential 的 JSON-LD context。 @context 数组中的每一项 MUST是字符串。
id [string]
MUST是一个 "data:" scheme URL [RFC2397], 使用封装安全方案表达受保护的 verifiable credential。
type [string]
MUST是 EnvelopedVerifiableCredential。
400 由于以下原因之一,无法处理请求: - 提供的 'issuer' 值与预期配置不匹配。 - 导致 Bad Request 的其他条件。

如果某个用例要求 issuer instance 将多个 proofs 附加到所提供的 credential,则该 instance MUST在对 /credentials/issue 端点的单次调用响应中附加所有这些 proofs。

如果提供的 credential 已经包含一个或多个 proofs,则其行为 由 issuer instance 的配置决定。issuing instance SHOULD 被配置为以下列方式之一处理现有 proofs:

  • 证明集:将新 proofs 追加到调用方提供的现有 proofs 列表中,必要时先将任何现有单一 proof 转换为列表。 在这里,新 proofs 不绑定到任何现有 proofs;新 proofs 与调用方先前提供的 proofs 并行存在。
  • 证明链:追加新 proofs 以创建或扩展现有 proof chain。在这里,proofs 按特定顺序链接,可能使用 previousProof 属性建立链关系。
  • 错误处理:如果提供了包含现有 proof 值的 credential 值,而该 instance 被配置为只接受没有现有 proofs 的 credentials,则返回错误。

使用的具体方法取决于 issuer instance 的配置 以及 verifiable credential 的预期用例。

3.2.2 获取特定凭证

GET /credentials/{id} - 按 ID 获取 credential 或 verifiable credential。若要获取 未设置 credential.id 但具有相关 credentialId 值的 credential,请改为传递 credentialId。

/credentials/{id} 端点在接收 GET 时可能产生以下任一响应:

响应 主体
200 Credential 已检索
content-type: application/json
成功请求 verifiable credential 后返回的格式。 它MUST是如下形式的对象:
verifiableCredential [object]
如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项MUST是 字符串。
id [string]
credential 的 ID。此属性MAY为空。 如果未提供 id 属性,issuer SHOULD NOT自动生成该属性, 因为 Verifiable Credential 不要求 id 属性 才有效,并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。 它MUST是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的 随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
,或一个用于在 verifiable presentation 中将 enveloped verifiable credential 与 verifiableCredential 属性关联的对象。 它MUST是如下形式的对象:
@context [array]
enveloped verifiable credential 的 JSON-LD context。 @context 数组中的每一项MUST是 字符串。
id [string]
MUST是一个 "data:" scheme URL [RFC2397], 使用封装安全方案表达受保护的 verifiable credential。
type [string]
MUST是 EnvelopedVerifiableCredential。
400 错误请求
401 未授权
404 未找到 credential
410 已消失!这里没有数据
418 我是茶壶——MUST不得在双方预先安排的场景之外返回

3.2.3 删除特定 凭证

签发者服务持有者 服务可能会长期存储已签发的可验证 凭证。这样做时,删除此类可验证 凭证可能很有用;例如,签发者可能 由于监管要求而需要这样做,例如 被遗忘权。有关从系统中移除可验证 凭证的更多 考量,见第 B.3 删除节。

DELETE /credentials/{id} - 按 ID 删除 credential 或 verifiable credential。若要删除 未设置 credential.id 但具有相关 credentialId 值的 credential,请改为传递 credentialId。

/credentials/{id} 端点在接收 DELETE 时可能产生以下任一响应:

响应 主体
202 Credential 已删除——默认使用 202,因为假定会进行软删除并需要处理 时间
400 错误请求
401 未授权
404 未找到 credential
410 已消失!这里没有数据

3.3 验证

以下 API 被定义用于验证 Verifiable Credential:

端点 描述
POST /credentials/verify 验证 verifiableCredential,并在响应主体中返回 verificationResult。
POST /presentations/verify 验证 Presentation 及其包含的所有 Verifiable Credentials,并返回详细的 验证结果。
POST /challenges 向此端点传递空主体会创建并在 响应主体中返回一个 challenge 字符串。

3.3.1 验证凭证

此端点用于验证可验证 凭证

:验证 credential 的媒体类型

若要验证媒体类型不是 application/vc 的 credentials,例如 application/mdocapplication/vc+sd-jwtapplication/vcb;barcode-format=qr_codeapplication/vcb;barcode-format=pdf417,可以在请求中 提供一个 EnvelopedVerifiableCredential

POST /credentials/verify - 验证 verifiableCredential,并在 响应主体中返回 verificationResult。

/credentials/verify 端点在接收 POST 时使用以下模式之一:

属性 描述
verifiableCredential [object] 如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果未提供 id 属性, issuer SHOULD NOT 自动生成该属性,因为 Verifiable Credential 不要求 id 属性才有效,并且存在 无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
options [object] 用于指定如何验证 credential 的选项。它 MUST 是如下形式的对象:
returnResults [boolean]
在响应中包含所执行的每个验证步骤的结果,例如 验证各个 proofs、statuses 和 schemas。
returnProblemDetails [boolean]
在响应中包含 ProblemDetails 错误和警告。
returnCredential [boolean]
是否应在响应中返回已验证的 credential?如果为 true,则 已验证的 credential 应以其被验证时的形式 返回。如果为 false 或未提供,则不应 返回已验证的 credential。

或者,/credentials/verify 端点也可以使用以下模式:

属性 描述
verifiableCredential [object] 用于在 verifiable presentation 中将 enveloped verifiable credential 与 verifiableCredential 属性关联的对象。它 MUST 是 如下形式的对象:
@context [array]
enveloped verifiable credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
MUST 是一个 "data:" scheme URL [RFC2397],用于使用封装 安全方案表达受保护的 verifiable credential。
type [string]
MUST 是 EnvelopedVerifiableCredential。
options [object] 用于指定如何验证 credential 的选项。它 MUST 是如下形式的对象:
returnResults [boolean]
在响应中包含所执行的每个验证步骤的结果,例如 验证各个 proofs、statuses 和 schemas。
returnProblemDetails [boolean]
在响应中包含 ProblemDetails 错误和警告。
returnCredential [boolean]
是否应在响应中返回已验证的 credential?如果为 true,则 已验证的 credential 应以其被验证时的形式 返回。如果为 false 或未提供,则不应 返回已验证的 credential。

/credentials/verify 端点在接收 POST 时可能产生以下任一响应:

响应 主体
200 Verifiable Credential 已成功验证!
content-type: application/json
用于报告 VerifiableCredential 验证过程结果的对象。它 MUST 是如下形式的对象:
verified [boolean]
VerifiableCredential 的整体验证断言。如果在 验证过程中未检测到错误,则设为 true; 否则为 false。有关错误、警告和 验证步骤的更多指导,见错误处理章节。
credential [object]
一个对象
problemDetails [array]
由 ProblemDetails 对象组成的数组。problemDetails 数组中的每一项 MUST 是如下 形式的对象:
type [string]
标识问题类型的 URL。
title [string]
针对问题的简短但具体的人类可读字符串。
detail [string]
针对问题的较长人类可读字符串。
results [object]
作为更详细输出包含的验证结果。键 映射到 Verifiable Credential Data Model 中的属性。 它 MUST 是如下形式的对象:
validFrom [object]
验证 validFrom 属性的结果(若该属性存在于 VerifiableCredential 中)。它 MUST 是如下 形式的对象:
verified [boolean]
验证结果。
input [string]
validFrom 值。
validUntil [object]
验证 validUntil 属性的结果(若该属性存在于 VerifiableCredential 中)。它 MUST 是如下 形式的对象:
verified [boolean]
验证结果。
input [string]
validUntil 值。
credentialSchema [array]
验证 credentialSchema 对象的结果(若有)。 credentialSchema 数组中的每一项 MUST 是 验证 credentialSchema 对象的结果。它 MUST 是 如下形式的对象:
verified [boolean]
验证 credentialSchema 对象的结果。
input [object]
一个对象
credentialStatus [array]
验证 credentialStatus 对象的结果(若有)。 credentialStatus 数组中的每一项 MUST 是 验证 credentialStatus 对象的结果。它 MUST 是 如下形式的对象:
value [integer]
与状态条目关联的具体状态值。
verified [boolean]
验证 credentialStatus 对象的结果。
input [object]
一个对象
proof [array]
验证 proof 对象的结果(若有)。proof 数组中的每一项 MUST 是验证 proof 对象的结果。它 MUST 是如下 形式的对象:
verified [boolean]
验证 proof 对象的结果。
input [object]
一个对象
400 输入无效!

3.3.2 验证表达

此端点用于验证可验证 表达,并且默认验证其中包含的所有 可验证 凭证

验证过程包括:

  • 验证表达自身的 proof(包括 domain 和 challenge 验证)
  • 验证每个所含可验证凭证的 proof、status 和有效 期限
  • 检查表达中的 holder 是否与 表达 proof 中使用的 verification method 匹配

业务规则验证(例如验证 credential subjects 是否与 presentation holder 匹配,或关于谁可以出示哪些 credentials 的授权策略)不在此验证端点范围内,应由 调用应用程序执行。

POST /presentations/verify - 验证 Presentation 及其包含的所有 Verifiable Credentials, 并返回详细验证结果。

/presentations/verify 端点在接收 POST 时使用以下模式之一:

属性 描述
verifiablePresentation [object] 如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是如下 形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性,因为 Verifiable Credential 不要求 id 属性才有效, 并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
proof [object]
包含 challenge 和 domain 的 Data Integrity Proof,如 W3C VC Data Integrity 规范所定义。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
challenge [string]
verifier 选择的值,用于缓解认证 proof 重放攻击。
domain [string]
proof 的 domain,用于将其使用限制到特定目标。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
options [object] 用于指定如何验证 presentation 的选项。 实现 MAY 用附加属性扩展此对象,以控制 验证行为。常见扩展可以包括用于禁用对 所含 credentials 的验证的选项(例如用于调试,或仅需要 presentation 级验证时);对 credential 各方面验证的细粒度控制,例如 status checks、validity period validation、proof verification 和 schema validation;以及针对 presentation 中特定 credentials 的 选择性验证控制。 当 credential verification 被禁用或受限时,此 API 是可组合的; 可以使用 /credentials/verify 端点单独验证 individual credentials。它 MUST 是如下形式的对象:
challenge [string]
由 proof 请求方提供的 challenge;例如 6e62f66e-67de-11eb-b490-ef3eeefa55f2
domain [string]
proof 的预期有效 domain;例如 website.example
returnPresentation [boolean]
是否返回已验证的 presentation。如果为 true,则 已验证的 presentation MUST 被返回。如果为 false 或未提供,则 已验证的 presentation MUST NOT 被返回。

或者,/presentations/verify 端点也可以使用以下模式:

属性 描述
presentation [object] 不带 proof 的 JSON-LD Verifiable Presentation。它 MUST 是 如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是如下 形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性,因为 Verifiable Credential 不要求 id 属性才有效, 并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
属性 描述
verifiablePresentation [object] 用于表达 enveloped verifiable presentation 的对象。它 MUST 是 如下形式的对象:
@context [array]
enveloped verifiable presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
MUST 是一个 "data:" scheme URL [RFC2397],用于使用封装 安全方案表达受保护的 verifiable presentation。
type [string]
MUST 是 EnvelopedVerifiablePresentation。
options [object] 用于指定如何验证 presentation 的选项。 实现 MAY 用附加属性扩展此对象,以控制 验证行为。常见扩展可以包括用于禁用对 所含 credentials 的验证的选项(例如用于调试,或仅需要 presentation 级验证时);对 credential 各方面验证的细粒度控制,例如 status checks、validity period validation、proof verification 和 schema validation;以及针对 presentation 中特定 credentials 的 选择性验证控制。 当 credential verification 被禁用或受限时,此 API 是可组合的; 可以使用 /credentials/verify 端点单独验证 individual credentials。它 MUST 是如下形式的对象:
challenge [string]
由 proof 请求方提供的 challenge;例如 6e62f66e-67de-11eb-b490-ef3eeefa55f2
domain [string]
proof 的预期有效 domain;例如 website.example
returnPresentation [boolean]
是否返回已验证的 presentation。如果为 true,则 已验证的 presentation MUST 被返回。如果为 false 或未提供,则 已验证的 presentation MUST NOT 被返回。

/presentations/verify 端点在接收 POST 时可能产生以下任一响应:

响应 主体
200 验证过程已成功完成。响应主体包含 详细结果, 指示 presentation 及其包含的 credentials 是通过还是 未通过验证。 <code>200</code> 状态表示验证过程本身 成功,无论 presentation 和/或 credentials 被判定为有效还是无效。
content-type: application/json
用于报告 VerifiablePresentation 验证过程结果的对象。它 MUST 是如下形式的对象:
verified [boolean]
VerifiablePresentation 的整体验证断言。如果 VerifiablePresentation 和所有已检查的 VerifiableCredentials 均通过验证,则设为 true;否则为 false。有关错误和警告,以及验证和校验步骤的 更多指导,见错误处理章节。
verifiablePresentation [object]
一个对象
problemDetails [array]
由 presentation 级整体问题的 ProblemDetails 对象组成的数组。 problemDetails 数组中的每一项 MUST 是如下形式的对象:
type [string]
标识问题类型的 URL。
title [string]
针对问题的简短但具体的人类可读字符串。
detail [string]
针对问题的较长人类可读字符串。
results [object]
默认情况下,包含 VerifiablePresentation 和其中所有 VerifiableCredentials 的详细验证结果。键 映射到 Verifiable Credential Data Model 中受验证约束的 属性。它 MUST 是如下 形式的对象:
presentation [object]
特定于 VerifiablePresentation 本身(不包括其所含 VerifiableCredentials)的验证结果。它 MUST 是 如下形式的对象:
challenge [object]
如果在验证选项中提供,则为 验证所有所提供 proofs 的 security challenge 的结果。 它 MUST 是如下形式的对象:
verified [boolean]
验证所有所提供 proofs 的 security challenge 的结果。
input [string]
challenge 输入字符串。
domain [object]
如果在验证选项中提供,则为 验证所有所提供 proofs 的 security domain 的结果。 它 MUST 是如下 形式的对象:
verified [boolean]
验证所有所提供 proofs 的 security domain 的结果。
input [string]
security domain 输入字符串。
holder [object]
验证 holder 的结果(若有)。它 MUST 是 如下形式的对象:
verified [boolean]
验证 holder 的结果。
input [string]
holder 输入字符串。
proof [array]
验证 proof 对象的结果(若有)。 proof 数组中的每一项 MUST 是 验证 proof 对象的结果。它 MUST 是 如下形式的对象:
verified [boolean]
验证 proof 对象的结果。
input [object]
一个对象
problemDetails [array]
特定于此 proof 的问题。problemDetails 数组中的每一项 MUST 是如下形式的对象:
type [string]
标识问题类型的 URL。
title [string]
针对问题的简短但具体的人类可读 字符串。
detail [string]
针对问题的较长人类可读字符串。
credentials [array]
VerifiablePresentation 中每个 VerifiableCredential 的 详细验证结果。credentials 数组中的每一项 MUST 是用于报告 VerifiableCredential 验证过程结果的对象。 它 MUST 是如下形式的对象:
verified [boolean]
VerifiableCredential 的整体 验证断言。如果在验证过程中 未检测到错误,则设为 true;否则为 false。有关错误、警告和 验证步骤的更多指导, 见错误处理章节。
credential [object]
一个对象
problemDetails [array]
由 ProblemDetails 对象组成的数组。 problemDetails 数组中的每一项 MUST 是如下形式的对象:
type [string]
标识问题类型的 URL。
title [string]
针对问题的简短但具体的人类可读字符串。
detail [string]
针对问题的较长人类可读字符串。
results [object]
作为更详细输出包含的验证结果。 键映射到 Verifiable Credential Data Model 中的属性。它 MUST 是 如下形式的对象:
validFrom [object]
验证 validFrom 属性的结果, 若存在于 VerifiableCredential 中。它 MUST 是如下形式的对象:
verified [boolean]
验证结果。
input [string]
validFrom 值。
validUntil [object]
验证 validUntil 属性的结果,若存在于 VerifiableCredential 中。它 MUST 是如下 形式的对象:
verified [boolean]
验证结果。
input [string]
validUntil 值。
credentialSchema [array]
验证 credentialSchema 对象的结果(若有)。credentialSchema 数组中的每一项 MUST 是 验证 credentialSchema 对象的结果。它 MUST 是 如下形式的对象:
verified [boolean]
验证 credentialSchema 对象的结果。
input [object]
一个对象
credentialStatus [array]
验证 credentialStatus 对象的结果(若有)。credentialStatus 数组中的每一项 MUST 是 验证 credentialStatus 对象的结果。它 MUST 是 如下形式的对象:
value [integer]
与状态条目关联的 具体状态值。
verified [boolean]
验证 credentialStatus 对象的结果。
input [object]
一个对象
proof [array]
验证 proof 对象的结果(若 有)。proof 数组中的每一项 MUST 是验证 proof 对象的结果。它 MUST 是 如下形式的对象:
verified [boolean]
验证 proof 对象的结果。
input [object]
一个对象
400 无效或格式错误的输入阻止了验证过程 执行。 这表示请求格式、结构或参数存在问题, 而不是 验证失败。
413 载荷过大
429 已超过请求速率限制。

3.3.3 创建质询

POST /challenges - 向此端点传递空主体会创建并在 响应主体中返回一个 challenge 字符串。

/challenges 端点在接收 POST 时可能产生以下任一响应:

响应 主体
200 Challenge 已创建
content-type: application/json
包含 challenge 的对象。它 MUST 是如下形式的对象:
challenge [string]
challenge 值
400 无效或格式错误的输入

instance 应创建用于验证期间的 challenge,并跟踪 该 challenge 作为 options.challenge 被传递给验证端点的 次数。

3.4 请求表达

在使用可验证 凭证和基于去中心化 标识符的认证时,一方通常需要向 另一方请求数据。本节描述这些请求的一般格式,并 提供一种具体的可验证表达请求格式。

3.4.1 可验证 表达请求

可验证表达请求验证者持有者发出的 对表达的请求。若要请求一个或多个封装在可验证 表达中的 credentials, 验证者 会构造一个 JSON 请求,描述其希望从 持有者接收的一个或多个 credentials。请求的一般格式 如下所示:

示例 1:可验证表达请求的一般形式
{
  // 一个或多个对可验证凭证的请求
  "query": [{
    "type": "QueryByExample",
    // QueryByExample 专用的查询详细信息...
  }],
  // 要包含在可验证表达中的目标安全域,
  // 例如网站域名
  "domain": "domain.example",

  // 要包含在可验证表达中的随机 challenge 字符串
  "challenge": "f63cb0d2-760e-11f0-a2b1-67febb854a5f"
}

query 属性作为 presentation 中数据请求的主要扩展点机制。 虽然本文档定义了一种通用查询 机制(见第 3.4.2 按示例查询节),但所有 query 对象均为 如下形式:

query
一个 REQUIRED 属性,指定 验证者所请求的信息。该值 MUST 是一个或多个映射,其中每个映射 MUST 定义一个 type 属性,其关联值为字符串
domain
一个 OPTIONAL字符串,由验证者presentation request 期间提供给持有者持有者 会检查以确保该数据与其正在交互的 domain(例如网站域名) 关联;如果是,则将该数据包含在可验证 表达中。domain 用于确保持有者将其可验证 表达 限定到特定验证者,从而保护验证者免受 重放攻击
challenge
一个 OPTIONAL、唯一的字符串,由验证者在特定 presentation request 期间提供给 持有者持有者 将此数据包含在发送给验证者可验证 表达中,从而保护 验证者免受重放 攻击

3.4.2 按示例查询

“query by example” credential 查询格式旨在使开发者 能够轻松地从一个或多个可验证 凭证中请求其需要的声明, 以支持特定业务流程。该查询还可以 指定其他信息,例如一个或多个受到 验证者信任的签发者

QueryByExample 查询中的 credentialQuery 属性是单个对象。 用于组合多个查询的逻辑 "AND" 和 "OR" 操作 通过查询级别的 group 属性处理,如第 3.4.5 查询中的逻辑操作节所述。具有相同 group 值的多个查询作为 "AND" 操作处理,而具有不同 或缺失 group 值的查询作为 "OR" 操作处理。

示例 2:Query By Example 查询
{
  "query": [{
    "type": "QueryByExample",
    "credentialQuery": {
      // (可选)请求此 credential 的原因,
      // 可由用户的软件显示给用户
      "reason": "We need to know if you are an alumni of this school.",
      // (可选)所请求 credential 的示例
      "example": {
        "@context": [
          "https://www.w3.org/ns/credentials/v2",
          "https://www.w3.org/ns/credentials/examples/v2"
        ],
        "type": "ExampleAlumniCredential",
        // (可选)根据 credential subject type 选择 credential
        "credentialSubject": {
          "type": "Alumni"
        }
      },
      // (可选)指定来自特定 acceptedIssuers 或
      // 权威委托方的 credentials
      "acceptedIssuers": [{
        "issuer": "did:web:authority.example"
      }]
    }
  }],
  "challenge": "3182bdea-63d9-11ea-b6de-3b7c1404d57f",
  "domain": "reunion.example"
}

credentialQuery 对象支持以下属性:

属性 描述
reason 一个 OPTIONAL字符串,提供 人类可读的说明,解释为什么 请求该 credential。该说明 MAY 由其软件显示给 持有者
example 一个 OPTIONAL 对象,提供所请求 credential 的示例, 包括其 @contexttype,以及可选的 credentialSubject 字段,用于指示需要哪些 claims。
acceptedIssuers 一个 OPTIONAL 数组,包含条目或包含条目的列表,用于 标识验证者认可并接受作为 可验证 凭证签发者的实体。每一项 MUST 是以下之一: 1)标识收到的可验证 凭证issuer 属性中 某个签发者的 [URL]; 或 2)包含 id 属性的对象,该属性值是 [URL],用于 标识收到的可验证 凭证issuer 属性中的签发者; 或 3)包含 recognizedIn 属性的对象,该属性 与一个对象关联,该对象具有设置为 RecognizedEntityCredentialtype 属性,以及带有 [URL] 值的 id 属性, 该值指向 Recognized Entities v1.0 规范中定义的此类 credential;该列表包含 验证者可接受的已认可签发者。有效 示例值包括:
  • did:web:red-issuer.example
  • https://blue-issuer.example/
  • {"id": "did:web:green-issuer.example"}
  • {"recognizedIn": {"id": "https://url.example/list.vc", "type": "RecognizedEntityCredential"}}
acceptedCryptosuites 一个 OPTIONAL 数组,指定 验证者 将接受哪些 cryptographic proof suites。每个元素 SHOULD 是一个对象,带有 cryptosuite 属性,引用 Data Integrity cryptosuite 名称,或为旧版使用 Ed25519Signature2020 (为向后兼容,字符串值也 MAY 被使用,并 解释为 cryptosuite 名称)。这使持有者能够选择 适当的 proof 格式。此属性 MAY 独立于 acceptedEnvelopes 使用, 后者仅适用于 enveloped credentials。有效示例值包括:
  • [{"cryptosuite": "eddsa-rdfc-2022"}, {"cryptosuite": "ecdsa-rdfc-2019"}]
  • [{"cryptosuite": "bbs-2023"}, {"cryptosuite": "ecdsa-sd-2023"}]
acceptedEnvelopes 一个 OPTIONAL 数组,指定验证者将 接受哪些 envelope formats。每个元素 SHOULD 是一个带有 mediaType 属性的对象,该属性引用 envelope 的媒体类型 (为向后兼容,字符串值也 MAY 被使用,并 解释为媒体类型)。这使持有者能够 以默认 Data Integrity 格式之外的格式提供 credentials。 此属性 MAY 独立于 acceptedCryptosuites 使用, 后者仅适用于 使用可接受 cryptosuite 签名的 JSON-LD credentials。有效示例值包括:
  • [{"mediaType": "application/jwt"}]
  • [{"mediaType": "application/vc+sd-jwt"}]

QueryByExample 的 JSON Schema 在单独文件中提供,用于集成到 软件系统中。

以下示例演示一个指定可接受 cryptosuites 和 envelope formats 的 QueryByExample,使持有者能够选择 适当的 proof 机制:

示例 3:带有可接受 cryptosuites 和 envelopes 的 Query By Example
{
  "query": [{
    "type": "QueryByExample",
    "credentialQuery": {
      "reason": "Please present your PermanentResidentCard to complete the verification process.",
      "example": {
        "@context": [
          "https://www.w3.org/ns/credentials/v2",
          "https://w3id.org/citizenship/v3"
        ],
        "type": ["PermanentResidentCard"],
        "credentialSubject": {
          "birthCountry": ""
        }
      },
      "acceptedCryptosuites": [
        {"cryptosuite": "eddsa-rdfc-2022"},
        {"cryptosuite": "ecdsa-rdfc-2019"},
        {"cryptosuite": "bbs-2023"},
        {"cryptosuite": "ecdsa-sd-2023"}
      ],
      "acceptedEnvelopes": [
        {"mediaType": "application/jwt"},
        {"mediaType": "application/vc+sd-jwt"}
      ]
    }
  }],
  "challenge": "9876fedc-ba98-7654-3210-fedcba987654",
  "domain": "immigration.example"
}

在上述示例中,验证者表明其将 接受由所列任一 cryptosuite 保护的 credentials。 通过包含 bbs-2023ecdsa-sd-2023验证者表示选择性 披露 proofs 是可接受的,从而允许持有者只披露 birthCountry 字段,而不是整个 credential。acceptedEnvelopes 属性表示基于 JWT 的 envelope formats 也是可接受的。

:使用 Query By Example 进行选择性 披露

Query By Example 中包含的任何字段都是必填字段。这意味着在使用 Query By Example 启用选择性披露时,请求者需要注意不要在其查询中包含 用例不需要的字段。Query By Example 没有办法指示“可选” 字段; 因此,响应查询的钱包有责任确保其响应 不会披露超出请求范围的信息。注意:某些用于 可验证凭证的保护机制不允许选择性披露;在这些情况下, 可能必须发送未请求的信息,才能发送所请求的信息。数字钱包 预期会告知用户将共享哪些信息。 若要请求一个字段而不声明预期值,请求者可以在 请求中包含该字段并将其值留为空字符串。例如,如果请求者需要名字, 可以包含可选的 "credentialSubject" 对象,并带有一个字段 "firstName": ""。 这将允许钱包仅以所请求 credential 的 firstName 进行响应, 而不期待包含任何其他字段。_这并不阻止钱包通过在其查询响应中包含 额外字段而过度共享。_ 若要表示选择性披露 cryptosuites 是可接受的,验证者 SHOULDacceptedCryptosuites 数组中包含诸如 bbs-2023ecdsa-sd-2023 的 cryptosuites。

3.4.3 DID 认证

本节定义验证者如何请求 持有者 执行基于去中心化标识符的认证 [DID-CORE]。最简单的形式中, 认证协议由验证者发出的 challenge 和持有者给出的响应组成:

示例 4:DID Authentication 请求
{
  "query": [{
    "type": "DIDAuthentication",
    "acceptedMethods": [{"method": "example"}]
  }],
  "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
  "domain": "example.com"
}

上述 DID Authentication 请求指定验证者希望 持有者通过对所提供 challenge 生成 数字签名来证明其对 DID 的控制。持有者可以通过提供以下 响应来回应:

示例 5:DID Authentication 响应
{
  "@context": ["https://www.w3.org/ns/credentials/v2"],
  "type": "VerifiablePresentation",
  "holder": "did:example:12345",
  "proof": {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-rdfc-2022",
    "verificationMethod": "did:example:12345#key-1",
    "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
    "domain": "example.com",
    "created": "2024-02-25T14:58:42Z",
    "proofPurpose": "authentication",
    "proofValue": "z3FXQjecWufY46...UAUL5n2Brbx"
  }
}
3.4.3.1 DID Authentication 查询格式

DID Authentication 查询格式使验证者能够请求 持有者 以特定方式进行认证。DID Authentication 查询 MUST 采用以下形式:

属性 描述
type 一个 REQUIRED 字符串值,MUST 设置为 DIDAuthentication
acceptedMethods 一个可选的对象数组,表示验证者将 接受 所列的任意 DID Method。数组中的每个对象 MUST 包含一个名为 method 的属性,其值是 DID Method 名称,并且 MAY 包含其他 DID Method 专用属性。有效示例值 包括:
  • [{"method": "key"}]
  • [{"method": "key"}, {"method": "web"}]
acceptedCryptosuites 一个可选的对象数组,传达 持有者在生成要提交给此 验证者的 cryptographic proof 时 MUST 选择的 cryptography suites。数组中的每个 对象 MUST 包含一个名为 cryptosuite 的属性,其值是 Data Integrity cryptosuite 名称(或旧版的 Ed25519Signature2020), 并且 MAY 包含其他 cryptosuite 专用属性。 有效示例值包括:
  • [{"cryptosuite": "eddsa-rdfc-2022"}]
  • [{"cryptosuite": "ecdsa-rdfc-2019"}, {"cryptosuite": "bbs-2023"}]

以下示例演示验证者希望 持有者 使用 DID Web method 和 data integrity ECDSA cryptography suite,在已建立的通信通道(例如 Credential Handler API(CHAPI))上进行认证:

示例 6:使用 did:web 和 ecdsa-rdfc-2019 的 DID Authentication 请求
{
  "query": [{
    "type": "DIDAuthentication",
    "acceptedMethods": [{"method": "key"}],
    "acceptedCryptosuites": [{"cryptosuite": "ecdsa-rdfc-2019"}]
  }],
  "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
  "domain": "example.com"
}

在下一个示例中,验证者希望 持有者 使用 DID Key 或 DID Web method,并使用标准 EdDSA data integrity cryptography suite;可选地包含一个 cryptographic proof,证明其能够执行 data integrity BBS proof;并在不同通信通道上进行认证,在此情况下 使用 Verifiable Credential API HTTP 端点。

示例 7:复杂 DID Authentication 请求
{
  "query": [{
    "type": "DIDAuthentication",
    "acceptedMethods": [{"method": "key"}, {"method": "web"}],
    "acceptedCryptosuites": [{"cryptosuite": "ecdsa-rdfc-2019"}]
  }, {
    "type": "DIDAuthentication",
    "required": false,
    "acceptedMethods": [{"method": "key"}, {"method": "web"}],
    "acceptedCryptosuites": [{"cryptosuite": "bbs-2023"}]
  }],
  "challenge": "zLEwtBYgQVNR4tyeo",
  "domain": "didauth.example"
}
3.4.3.2 DID Authentication 响应格式

DID Authentication 响应格式使持有者能够 提供验证者请求的信息。DID Authentication 响应 MUST 是如下形式的可验证 表达

属性 描述
type 一个 REQUIRED 字符串值,MUST 设置为 VerifiablePresentation
holder 一个 REQUIRED 字符串值,MUST 设置为 DID Authentication 查询中所请求 类型的特定 DID。
proof 一个 REQUIRED 值,MUST 是 DID Authentication 查询中所请求的一个或多个特定 digital proof types。 每个 proof 对象 MUST 包含 DID Authentication 查询中提供的 domainchallenge 值。 Holder 实现 MUST 确保验证者 指定的 domain 与当前通信通道使用的 domain 匹配。

持有者实现检查 verifier 提供的 domain 是否与当前通信通道所使用的 domain 匹配,这一点至关重要。 如果持有者未能这样做, 不诚实的验证者就可能将 消息重放到并非其自己的 domain。例如,一个从 evil.example domain 运行的不诚实验证者 可以从你的银行获取 challenge,指定 yourbank.example 的 domain 值, 然后将你的响应重放给你的银行以访问你的金融账户。 只要实现确保在生成可验证 表达时使用适当的 domain, 这种攻击就能被缓解。

以下示例演示一个简单的 DID Authentication 响应。

示例 8:使用 did:key 的 DID Authentication 响应
{
  "@context": ["https://www.w3.org/ns/credentials/v2"],
  "type": "VerifiablePresentation",
  "holder": "did:example:12345",
  "proof": {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-rdfc-2022",
    "verificationMethod": "did:example:12345#key-1",
    "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
    "domain": "example.com",
    "created": "2024-02-25T14:58:42Z",
    "proofPurpose": "authentication",
    "proofValue": "z3FXQjecWufY46...UAUL5n2Brbx"
  }
}

3.4.4 授权 能力请求

议题 2

Authorization Capability 查询和响应此时可能不会被标准化。 此示例用于演示可验证 凭证和 mDLs/mdocs 并不是唯一可被 查询的 credential 类型。

这种查询类型会包含在请求中,用于请求 Verifiable Presentation 中的 Authorization Capabilities 或 "zcaps"。

示例 9:Authorization Capability Request 查询
{
  "query": [{
    "type": "AuthorizationCapabilityQuery",
    "capabilityQuery": [{
      "referenceId": "a-memorable-name",
      "allowedAction": ["read", "write"],
      "controller": "did:example:1234",
      "invocationTarget": {
        "type": "urn:edv:documents"
      }
    }, {
      "referenceId": "another-memorable-name",
      "allowedAction": "sign",
      "controller": "did:example:1234",
      "invocationTarget": {
        "type": "Multikey",
        "proofPurpose": "assertionMethod"
      }
    }],
    challenge: "111112b24-63d9-11ea-b99f-4f66f3e4f81a"
  }]
}

3.4.5 查询中的逻辑操作

在 Verifiable Presentation Requests 中,信息的结构化和检索 依赖逻辑操作的使用。"AND" 和 "OR" 操作 在定义到达期望数据的路径方面发挥关键作用。

3.4.5.1 顶层 查询("AND" 操作)

在请求结构的最顶层,如果每个查询的 group 属性 设置为相同值,则不同类型的查询 预期作为 "AND" 操作处理。

在此示例中,有两个查询的 group 标志设置为 certification。这会产生一个 "AND" 操作,表示为了满足请求, 这两个条件都需要被满足。

示例 10:使用顶层查询一次请求多个 credentials
{
  "query": [{
    "type": "QueryByExample",
    "group": "certification",
    // 查询详细信息 ...
  },
  // "AND"
  {
    "type": "DigitalCredentialQueryLanguage",
    "group": "certification",
    // 查询详细信息 ...
  }]
}
3.4.5.2 嵌套查询 ("OR" 操作)

在特定查询类型内,可以通过不指定 group,或提供彼此不同的 group 值, 应用 "OR" 操作。

示例 11:针对备选 credentials 的查询,其中 任一匹配都会成功
{
  "query": [{
    "type": "QueryByExample",
    "group": "college-degree",
    // 查询详细信息 ...
  },
  // "OR"
  {
    "type": "DigitalCredentialQueryLanguage",
    "group": "job-experience",
    // 查询详细信息 ...
  }]
}

3.5 出示

以下 API 被定义用于出示 Verifiable Credential:

端点 描述
POST /credentials/derive 派生 credential,并在响应主体中返回它。
GET /presentations 获取 presentations 或 verifiable presentations 的列表
POST /presentations 创建 presentation,并在响应主体中返回它。
GET /presentations 获取 presentations 或 verifiable presentations 的列表
POST /presentations 创建 presentation,并在响应主体中返回它。
GET /presentations/{id} 按 ID 获取 presentation 或 verifiable presentation
DELETE /presentations/{id} 按 ID 删除 presentation 或 verifiable presentation
POST /exchanges/ 错误:API 端点未定义 - /exchanges/
POST /exchanges/{exchangeId} 错误:API 端点未定义 - /exchanges/{exchangeId}

URL 路径值 exchange-id 对服务器有意义,但对客户端是不透明的。虽然某些服务器 实现可能使用恰好为人类可读的值,但强烈建议客户端 不要为任何人类可读值赋予语义。

3.5.1 派生凭证

POST /credentials/derive - 派生 credential,并在响应主体中返回它。

/credentials/derive 端点在接收 POST 时使用以下模式:

属性 描述
verifiableCredential [object] 如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果未提供 id 属性, issuer SHOULD NOT 自动生成该属性,因为 Verifiable Credential 不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
options [object] 用于指定如何创建 derived credential 的选项。它 MUST 是 如下形式的对象:
selectivePointers [array]
指定选择性披露信息的 JSON pointers 数组。 selectivePointers 数组中的每一项 MUST 是字符串。

/credentials/derive 端点在接收 POST 时可能产生以下任一响应:

响应 主体
201 Credential 已成功派生。
content-type: application/json
如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性,因为 Verifiable Credential 不要求 id 属性才有效, 并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
400 无效请求

3.5.2 创建表达

: Presentation 媒体类型

可以在响应中返回 EnvelopedVerifiablePresentation, 以便创建媒体类型不是 application/vp 的 presentations, 例如 application/vp+jwt

POST /presentations - 创建 presentation,并在响应主体中返回它。

/presentations 端点在接收 POST 时使用以下模式:

属性 描述
presentation [object] 不带 proof 的 JSON-LD Verifiable Presentation。它 MUST 是 如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是如下 形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性,因为 Verifiable Credential 不要求 id 属性才有效, 并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
options [object] 用于指定如何创建 DataIntegrityProof 的选项。它 MUST 是如下 形式的对象:
type [string]
proof 的类型。默认值为 'DataIntegrityProof'。
cryptosuite [string]
proof 的 cryptosuite。
verificationMethod [string]
用于 proof 的 verificationMethod 的 URI。如果省略,将使用默认的 verification method。
proofPurpose [string]
proof 的用途。默认值为 'assertionMethod'。
created [string]
proof 的日期和时间(最高精确到秒)。默认值为 当前系统时间。
challenge [string]
由 proof 请求方提供的 challenge。例如 6e62f66e-67de-11eb-b490-ef3eeefa55f2
domain [string]
proof 的预期有效 domain。例如 website.example

/presentations 端点在接收 POST 时可能产生以下任一响应:

响应 主体
201 Presentation 已成功创建!
content-type: application/json
如下形式的对象:
verifiablePresentation [object]
如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是 如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性, 因为 Verifiable Credential 不要求 id 属性才有效,并且存在无法 设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于 出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
proof [object]
包含 challenge 和 domain 的 Data Integrity Proof,如 W3C VC Data Integrity 规范所定义。它 MUST 是如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
challenge [string]
verifier 选择的值,用于缓解 认证 proof 重放攻击。
domain [string]
proof 的 domain,用于将其使用限制到 特定目标。
nonce [string]
proof 创建者选择的值,用于 出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
,或一个用于表达 enveloped verifiable presentation 的对象。它 MUST 是如下形式的对象:
@context [array]
enveloped verifiable presentation 的 JSON-LD context。@context 数组中的每一项 MUST 是字符串。
id [string]
MUST 是一个 "data:" scheme URL [RFC2397],用于使用 封装安全方案表达受保护的 verifiable presentation。
type [string]
MUST 是 EnvelopedVerifiablePresentation。
400 输入无效!

3.5.3 获取表达

GET /presentations - 获取 presentations 或 verifiable presentations 的列表

/presentations 端点在接收 GET 时可能产生以下任一响应:

响应 主体
200 Presentations 已检索
content-type: application/json
数组中的每一项 MUST 是不带 proof 的 JSON-LD Verifiable Presentation。 它 MUST 是如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是 如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性, 因为 Verifiable Credential 不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于 出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
,或如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是 如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性, 因为 Verifiable Credential 不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于 出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
proof [object]
包含 challenge 和 domain 的 Data Integrity Proof,如 W3C VC Data Integrity 规范所定义。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
challenge [string]
verifier 选择的值,用于缓解认证 proof 重放攻击。
domain [string]
proof 的 domain,用于将其使用限制到特定 目标。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
400 错误请求
401 未授权
410 已消失!这里没有数据

3.5.4 获取特定 表达

GET /presentations/{id} - 按 ID 获取 presentation 或 verifiable presentation

/presentations/{id} 端点在接收 GET 时可能产生以下任一响应:

响应 主体
200 Credential 已检索
content-type: application/json
不带 proof 的 JSON-LD Verifiable Presentation。它 MUST 是 如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是 如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性, 因为 Verifiable Credential 不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于 出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
,或如下形式的对象:
@context [array]
presentation 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
presentation 的 ID。
type [array]
presentation 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
holder [object]
一个对象
verifiableCredential [array]
Verifiable Credentials。verifiableCredential 数组中的每一项 MUST 是 如下形式的对象:
@context [array]
credential 的 JSON-LD context。 @context 数组中的每一项 MUST 是字符串。
id [string]
credential 的 ID。此属性 MAY 为空。如果 issuer 未提供 id 属性,则 SHOULD NOT 自动生成该属性, 因为 Verifiable Credential 不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [array]
credential 的 JSON-LD type。type 数组中的每一项 MUST 是字符串。
issuer [object]
字符串,或如下形式的对象:
id [string]
issuer id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的 Data Integrity Proof。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
nonce [string]
proof 创建者选择的值,用于 出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
proof [object]
包含 challenge 和 domain 的 Data Integrity Proof,如 W3C VC Data Integrity 规范所定义。它 MUST 是 如下形式的对象:
type [string]
Data Integrity Proof 类型。
cryptosuite [string]
密码套件的名称。
created [string]
proof 创建日期。
challenge [string]
verifier 选择的值,用于缓解认证 proof 重放攻击。
domain [string]
proof 的 domain,用于将其使用限制到特定 目标。
nonce [string]
proof 创建者选择的值,用于出于隐私目的随机化 proof 值。
verificationMethod [string]
用于验证 proof 的 Verification Method。
proofPurpose [string]
proof 的用途,与 verificationMethod 一起使用。
proofValue [string]
Linked Data proof 的值。
400 错误请求
401 未授权
404 未找到 presentation
410 已消失!这里没有数据

3.5.5 删除特定 表达

DELETE /presentations/{id} - 按 ID 删除 presentation 或 verifiable presentation

/presentations/{id} 端点在接收 DELETE 时可能产生以下任一响应:

响应 主体
202 Presentation 已删除——默认使用 202,因为假定会进行软删除并需要处理 时间
400 错误请求
401 未授权
404 未找到 presentation
410 已消失!这里没有数据

3.6 工作流和交换

工作流定义了 用于在跨越信任边界的两方之间交换 可验证凭证的一组特定步骤。每一步都可能涉及 可验证凭证的签发、验证、传输和/或出示。 工作流旨在支持线性的步骤序列,以及包含分支逻辑和重复步骤的 更复杂模式, 从而支持相关各方之间的复杂交互。VC API 工作流的示例包括但不限于以下内容:

工作流实例预计由管理员创建,用于例如协调器网站。 工作流实例通过向工作流服务的 /workflows 端点 执行 HTTP POST 来创建。HTTP 请求主体包含工作流实例的配置。 这包括但不限于定义工作流的步骤信息,以及将用于签发 可验证凭证的任何凭证模板。 定义工作流的步骤也可以是模板, 从而提供额外的灵活性。如果工作流涉及 可验证凭证的签发,或出示或凭证的验证, 则工作流实例配置可以包含用于使用一个或多个签发者和/或验证服务的 授权能力。

一旦工作流实例存在,就可以向协调器授予创建和查询特定 工作流交互的授权,这些交互称为交换。

交换表示基于给定工作流的特定交互。 该交互将在交换客户端和工作流服务之间进行。 交换预计是短暂的,仅在交互完成所需的时间内存在。 工作流服务会存储每个交换的状态信息,例如该交换是 待处理、活动还是已完成,以及工作流中的当前步骤、任何 工作流特定的变量和数据,以及在交换执行期间收到的任何可验证出示和 凭证。除第 3.6.3 创建 交换 中定义的保留变量之外,实现者还可以自由使用 其实现所需的任何变量。虽然技术上对工作流中的步骤数量没有限制, 但实现者可能希望强制执行默认的最大步骤数以防止 bug。

签发者、验证者或持有者协调器负责创建交换。 协调器通过向工作流服务上所选工作流的 /exchanges 子路径执行 HTTP POST 来创建交换。 HTTP 请求主体包含交换的过期日期和时间,以及用于填充该特定 交换的工作流模板的任何变量。请求主体还可以包含配置选项, 以允许使用本 API 之外的其他协议执行该交换。 创建交换后,会向协调器返回一个用于标识该交换并允许与之交互的 交换 URL。

交换 URL 会提供给交换客户端,以便其发起该交换。 请注意,虽然交换 URL 会提供给协调器,再由协调器将其提供给 交换客户端,但实际的交换是在交换客户端和工作流服务之间执行; 协调器在向交换客户端提供交换 URL 后不再参与。 为清楚起见:对于任何需要协调器自身执行交换的用例, 协调器仍然可以使用自己的交换客户端。

发起交换不需要交换 URL 之外的任何授权。 根据工作流服务实现,交换 URL 也可以是能力 URL (即,该 URL 是不可猜测的秘密,因此只有被给予该 URL 的人才能发起交换)。 如果该交换所基于的工作流需要持有交换 URL 之外的任何其他授权, 则应在交换期间获得,而不是在发起时获得。

协调器也可以使用交换 URL 查询交换进展中的当前状态, 并获取工作流服务已存储的与该交换相关的信息。 以这种方式查询交换需要额外授权,协调器预计拥有该授权, 而交换客户端没有。

交换 URL 如何从协调器传输到交换客户端不在本规范范围内。 与客户端共享交换 URL 的已知机制包括 Credential Handler API (又称 CHAPI)、二维码或通用链接。

交换被设计为除了本 API 交换协议之外,还可使用其他协议执行; 例如,交换可能可以使用 OID4VCI、OID4VP、DIDComm 以及 exchange 协议中的任何一种来执行。支持的协议取决于 交换所基于的工作流的复杂性,以及协调器在创建交换时提供的选项。

交换客户端预计会使用与其接收交换 URL 的方式相兼容的协议来发起交换。 例如,交换 URL 可能通过 CHAPI 提供,并带有一个协议标识符, 指示应使用本 API 协议。或者,交换 URL 可以作为 OID4VCI 凭证要约中的 "credential_issuer", 或作为 OID4VP 授权请求中的 "client_id", 分别指示应使用 OID4VCI 或 OID4VP。本节重点说明 交换客户端如何使用本 API 与交换交互;参见 待定附录,以了解如何将交换 与 OID4VCI、OID4VP 和 DIDComm 等其他协议结合使用。

使用本 API 协议执行的交换涉及通过 HTTP 以请求和响应主体形式发送的消息。 每条消息都由一个简单的 JSON 对象组成,其中包含零个或多个以下属性和值:

也可以包含自定义属性和值,但在不识别它们的实现中预计会触发错误。

要使用本 API 协议发起交换,交换客户端会执行 HTTP POST, 将一个 JSON 对象作为请求主体发送。在最简单的情况下,当客户端 对交换没有自己的约束——也就是说,它没有要向另一方请求的内容—— JSON 对象为空({})。工作流服务会在响应主体中以其自己的 JSON 对象进行响应。

如果该响应对象为空,则交换完成,并且没有向交换客户端请求或提供任何内容。 如果该对象包含 verifiablePresentationRequest,则交换尚未完成, 并且会根据关联的可验证出示请求的内容请求一些额外信息。 如果该对象包含 verifiablePresentation,则会提供一些信息, 例如签发给操作交换客户端的持有者的可验证凭证,或基于交换客户端请求 提供的、关于交换服务器运营者的信息的可验证凭证。 如果该对象包含 redirectUrl,则交换完成,并且工作流服务建议客户端 前往另一个位置,以另一种形式继续交互。

许多可验证凭证用例都可以使用这些基本原语实现。 交换的任一方都能够请求可验证出示,并提供一个或多个可能有助于 建立信任和/或获得授权能力的可验证凭证; 任一方也都能够出示他们持有或签发的凭证。 可以配置特定工作流以期望特定的出示和凭证,并拒绝偏离预期信息流的情况。 当工作流服务确定某条特定消息不可接受时,它会通过返回 4xx HTTP 状态 消息和一个表达错误信息的 JSON 对象来引发错误。

交换设计方法是分层的:它旨在提供一个最小的通信消息层和一组原语, 使大多数用例能够通过上一层中的特定可验证出示请求和可验证凭证来实现。 有关使用特定可验证出示请求和可验证凭证的工作流与交换示例, 请参见后续附录。

:工作流步骤 和凭证示例

步骤模板和凭证模板的最小可行示例,以及几个更复杂的工作流模板, 可以在附录 工作流步骤和模板示例 中找到。

与交换的一次给定交互预计是短暂的,但也可以使用其他机制来支持更长或多阶段的交互。 其他交互机制的示例包括短信、电子邮件、Web 通知或电话。 这种方法简化了数字钱包实现,并允许复用现有机制,而无需在本 API 中重新发明。 Web 或原生平台预计会通过应用程序(例如 Web 浏览器)或其他平台功能支持额外交互。 例如,在异步签发中,持有者请求凭证但需要等待处理。 在这种情况下,系统组件(例如签发者协调器)会使用本 API 之外的机制, 在持有者的凭证可供领取时通知持有者。

为需要跨越信任边界的凭证用例使用工作流和交换,定义了以下 API:

端点 描述
POST /workflows 创建新的工作流,并在响应标头中返回工作流元数据的位置。
GET /workflows/{localWorkflowId} 获取现有工作流的配置,并在响应主体中返回。
POST /workflows/{localWorkflowId}/exchanges 创建新的交换,并在响应标头中返回交换元数据的位置。
GET /workflows/{localWorkflowId}/exchanges/{localExchangeId} 获取现有交换的状态,并在响应主体中返回。
POST /workflows/{localWorkflowId}/exchanges/{localExchangeId} 参与交换。提交空主体将启动交换,或返回该交换为完成下一步所期望的内容。 提交可验证出示请求将导致 4xx 错误,或以下之一——符合客户端请求的 可验证出示或可验证出示请求。如果发送了可验证出示,也可以发送额外的 可验证出示请求以继续交换。

在工作流和交换 API 中,“local” ID 指的是相对于服务实例本地的 ID。 换句话说,exchangeIdworkflowId 指的是 完全限定的 URL,而 localExchangeIdlocalWorkflowId 指的是 URL 路径中的特定元素。

3.6.1 创建工作流

POST /workflows - 创建新的工作流,并在响应标头中返回工作流元数据的位置。

/workflows 端点在接收 POST 时使用以下模式:

属性 描述
id [string] 将用于已创建工作流的 ID。传递 ID 是可选的。
initialStep [string] 交换开始时使用的上述步骤集合中的步骤。传递 initialStep 是 必需的。
controller [string] 一个可选属性,用于指定实例的根控制器,该属性可供支持 授权能力(ZCAPs)等依赖对象能力的授权机制的系统使用。 该值可以与 authorization 属性结合使用,以同时允许 其他授权机制。
authorization [object] 一个可选属性,用于指定端点的授权方案信息,例如 OAuth2 配置。 它必须是以下形式的对象:
oauth2 [object]
OAuth2 配置。它必须是以下形式的对象:
issuerConfigUrl [string]
OAuth2 签发者配置 URL。
credentialTemplates [array] 一个数组,其中每一项都必须是以下形式的对象:
id [string]
模板的 ID。
type [string]
模板的类型。
template [string]
模板本身。
steps [object] 完成该工作流上的交换所需的一个或多个步骤。传递 steps 对象是必需的。 键是一个或多个步骤名称,其中每个 STEP_NAME 会替换为某个步骤的名称 (例如 request-employee-id),值是步骤配置。它必须是以下形式的对象:
STEP_NAME [object]
如果未使用模板,则包含步骤数据。它必须是以下形式的对象:
createChallenge [boolean]
一个可选的步骤指令,告诉交换通过其拥有 zcap 的 VCALM 验证者服务来处理质询管理。
verifiablePresentationRequest [object]
一个可验证出示请求。它必须是以下形式的对象:
query [array]
请求者发送的一个或多个查询集合。每个 query 数组中的项都必须是 以下形式的对象:
type [array]
查询的类型。type 数组中的每一项都必须是字符串。
credentialQuery [object]
对于 QueryByExample 查询,指定凭证 请求详情。它必须是 以下形式的对象:
reason [string]
说明为什么请求该凭证的 人类可读解释。
example [object]
一个对象
acceptedIssuers [array]
所请求凭证的可接受签发者。 acceptedIssuers 数组中的 每一项都必须是以下形式的对象:
issuer [string]
acceptedCryptosuites [array]
验证者将接受的密码学证明套件。 每个元素应该是一个带有 cryptosuite 属性的对象, 该属性引用 Data Integrity cryptosuite 名称,或用于旧版的 Ed25519Signature2020 (为向后兼容,也可以使用字符串值, 并将其解释为 cryptosuite 名称)。 这使持有者能够选择合适的 证明格式。此属性可以独立于 acceptedEnvelopes 使用, 后者仅适用于封装凭证。 acceptedCryptosuites 数组中的 每一项都必须是 undefined:
acceptedEnvelopes [array]
验证者将接受的封装格式。 每个元素应该是一个带有 mediaType 属性的对象, 该属性引用封装的媒体类型(为 向后兼容,也可以使用字符串值并将其 解释为媒体类型)。这使持有者能够 以默认 Data Integrity 格式之外的格式 提供凭证。此属性可以独立于 acceptedCryptosuites 使用, 后者仅适用于使用可接受 cryptosuite 签名的 JSON-LD 凭证。 acceptedEnvelopes 数组中的每一项都必须是 undefined:
challenge [string]
由请求者提供的质询,旨在防止重放攻击, 通常预计会包含在可验证出示响应中。
domain [string]
由请求者提供的域,旨在防止重放攻击, 通常预计会包含在可验证出示响应中。
interact [array]
服务器支持的交互机制列表。 interact 数组中的每一项都必须是 以下形式的对象:
service [object]
服务器支持的一项服务,能够接收对 可验证出示请求的响应。它必须是 以下形式的对象:
type [array]
服务的类型。type 数组中的每一项都必须是字符串。
serviceEndpoint [string]
可用于与服务交互以响应 可验证出示请求的 URL。
verifiablePresentation [object]
以下形式的对象:
@context [array]
出示的 JSON-LD 上下文。@context 数组中的每一项都必须是字符串。
id [string]
出示的 ID。
type [array]
出示的 JSON-LD 类型。type 数组中的每一项都必须是字符串。
holder [object]
一个对象
verifiableCredential [array]
可验证凭证。verifiableCredential 数组中的每一项都必须是 以下形式的对象:
@context [array]
凭证的 JSON-LD 上下文。 @context 数组中的每一项 都必须是字符串。
id [string]
凭证的 ID。此属性可以为空。 如果未提供,签发者不应该自动生成 id 属性,因为可验证凭证并不要求 id 属性 有效,并且存在无法设置 id 属性的用例。
type [array]
凭证的 JSON-LD 类型。type 数组中的每一项都必须是字符串。
issuer [object]
一个字符串,或以下形式的对象:
id [string]
签发者 id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的数据完整性证明。 它必须是以下形式的对象:
type [string]
数据完整性证明类型。
cryptosuite [string]
密码学套件的名称。
created [string]
证明创建日期。
nonce [string]
证明创建者选择的一个值,用于出于隐私目的 随机化证明值。
verificationMethod [string]
用于验证证明的验证方法。
proofPurpose [string]
与 verificationMethod 一起使用的证明目的。
proofValue [string]
Linked Data 证明的值。
proof [object]
包含质询和域的数据完整性证明,如 W3C VC Data Integrity 规范所定义。它必须是以下形式的对象:
type [string]
数据完整性证明类型。
cryptosuite [string]
密码学套件的名称。
created [string]
证明创建日期。
challenge [string]
验证者选择的一个值,用于缓解 认证证明重放攻击。
domain [string]
证明的域,用于将其使用限制到 特定目标。
nonce [string]
证明创建者选择的一个值,用于出于隐私目的 随机化证明值。
verificationMethod [string]
用于验证证明的验证方法。
proofPurpose [string]
与 verificationMethod 一起使用的证明目的。
proofValue [string]
Linked Data 证明的值。
redirectUrl [string]
发送给客户端的 URL,可用于在另一个位置继续 交互。传递 redirectUrl 是可选的。
callback [object]
一个回调,将在此步骤执行后被调用。它必须是 以下形式的对象:
url [string]
将接收回调数据的 URL。
issueRequests [array]
issueRequests 数组中的每一项都必须是
{
  "required": [
    "credentialTemplateId"
  ]
}
{
  "required": [
    "credentialTemplateIndex"
  ]
}
presentationSchema
用于描述要对出示执行的验证的 JSON Schema。 它必须是以下形式的对象:
type [string]
该值必须是 JsonSchema
jsonSchema [object]
一个对象
,或是在当前步骤中验证出示时使用的 另一种出示模式格式。对于特定出示模式类型, 预计会有其他属性,但这些属性超出本规范范围。 它必须是以下形式的对象:
type [string]
验证出示时使用的出示模式机制类型。
verifyPresentationResponseSchema
用于描述要对验证出示的结果执行的验证的 JSON Schema。 它必须是以下形式的对象:
type [string]
该值必须是 JsonSchema
jsonSchema [object]
一个对象
,或是在当前步骤中对验证出示的结果使用的 另一种出示模式格式。对于特定出示模式类型, 预计会有其他属性,但这些属性超出本规范范围。 它必须是以下形式的对象:
type [string]
验证出示的结果时使用的出示模式机制类型。
nextStep [string]
序列中下一步的名称。传递 nextStep 是 可选的。此字段不得出现在最终步骤 配置中。
openId [object]
以下之一
{
  "required": [
    "createAuthorizationRequest"
  ],
  "not": {
    "required": [
      "authorizationRequest"
    ]
  }
}
{
  "required": [
    "authorizationRequest"
  ],
  "not": {
    "required": [
      "createAuthorizationRequest"
    ]
  }
}
或以下形式的对象:
clientProfiles [object]
一个对象
或以下形式的对象:
stepTemplate [object]
工作流步骤的模板。必须存在此项或其他步骤数据, 但不能同时存在两组数据。它必须是 以下形式的对象:
type [string]
模板的类型。
template [string]
步骤模板。

/workflows 端点在接收 POST 时可能产生以下任一响应:

响应 主体
201 工作流已成功创建(带数据)
204 工作流已成功创建(不带数据)
400 无效输入
401 未授权
500 内部错误

工作流可以包含有关步骤、凭证模板和授权的信息。 在某些情况下,工作流还会在其配置的不同位置 (通常在凭证模板中)引用保留的 results 变量。 此变量保存工作流服务在交换过程中从客户端接收的数据。 下面是一个基本的工作流配置,其中包含一个 DID Authentication 步骤 和一个凭证交付步骤:

一个步骤可以包含一个 issueRequests 数组,其中包含一个或多个签发 请求对象。每个签发请求对象都会标识要使用的凭证模板, 可以通过其标识符(credentialTemplateId)或通过其 在工作流 credentialTemplates 数组中的索引 (credentialTemplateIndex)来标识。签发请求对象可以还 包含一个 variables 属性,用于提供在评估 凭证模板时使用的值。默认情况下,每个签发请求的结果都会包含 在同一步骤中发送给交换客户端的 可验证 出示中。签发请求对象可以包含一个可选的 result 属性, 其值必须是交换的 variables 对象中的顶层变量名称,或指向交换 variables 对象中任意变量的 JSON 指针,用于标识签发请求结果的 存储位置。这支持更强的组合性,因为后续步骤可以引用 已存储的结果,或者交换可以结束,而拥有交换 状态访问权限的一方可以获取该结果,用于另一个交换或通过其他 机制使用。

示例 12:一个基本工作流
{
  "id": "9fd3bc6d-4a04-4b3d-a983-3482d0586626",
  "initialStep": "didAuthRequest",
  "steps": {
    "didAuthRequest": {
      "createChallenge": true,
      "verifiablePresentationRequest": {
        "query": {
          "type": "DIDAuthentication",
          "acceptedMethods": [
            {
              "method": "key"
            },
            {
              "method": "web"
            }
          ],
          "acceptedCryptosuites": [
            {
              "cryptosuite": "eddsa-rdfc-2022"
            },
            {
              "cryptosuite": "ed25519-2020"
            }
          ]
        },
        "domain": "https://issuer.example.com"
      },
      "nextStep": "credentialDelivery"
    },
    "credentialDelivery": {
      "issueRequests": [
        {
          "credentialTemplateId": "caffb919-053a-4bfa-beba-80567904f842",
          "variables": "sampleAchievementCredential"
        }
      ]
    }
  },
  "credentialTemplates": [
    {
      "id": "caffb919-053a-4bfa-beba-80567904f842",
      "type": "jsonata",
      "template": "{
        \"credential\": {
          \"@context\": [
            \"https://www.w3.org/ns/credentials/v2\",
            \"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json\",
            \"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json\"
          ],
          \"id\": sampleAchievementCredential.id,
          \"type\": [\"VerifiableCredential\", \"AchievementCredential\"],
          \"issuer\": {
            \"type\": [\"Profile\"],
            \"name\": \"Example Issuer\",
            \"image\": {
              \"type\": \"Image\",
              \"id\": \"https://issuer.example.com/logo.png\"
            }
          },
          \"awardedDate\": sampleAchievementCredential.awardedDate,
          \"validFrom\": sampleAchievementCredential.validFrom,
          \"name\": \"Sample Achievement\",
          \"credentialSubject\": {
            \"id\": results.didAuthRequest.verifiablePresentation.holder,
            \"type\": \"AchievementSubject\",
            \"name\": sampleAchievementCredential.credentialSubject.name,
            \"achievement\": {
              \"id\": sampleAchievementCredential.credentialSubject.achievement.id,
              \"type\": [\"Achievement\"],
              \"achievementType\": sampleAchievementCredential.credentialSubject.achievement.achievementType,
              \"name\": sampleAchievementCredential.credentialSubject.achievement.name,
              \"description\": sampleAchievementCredential.credentialSubject.achievement.description,
              \"alignment\": sampleAchievementCredential.credentialSubject.achievement.alignment
            }
          }
        }
      }"
    }
  ],
  "controller": "did:web:issuer.example.com"
}

一个步骤可以包含一个 verifiablePresentation,以明确 表达要在该步骤中使用的 可验证 出示。该出示可以通过交换中的其他变量组合而成, 并且可以附加在该步骤期间可能签发的任何额外 可验证 凭证(依据 issueRequests)。 这支持以下用例:需要特定 可验证 出示版本、需要特定子类型的 可验证 出示,或需要特定 可验证 出示内容,包括要在 工作流步骤中交付的、先前通过带外方式签发的 可验证 凭证

一个步骤可以包含 redirectUrl,用于指定发送给 客户端的 URL,该 URL 可用于在另一个位置继续交互。 其一个用例是在交换完成后将交换客户端的用户送回 协调器网站。另一个用例是返回一个交互 URL,使服务器能够在持续交互期间实现 自定义业务规则,而无需客户端导航到 Web 浏览器。 例如,第一个交换可以向用户请求信息,然后通过 redirectUrl 返回一个 交互 URL。客户端 (例如数字钱包)可以确定它是一个交互 URL(例如, URL 使用 ?iuv=1)并获取它,从而使交互服务器运行 自定义业务逻辑,然后返回一个协议对象,其中包含另一个 用于继续交互的交换。

某些工作流需要在其一个或多个步骤中引用自定义变量。 在这种情况下,协调器在创建交换时需要 为这些变量提供适当的值。 下面是一个带模板化 DID Authentication 步骤的工作流配置示例 (请注意 didAuthRequest 步骤中引用的 verifiablePresentationRequestcallbackUrl 变量):

示例 13:一个模板化工作流
{
  "id": "9fd3bc6d-4a04-4b3d-a983-3482d0586626",
  "initialStep": "didAuthRequest",
  "steps": {
    "didAuthRequest": {
      "stepTemplate": {
        "type": "jsonata",
        "template": "{
          "createChallenge": true,
          "verifiablePresentationRequest": verifiablePresentationRequest,
          "callback": {
            "url": callbackUrl
          },
          "nextStep": "credentialDelivery"
        }"
      }
    },
    "credentialDelivery": {
      "issueRequests": [
        {
          "credentialTemplateId": "caffb919-053a-4bfa-beba-80567904f842",
          "variables": "sampleAchievementCredential"
        }
      ]
    }
  },
  "credentialTemplates": [
    {
      "id": "caffb919-053a-4bfa-beba-80567904f842",
      "type": "jsonata",
      "template": "{
        \"credential\": {
          \"@context\": [
            \"https://www.w3.org/ns/credentials/v2\",
            \"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json\",
            \"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json\"
          ],
          \"id\": sampleAchievementCredential.id,
          \"type\": [\"VerifiableCredential\", \"AchievementCredential\"],
          \"issuer\": {
            \"type\": [\"Profile\"],
            \"name\": \"Example Issuer\",
            \"image\": {
              \"type\": \"Image\",
              \"id\": \"https://issuer.example.com/logo.png\"
            }
          },
          \"awardedDate\": sampleAchievementCredential.awardedDate,
          \"validFrom\": sampleAchievementCredential.validFrom,
          \"name\": \"Sample Achievement\",
          \"credentialSubject\": {
            \"id\": results.didAuthRequest.verifiablePresentation.holder,
            \"type\": \"AchievementSubject\",
            \"name\": sampleAchievementCredential.credentialSubject.name,
            \"achievement\": {
              \"id\": sampleAchievementCredential.credentialSubject.achievement.id,
              \"type\": [\"Achievement\"],
              \"achievementType\": sampleAchievementCredential.credentialSubject.achievement.achievementType,
              \"name\": sampleAchievementCredential.credentialSubject.achievement.name,
              \"description\": sampleAchievementCredential.credentialSubject.achievement.description,
              \"alignment\": sampleAchievementCredential.credentialSubject.achievement.alignment
            }
          }
        }
      }"
    }
  ],
  "controller": "did:web:issuer.example.com"
}

对于 openId 选项,特别是 createAuthorizationRequestauthorizationRequest 值,下面提供的示例 用于帮助开发者理解 OID4VP 授权请求的形式:

示例 14:一个 OID4VP 授权请求
{
  "response_type": "vp_token",
  "presentation_definition": {
    "id": "f1bd224a-0fed-469a-b64a-dad7cf63fd98",
    "input_descriptors": [
      {
        "id": "77d50c71-95ef-442c-a372-f32e17634fab",
        "constraints": {
          "fields": [
            {
              "path": [
                "$['@context']"
              ],
              "filter": {
                "type": "array",
                "contains": {
                  "type": "string",
                  "const": "https://www.w3.org/ns/credentials/v2"
                }
              }
            },
            {
              "path": [
                "$['type']"
              ],
              "filter": {
                "type": "array",
                "contains": {
                  "type": "string",
                  "const": "VerifiableCredential"
                }
              }
            },
            {
              "path": [
                "$['credentialSubject']['name']"
              ],
              "filter": {
                "type": "string"
              }
            }
          ]
        },
        "purpose": "We require a name credential to display your name when you post messages."
      }
    ]
  },
  "response_mode": "direct_post",
  "client_metadata": {
    "vp_formats_supported": {
      "ldp_vc": {
        "proof_type_values": [
          "DataIntegrityProof",
          "Ed25519Signature2020"
        ],
        "cryptosuite_values": [
          "ecdsa-rdfc-2019",
          "eddsa-rdfc-2022"
        ]
      }
    },
    "vp_formats": {
      "jwt_vp": {
        "alg": [
          "EdDSA",
          "Ed25519",
          "ES256",
          "ES384"
        ]
      },
      "jwt_vp_json": {
        "alg": [
          "EdDSA",
          "Ed25519",
          "ES256",
          "ES384"
        ]
      },
      "di_vp": {
        "proof_type": [
          "ecdsa-rdfc-2019",
          "eddsa-rdfc-2022",
          "Ed25519Signature2020"
        ]
      },
      "ldp_vp": {
        "proof_type": [
          "ecdsa-rdfc-2019",
          "eddsa-rdfc-2022",
          "Ed25519Signature2020"
        ]
      }
    }
  },
  "client_id": "https://some.example/workflows/z1A7ojitBF3pGpVzW17MgU7zm/exchanges/z1ACKwiBiXmuGjpKAdKMpBZXB/openid/client/authorization/response",
  "client_id_scheme": "redirect_uri",
  "response_uri": "https://some.example/workflows/z1A7ojitBF3pGpVzW17MgU7zm/exchanges/z1ACKwiBiXmuGjpKAdKMpBZXB/openid/client/authorization/response",
  "nonce": "z1ACKwiBiXmuGjpKAdKMpBZXB"
}

3.6.2 获取工作流配置

GET /workflows/{localWorkflowId} - 获取现有工作流的配置,并在响应主体中返回。

/workflows/{localWorkflowId} 端点在接收 GET 时可能产生以下任一响应:

响应 主体
200 已检索工作流配置!
content-type: application/json
包含工作流相关信息的对象。它必须是以下形式的对象:
id [string]
将用于已创建工作流的 ID。传递 ID 是 可选的。
initialStep [string]
交换开始时使用的上述步骤集合中的步骤。传递 intialStep 是必需的。
controller [string]
实例的控制器。传递 controller 是可选的。
authorization [object]
授权方案信息(例如 OAuth2 配置)。 传递 authorization 是可选的。它必须是 以下形式的对象:
oauth2 [object]
OAuth2 配置。它必须是以下 形式的对象:
issuerConfigUrl [string]
OAuth2 签发者配置 URL。
credentialTemplates [array]
用于凭证签发的一个或多个模板。 template 字符串应渲染为一个对象,该对象包含 credential 字段,用于保存凭证模板, 并且(可选)包含 options 字段,用于保存 重要的凭证签发参数(这是发送到 POST /credentials/issue 的请求主体格式)。 传递 credentialTemplates 是可选的。 credentialTemplates 数组中的每一项都必须是 以下形式的对象:
type [string]
模板的类型。
template [string]
模板本身。
steps [object]
完成该工作流上的交换所需的一个或多个步骤。 键是一个或多个步骤名称,其中每个 STEP_NAME 会 替换为某个步骤的名称(例如 request-employee-id),值是步骤 配置。它必须是以下形式的对象:
STEP_NAME [object]
如果未使用模板,则包含步骤数据。 它必须是以下形式的对象:
createChallenge [boolean]
一个可选的步骤指令,告诉交换 通过其拥有 zcap 的 VCALM 验证者 服务来处理质询管理。
verifiablePresentationRequest [object]
一个可验证出示请求。它必须是 以下形式的对象:
query [array]
请求者发送的一个或多个查询集合。 query 数组中的每一项都必须是 以下形式的对象:
type [array]
查询的类型。 type 数组中的每一项都必须是 字符串。
credentialQuery [object]
对于 QueryByExample 查询, 指定凭证请求 详情。它必须是 以下形式的对象:
reason [string]
说明为什么请求该凭证的 人类可读解释。
example [object]
一个对象
acceptedIssuers [array]
所请求凭证的可接受签发者。 acceptedIssuers 数组中的每一项都必须是 以下形式的对象:
issuer [string]
acceptedCryptosuites [array]
验证者将接受的密码学证明套件。 每个元素应该是一个 带有 cryptosuite 属性的对象,该属性引用 Data Integrity cryptosuite 名称, 或用于旧版的 Ed25519Signature2020 (为向后兼容,也可以使用字符串值, 并将其解释为 cryptosuite 名称)。这 使持有者能够选择 合适的证明格式。 此属性可以独立于 acceptedEnvelopes 使用, 后者仅适用于 封装凭证。 acceptedCryptosuites 数组中的每一项都必须是 undefined:
acceptedEnvelopes [array]
验证者将接受的封装格式。 每个元素应该是一个 带有 mediaType 属性的对象,该属性引用 封装的媒体类型 (为向后兼容,也可以使用字符串值, 并将其解释为媒体 类型)。这使 持有者能够以默认 Data Integrity 格式之外的格式 提供凭证。此 属性可以独立于 acceptedCryptosuites 使用, 后者仅适用于 使用可接受 cryptosuite 签名的 JSON-LD 凭证。 acceptedEnvelopes 数组中的每一项都必须是 undefined:
challenge [string]
由请求者提供的质询,旨在防止 重放攻击,通常预计会包含在 可验证出示响应中。
domain [string]
由请求者提供的域,旨在防止 重放攻击,通常预计会包含在 可验证出示响应中。
interact [array]
服务器支持的交互机制列表。 interact 数组中的每一项都必须是 以下形式的对象:
service [object]
服务器支持的一项服务,能够接收 对可验证 出示请求的响应。它必须是 以下形式的对象:
type [array]
服务的类型。 type 数组中的每一项都必须 是字符串。
serviceEndpoint [string]
可用于与服务交互以 响应可验证 出示请求的 URL。
verifiablePresentation [object]
以下形式的对象:
@context [array]
出示的 JSON-LD 上下文。 @context 数组中的每一项 都必须是字符串。
id [string]
出示的 ID。
type [array]
出示的 JSON-LD 类型。 type 数组中的每一项都必须是 字符串。
holder [object]
一个对象
verifiableCredential [array]
可验证凭证。verifiableCredential 数组中的每一项都必须是以下形式的对象:
@context [array]
凭证的 JSON-LD 上下文。 @context 数组中的每一项都必须是 字符串。
id [string]
凭证的 ID。此 属性可以为空。如果未提供, 签发者不应该自动生成 id 属性,因为 可验证凭证并不 要求 id 属性有效, 并且存在无法设置 id 属性的用例。
type [array]
凭证的 JSON-LD 类型。 type 数组中的每一项都必须是字符串。
issuer [object]
一个字符串,或以下 形式的对象:
id [string]
签发者 id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的数据完整性证明。 它必须是以下形式的对象:
type [string]
数据完整性证明类型。
cryptosuite [string]
密码学套件的名称。
created [string]
证明创建日期。
nonce [string]
证明创建者选择的一个值, 用于出于隐私目的 随机化证明值。
verificationMethod [string]
用于验证证明的验证方法。
proofPurpose [string]
与 verificationMethod 一起使用的 证明目的。
proofValue [string]
Linked Data 证明的值。
proof [object]
包含质询和域的数据完整性证明, 如 W3C VC Data Integrity 规范所定义。 它必须是以下形式的对象:
type [string]
数据完整性证明类型。
cryptosuite [string]
密码学套件的名称。
created [string]
证明创建日期。
challenge [string]
验证者选择的一个值,用于 缓解认证证明重放 攻击。
domain [string]
证明的域,用于将 其使用限制到特定目标。
nonce [string]
证明创建者选择的一个值, 用于出于隐私目的随机化证明值。
verificationMethod [string]
用于验证证明的验证方法。
proofPurpose [string]
与 verificationMethod 一起使用的 证明目的。
proofValue [string]
Linked Data 证明的值。
redirectUrl [string]
发送给客户端的 URL,可用于 在另一个位置继续交互。传递 redirectUrl 是可选的。
callback [object]
一个回调,将在此步骤 执行后被调用。它必须是以下 形式的对象:
url [string]
将接收回调数据的 URL。
issueRequests [array]
issueRequests 数组中的每一项 都必须是
{
  "required": [
    "credentialTemplateId"
  ]
}
{
  "required": [
    "credentialTemplateIndex"
  ]
}
presentationSchema
用于描述要对 出示执行的验证的 JSON Schema。 它必须是以下形式的对象:
type [string]
该值必须是 JsonSchema
jsonSchema [object]
一个对象
,或是在当前 步骤中验证出示时使用的另一种 出示模式格式。对于 特定出示模式类型,预计会有其他属性, 但这些属性超出 本规范范围。它必须是 以下形式的对象:
type [string]
验证出示时使用的 出示模式机制类型。
verifyPresentationResponseSchema
用于描述要对 验证出示的结果执行的验证的 JSON Schema。 它必须是以下 形式的对象:
type [string]
该值必须是 JsonSchema
jsonSchema [object]
一个对象
,或是在当前步骤中对 验证出示的结果使用的另一种 出示模式格式。对于 特定出示模式类型,预计会有其他属性, 但这些属性超出 本规范范围。它必须是 以下形式的对象:
type [string]
验证出示的结果时使用的 出示模式机制类型。
nextStep [string]
序列中下一步的名称。传递 nextStep 是可选的。此字段不得出现在 最终步骤配置中。
openId [object]
以下之一
{
  "required": [
    "createAuthorizationRequest"
  ],
  "not": {
    "required": [
      "authorizationRequest"
    ]
  }
}
{
  "required": [
    "authorizationRequest"
  ],
  "not": {
    "required": [
      "createAuthorizationRequest"
    ]
  }
}
或以下形式的对象:
clientProfiles [object]
一个对象
或以下形式的对象:
stepTemplate [object]
工作流步骤的模板。必须存在 此项或其他步骤数据, 但不能同时存在两组数据。 它必须是以下形式的对象:
type [string]
模板的类型。
template [string]
步骤模板。
400 无效输入
401 未授权
500 内部错误

有一个与交换关联的 expires 属性,用于表示 交换的过期日期和时间。它使用 /workflows/{localWorkflowId}/exchanges 端点创建。这会影响 与此类交换关联的质询的生命周期:如果质询绑定到 交换,则该质询会在交换的 expires 属性所引用的日期失效。

3.6.3 创建交换

POST /workflows/{localWorkflowId}/exchanges - 创建新的交换,并在响应标头中返回 交换元数据的位置。

/workflows/{localWorkflowId}/exchanges 端点在接收 POST 时使用以下模式:

属性 描述
expires [string] 交换过期的日期和时间(表示为 XML Schema dateTimeStamp)。
variables [object] 一个对象
openId [object]
{
  "required": [
    "createAuthorizationRequest"
  ],
  "not": {
    "required": [
      "authorizationRequest"
    ]
  }
}
{
  "required": [
    "authorizationRequest"
  ],
  "not": {
    "required": [
      "createAuthorizationRequest"
    ]
  }
}
或以下形式的对象:
clientProfiles [object]
一个对象

/workflows/{localWorkflowId}/exchanges 端点在接收 POST 时可能产生以下任一响应:

响应 主体
201 交换已成功创建(带数据)
204 交换已成功创建(不带数据)
400 无效输入
401 未授权
500 内部错误

3.6.4 获取交换协议

此端点为客户端提供一种机制,用于查询某个交换支持的所有 协议。单个交换可以支持许多协议, 这些协议能够实现该交换的目标,例如将 可验证 凭证签发到数字钱包中。

GET /workflows/{localWorkflowId}/exchanges/{localExchangeId}/protocols - 获取用于与特定交换 交互的受支持协议。

/workflows/{localWorkflowId}/exchanges/{localExchangeId}/protocols 端点在接收 GET 时可能产生以下 任一响应:

响应 主体
200 交换所理解的协议。
content-type: application/json
包含可用于执行特定交换的协议相关信息的对象。 它必须是以下形式的对象:
protocols [object]
包含一个或多个可用于执行 特定交换的协议的对象。它必须是以下 形式的对象:
interact [string]
可在人参与的交换流程中使用的 URL。 更多详情请参见关于 interact URL 格式 的章节。
vcapi [string]
发起 VCALM 交换时使用的 URL。
OID4VP [string]
发起 OID4VP 出示时使用的 URL。
OID4VCI [string]
发起 OID4VCI 签发时使用的 URL。
400 无效输入
401 未授权
500 内部错误

此端点还使网站运营者能够通过 HTTPS 域将信任委托给 第三方(例如服务提供商),从而将执行交换的权限 委托给该第三方。例如,网站 brand.example 可以通过在协议列表中使用 saas.example 域, 将交换的操作委托给合作伙伴 saas.example

3 钱包使用协议访问委托交换服务的示例。

这使客户端能够依赖其对 brand.example 的信任,将 交换的操作委托给第三方,其方式类似于网站 链接到来自其他域的资源以渲染网页。

3.6.5 参与交换

服务器 MAY 包含一个 referenceId 属性在交换消息中。若客户端收到一个 referenceId,则它 SHOULD 包含相同的 referenceId 。这有助于调试,并确保可能延迟或乱序的消息被链接到正确的请求。 referenceId SHOULD 是一个 urn:uuid: 值。

POST /workflows/{localWorkflowId}/exchanges/{localExchangeId} - 参与交换。提交空主体将启动交换,或返回该交换为完成下一步所期望的内容。提交可验证表达请求将产生 4xx 错误,或以下结果之一:符合客户端请求的可验证表达或可验证表达请求。若发送了可验证表达,也可以发送额外的可验证表达请求以继续该交换。

/workflows/{localWorkflowId}/exchanges/{localExchangeId} 端点在接收 POST 时使用以下模式之一:

属性 描述

或者,/workflows/{localWorkflowId}/exchanges/{localExchangeId} 端点也可以使用以下模式:

属性 描述
verifiablePresentationRequest [对象] 一个可验证表达请求。它 MUST 是如下形式的对象:
query [数组]
请求者发送的一组一个或多个查询。其中的每一项 query 数组 MUST 是如下形式的对象:
type [数组]
查询的类型。其中的每一项 type 数组 MUST 是字符串。
credentialQuery [对象]
对于 QueryByExample 查询,指定凭证请求的详细信息。它 MUST 是如下形式的对象:
reason [字符串]
说明为何请求该凭证的人类可读解释。
example [对象]
一个对象
acceptedIssuers [数组]
所请求凭证的可接受签发者。其中的每一项 acceptedIssuers 数组 MUST 是如下形式的对象:
issuer [字符串]
acceptedCryptosuites [数组]
验证者将接受的加密证明套件。每个元素 SHOULD 是带有 cryptosuite 属性的对象,该属性引用数据完整性密码套件名称,或引用 Ed25519Signature2020 以用于旧版兼容(为向后兼容,也 MAY 使用字符串值,并将其解释为密码套件名称)。这使持有者能够选择适当的证明格式。此属性 MAY 独立于 acceptedEnvelopes,后者仅适用于带封套凭证。其中的每一项 acceptedCryptosuites 数组 MUST 是 undefined:
acceptedEnvelopes [数组]
验证者将接受的封套格式。每个元素 SHOULD 是带有 mediaType 属性的对象,该属性引用封套的媒体类型(为向后兼容,也 MAY 使用字符串值,并将其解释为媒体类型)。这使持有者能够以默认数据完整性格式以外的格式提供凭证。此属性 MAY 独立于 acceptedCryptosuites,后者仅适用于使用可接受密码套件签名的 JSON-LD 凭证。其中的每一项 acceptedEnvelopes 数组 MUST 是 undefined:
challenge [字符串]
一个质询,由请求者提供,旨在防止重放攻击,通常预期会包含在可验证表达响应中。
domain [字符串]
一个域,由请求者提供,旨在防止重放攻击,通常预期会包含在可验证表达响应中。
interact [数组]
服务器支持的交互机制列表。其中的每一项 interact 数组 MUST 是如下形式的对象:
service [对象]
服务器支持且能够接收对可验证表达请求的响应的服务。它 MUST 是如下形式的对象:
type [数组]
服务的类型。其中的每一项 type 数组 MUST 是字符串。
serviceEndpoint [字符串]
可用于与服务交互的 URL,其用途是响应可验证表达请求。
referenceId [字符串] 当服务器先前发送了 referenceId 时,客户端 SHOULD 在此处包含它,以帮助调试和消息关联。该值 SHOULD 是 urn:uuid 值。
属性 描述
verifiablePresentation [对象] 如下形式的对象:
@context [数组]
表达的 JSON-LD 上下文。其中的每一项 @context 数组 MUST 是字符串。
id [字符串]
表达的 ID。
type [数组]
表达的 JSON-LD 类型。其中的每一项 type 数组 MUST 是字符串。
holder [对象]
一个对象
verifiableCredential [数组]
可验证凭证。其中的每一项 verifiableCredential 数组 MUST 是如下形式的对象:
@context [数组]
凭证的 JSON-LD 上下文。其中的每一项 @context 数组 MUST 是字符串。
id [字符串]
凭证的 ID。此属性 MAY 为空。如果未提供,签发者 SHOULD NOT 自动生成 id 属性,因为可验证凭证不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [数组]
凭证的 JSON-LD 类型。其中的每一项 type 数组 MUST 是字符串。
issuer [对象]
字符串或如下形式的对象:
id [字符串]
签发者 ID。
validFrom [字符串]
validFrom 日期
validUntil [字符串]
validUntil 日期
credentialSubject [对象]
一个对象
proof [对象]
W3C VC 数据完整性规范所定义的数据完整性证明。它 MUST 是如下形式的对象:
type [字符串]
数据完整性证明类型。
cryptosuite [字符串]
密码套件的名称。
created [字符串]
证明创建的日期。
nonce [字符串]
证明创建者选择的值,用于出于隐私目的对证明值进行随机化。
verificationMethod [字符串]
用于验证证明的验证方法。
proofPurpose [字符串]
与 verificationMethod 一起使用的证明目的。
proofValue [字符串]
链接数据证明的值。
proof [对象]
包含质询和域的数据完整性证明,如 W3C VC 数据完整性规范所定义。它 MUST 是如下形式的对象:
type [字符串]
数据完整性证明类型。
cryptosuite [字符串]
密码套件的名称。
created [字符串]
证明创建的日期。
challenge [字符串]
验证者选择的值,用于缓解认证证明重放攻击。
domain [字符串]
证明的域,用于将其使用限制到特定目标。
nonce [字符串]
证明创建者选择的值,用于出于隐私目的对证明值进行随机化。
verificationMethod [字符串]
用于验证证明的验证方法。
proofPurpose [字符串]
与 verificationMethod 一起使用的证明目的。
proofValue [字符串]
链接数据证明的值。
referenceId [字符串] 当服务器先前发送了 referenceId 时,客户端 SHOULD 在此处包含它,以帮助调试和消息关联。该值 SHOULD 是 urn:uuid 值。
属性 描述
redirectUrl [字符串] 客户端 MAY 将交互 URL 作为 redirectUrl 发送给服务器,邀请服务器成为另一个相关交换的客户端,并从该交互 URL 开始。服务器 MAY 与此 redirectUrl 交互。
referenceId [字符串] 当服务器先前发送了 referenceId 时,客户端 SHOULD 在此处包含它,以帮助调试和消息关联。该值 SHOULD 是 urn:uuid 值。

/workflows/{localWorkflowId}/exchanges/{localExchangeId} 端点在接收 POST 时可能产生以下任一响应:

响应 主体
200 交换已推进。
content-type: application/json
如下形式的对象:
verifiablePresentationRequest [对象]
一个可验证表达请求。它 MUST 是如下形式的对象:
query [数组]
请求者发送的一组一个或多个查询。其中的每一项 query 数组 MUST 是如下形式的对象:
type [数组]
查询的类型。其中的每一项 type 数组 MUST 是字符串。
credentialQuery [对象]
对于 QueryByExample 查询,指定凭证请求的详细信息。它 MUST 是如下形式的对象:
reason [字符串]
说明为何请求该凭证的人类可读解释。
example [对象]
一个对象
acceptedIssuers [数组]
所请求凭证的可接受签发者。其中的每一项 acceptedIssuers 数组 MUST 是如下形式的对象:
issuer [字符串]
acceptedCryptosuites [数组]
验证者将接受的加密证明套件。每个元素 SHOULD 是带有 cryptosuite 属性的对象,该属性引用数据完整性密码套件名称,或引用 Ed25519Signature2020 以用于旧版兼容(为向后兼容,也 MAY 使用字符串值,并将其解释为密码套件名称)。这使持有者能够选择适当的证明格式。此属性 MAY 独立于 acceptedEnvelopes,后者仅适用于带封套凭证。其中的每一项 acceptedCryptosuites 数组 MUST 是 undefined:
acceptedEnvelopes [数组]
验证者将接受的封套格式。每个元素 SHOULD 是带有 mediaType 属性的对象,该属性引用封套的媒体类型(为向后兼容,也 MAY 使用字符串值,并将其解释为媒体类型)。这使持有者能够以默认数据完整性格式以外的格式提供凭证。此属性 MAY 独立于 acceptedCryptosuites,后者仅适用于使用可接受密码套件签名的 JSON-LD 凭证。其中的每一项 acceptedEnvelopes 数组 MUST 是 undefined:
challenge [字符串]
一个质询,由请求者提供,旨在防止重放攻击,通常预期会包含在可验证表达响应中。
domain [字符串]
一个域,由请求者提供,旨在防止重放攻击,通常预期会包含在可验证表达响应中。
interact [数组]
服务器支持的交互机制列表。其中的每一项 interact 数组 MUST 是如下形式的对象:
service [对象]
服务器支持且能够接收对可验证表达请求的响应的服务。它 MUST 是如下形式的对象:
type [数组]
服务的类型。其中的每一项 type 数组 MUST 是字符串。
serviceEndpoint [字符串]
可用于与服务交互的 URL,其用途是响应可验证表达请求。
referenceId [字符串]
用于关联交换消息的可选标识符。服务器 MAY 包含此值;若存在,客户端 SHOULD 在其下一条消息中包含它。该值 SHOULD 是 urn:uuid 值。
或如下形式的对象:
verifiablePresentation [对象]
如下形式的对象:
@context [数组]
表达的 JSON-LD 上下文。其中的每一项 @context 数组 MUST 是字符串。
id [字符串]
表达的 ID。
type [数组]
表达的 JSON-LD 类型。其中的每一项 type 数组 MUST 是字符串。
holder [对象]
一个对象
verifiableCredential [数组]
可验证凭证。其中的每一项 verifiableCredential 数组 MUST 是如下形式的对象:
@context [数组]
凭证的 JSON-LD 上下文。其中的每一项 @context 数组 MUST 是字符串。
id [字符串]
凭证的 ID。此属性 MAY 为空。如果未提供,签发者 SHOULD NOT 自动生成 id 属性,因为可验证凭证不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [数组]
凭证的 JSON-LD 类型。其中的每一项 type 数组 MUST 是字符串。
issuer [对象]
字符串或如下形式的对象:
id [字符串]
签发者 ID。
validFrom [字符串]
validFrom 日期
validUntil [字符串]
validUntil 日期
credentialSubject [对象]
一个对象
proof [对象]
W3C VC 数据完整性规范所定义的数据完整性证明。它 MUST 是如下形式的对象:
type [字符串]
数据完整性证明类型。
cryptosuite [字符串]
密码套件的名称。
created [字符串]
证明创建的日期。
nonce [字符串]
证明创建者选择的值,用于出于隐私目的对证明值进行随机化。
verificationMethod [字符串]
用于验证证明的验证方法。
proofPurpose [字符串]
与 verificationMethod 一起使用的证明目的。
proofValue [字符串]
链接数据证明的值。
proof [对象]
包含质询和域的数据完整性证明,如 W3C VC 数据完整性规范所定义。它 MUST 是如下形式的对象:
type [字符串]
数据完整性证明类型。
cryptosuite [字符串]
密码套件的名称。
created [字符串]
证明创建的日期。
challenge [字符串]
验证者选择的值,用于缓解认证证明重放攻击。
domain [字符串]
证明的域,用于将其使用限制到特定目标。
nonce [字符串]
证明创建者选择的值,用于出于隐私目的对证明值进行随机化。
verificationMethod [字符串]
用于验证证明的验证方法。
proofPurpose [字符串]
与 verificationMethod 一起使用的证明目的。
proofValue [字符串]
链接数据证明的值。
referenceId [字符串]
用于关联交换消息的可选标识符。服务器 MAY 包含此值;若存在,客户端 SHOULD 在其下一条消息中包含它。该值 SHOULD 是 urn:uuid 值。
如下形式的对象:
redirectUrl [字符串]
交换希望将客户端重定向到的 URL。
referenceId [字符串]
用于关联交换消息的可选标识符。服务器 MAY 包含此值;若存在,客户端 SHOULD 在其下一条消息中包含它。该值 SHOULD 是 urn:uuid 值。
一个不含交换继续属性的对象,表示服务器希望终止该交换。它 MUST 是如下形式的对象:
referenceId [字符串]
用于关联交换消息的可选标识符。服务器 MAY 包含此值;若存在且有下一条消息要发送,则客户端 SHOULD 在其下一条消息中包含它。该值 SHOULD 是 urn:uuid 值。
400 无效输入
401 未授权
500 内部错误

3.6.6 获取交换状态

GET /workflows/{localWorkflowId}/exchanges/{localExchangeId} - 获取现有交换的状态,并在响应主体中返回它。

/workflows/{localWorkflowId}/exchanges/{localExchangeId} 端点在接收 GET 时可能产生以下任一响应:

响应 主体
200 已检索交换配置!
content-type: application/json
包含活动交换相关信息的对象。当给定交换没有要发送的 VP 且没有 redirectUrl 时,它可以是空对象。它 MUST 是如下形式的对象:
id [字符串]
用于标识该交换的本地交换 ID。
sequence [整数]
交换的序列号。创建时设置为 0。
expires [字符串]
交换过期的日期和时间(表示为 XML Schema dateTimeStamp)。
step [字符串]
交换中的当前步骤。
state [字符串]
交换的状态("pending" | "active" | "complete" | "invalid"),创建时设置为 "pending"。
lastError [对象]
如下形式的对象:
type [字符串]
标识问题类型的 URL。
title [字符串]
用于描述该问题的简短但具体的人类可读字符串。
detail [字符串]
用于描述该问题的更长的人类可读字符串。
variables [对象]
交换所需的变量。它 MUST 是如下形式的对象:
results [对象]
来自交换各步骤的结果。它 MUST 是如下形式的对象:
STEP_NAME [对象]
来自交换某个步骤的结果。它 MUST 是如下形式的对象:
verifiablePresentation [对象]
如下形式的对象:
@context [数组]
表达的 JSON-LD 上下文。其中的每一项 @context 数组 MUST 是字符串。
id [字符串]
表达的 ID。
type [数组]
表达的 JSON-LD 类型。其中的每一项 type 数组 MUST 是字符串。
holder [对象]
一个对象
verifiableCredential [数组]
可验证凭证。其中的每一项 verifiableCredential 数组 MUST 是如下形式的对象:
@context [数组]
凭证的 JSON-LD 上下文。其中的每一项 @context 数组 MUST 是字符串。
id [字符串]
凭证的 ID。此属性 MAY 为空。如果未提供,签发者 SHOULD NOT 自动生成 id 属性,因为可验证凭证不要求 id 属性才有效,并且存在无法设置 id 属性的用例。
type [数组]
凭证的 JSON-LD 类型。其中的每一项 type 数组 MUST 是字符串。
issuer [对象]
字符串或如下形式的对象:
id [字符串]
签发者 ID。
validFrom [字符串]
validFrom 日期
validUntil [字符串]
validUntil 日期
credentialSubject [对象]
一个对象
proof [对象]
W3C VC 数据完整性规范所定义的数据完整性证明。它 MUST 是如下形式的对象:
type [字符串]
数据完整性证明类型。
cryptosuite [字符串]
密码套件的名称。
created [字符串]
证明创建的日期。
nonce [字符串]
证明创建者选择的值,用于出于隐私目的对证明值进行随机化。
verificationMethod [字符串]
用于验证证明的验证方法。
proofPurpose [字符串]
与 verificationMethod 一起使用的证明目的。
proofValue [字符串]
链接数据证明的值。
proof [对象]
包含质询和域的数据完整性证明,如 W3C VC 数据完整性规范所定义。它 MUST 是如下形式的对象:
type [字符串]
数据完整性证明类型。
cryptosuite [字符串]
密码套件的名称。
created [字符串]
证明创建的日期。
challenge [字符串]
验证者选择的值,用于缓解认证证明重放攻击。
domain [字符串]
证明的域,用于将其使用限制到特定目标。
nonce [字符串]
证明创建者选择的值,用于出于隐私目的对证明值进行随机化。
verificationMethod [字符串]
用于验证证明的验证方法。
proofPurpose [字符串]
与 verificationMethod 一起使用的证明目的。
proofValue [字符串]
链接数据证明的值。
openId [对象]
来自 OID4VCI/OID4VP 持有者交互的结果。它 MUST 是如下形式的对象:
clientProfileId [对象]
一个对象
authorizationResponse [对象]
一个对象
presentationSubmission [对象]
一个对象
inviteRequest [对象]
来自邀请请求的结果。它 MUST 是如下形式的对象:
inviteResponse [对象]
对邀请请求的响应,指示将持有者重定向到何处。它 MUST 是如下形式的对象:
url [字符串]
交换应继续进行的 URL。
purpose [字符串]
交互描述。
referenceId [字符串]
邀请请求的唯一 ID。
400 无效输入
401 未授权
500 内部错误

3.6.7 交换步骤回调

POST /callbacks/{localCallbackId} - 一种回调,可以是任何能力 URL(即难以猜测的 URL),当执行交换步骤时可以收到通知。该 URL SHOULD 是能力 URL,以确保它只能由被共享该 URL 的各方使用,而无需授权令牌、周期性令牌刷新或客户端注册。若使用带有 "localCallbackId" 的建议 URL 格式,则 "localCallbackId" 值必须表达至少 128 位随机信息,以确保完整回调 URL 可被视为能力 URL。还建议为每个交换创建新的能力 URL,并且仅由该交换使用。

/callbacks/{localCallbackId} 端点在接收 POST 时使用以下模式:

属性 描述
event [对象] 与回调关联的事件信息。它 MUST 是如下形式的对象:
data [对象]
与回调关联的事件数据。它 MUST 是如下形式的对象:
exchangeId [字符串]
指向交换状态的 URL,可用于检索该交换的当前状态。

/callbacks/{localCallbackId} 端点在接收 POST 时可能产生以下任一响应:

响应 主体
200 已接收回调数据。
400 未接收回调数据。

3.6.8 交换示例

本规范中的 API 使得可以执行无中介(自动化、机器到机器)或有中介(人在环路中)的交换。这些交换由 持有者协调器 发起,并由实现交换的任何协调器响应。流程由以下步骤组成:

  1. 持有者协调器 联系接收方协调器,以请求启动特定交换。
  2. 接收方协调器以某种表达请求进行响应,以认证和/或授权 持有者协调器 并以 URL 形式提供交换中的下一跳。
  3. 持有者协调器 以包含满足表达请求的信息的可验证表达响应接收方协调器。
  4. 接收方协调器使用带有新签发可验证凭证的可验证表达,或如上文步骤 2 所述的进一步表达请求进行响应。

持有者协调器 MAY 调用协调器的交换发现端点,以确定 持有者协调器 是否支持协调器在特定端点上的协议要求,然后再实际启动交换。

上述步骤的图示如下:

4 一个 持有者签发者/验证者.

上述通用交换可以以完全自动化、由人中介,或以混合方式执行;在混合方式中,部分流程是自动化的,但在某些阶段需要人的交互。上述第二步用于提供指引,说明下一步是自动化的,还是需要个人介入。

下图展示了一种交换,其中 持有者协调器 以可验证表达请求发起,要求接收方协调器提供凭证后才继续:

5 一种由客户端发起的交换,其中 持有者签发者/验证者 请求凭证后才继续。

下图展示了一种交换,其中 持有者协调器 在收到服务器的初始请求后发送反向请求:

6 一种交换中途的反向请求,其中 持有者签发者/验证者 在收到服务器的初始请求后请求凭证。

以下示例演示交换客户端使用 verifiablePresentationRequest 发起交换,该请求指定其将接受哪些加密证明格式和封套类型。若 credentialQuery 属性不存在,则交换客户端将接受来自工作流服务、匹配指定格式的任何凭证。

示例 15:带有可接受格式的客户端发起交换
{
  "verifiablePresentationRequest": {
    "query": [{
      "type": "QueryByExample",
      "credentialQuery": {
        "acceptedCryptosuites": [
          {"cryptosuite": "eddsa-rdfc-2022"},
          {"cryptosuite": "ecdsa-rdfc-2019"},
          {"cryptosuite": "bbs-2023"}
        ],
        "acceptedEnvelopes": [
          {"mediaType": "application/jwt"}
        ]
      }
    }]
  }
}

以下示例演示交换客户端在满足任何后续请求之前,先向工作流服务请求凭证。在此场景中,交换客户端在共享个人信息之前,需要证明服务器运营者是注册企业。

示例 16:客户端在继续之前请求服务器凭证
{
  "verifiablePresentationRequest": {
    "query": [{
      "type": "QueryByExample",
      "credentialQuery": {
        "reason": "Please present your BusinessRegistrationCredential to complete the verification process.",
        "example": {
          "@context": [
            "https://www.w3.org/ns/credentials/v2"
          ],
          "type": ["BusinessRegistrationCredential"]
        },
        "acceptedCryptosuites": [
          {"cryptosuite": "eddsa-rdfc-2022"}
        ]
      }
    }]
  }
}

3.7 启动交互

对于一个实现来说,向另一个实现传达如何开始与其交互是有用的。这个引导过程称为 启动一次交互,它会传达每个实现支持哪些 协议,以及如何与该实现开始一次特定的交互。

:交互 与应用、用例和协议无关

虽然本文档中包含若干交互规范,但其通用方法并不依赖于用例、应用或协议。此方法 可用于配对两个或更多希望引导进入特定协议的应用,而不受任何传输媒介限制——例如 Web 浏览器、QR 码(光学媒介)或 NFC(无线媒介)——并且该协议 不需要涉及此 API。

下面的序列图概述了一个签发者生成交互 URL、使用 QR 码与持有者共享它,并继续使用 vcapi 协议的过程:

7 使用 QR 码由签发者发起的交互

下面的序列图概述了一个验证者生成交互 URL、使用 QR 码与持有者共享它,并继续使用 vcapi 协议的过程:

8 使用 QR 码由验证者发起的交互

下面的序列图概述了一个持有者生成交互 URL, 使用 QR 码与验证者共享它,并继续使用 inviteRequest 协议的过程:

9 使用 QR 码由持有者发起的交互

3.7.1 交互 URL 格式

交互 URL 的格式必须符合 URL 标准 的语法,并包含一个 iuv 查询参数,用于编码交互 URL 版本号;在使用此版本的本 API 时,该版本号必须1。 交互 URL 应该是一个 HTTPS URL,并包含一个特定于交互的 标识符。该 URL 应该是不透明的,并且在接收系统获取它之前, 不需要进行 URL 语法处理。此类 URL 的示例如下:

示例 17:一个交互 URL
https://app.example/interactions/z8n38Dp7a?iuv=1

将较长的协议特定信息编码到 URL 中的协议,会受到软件库对 URL 最大允许长度所施加的限制。在撰写本文时,建议的 URL 长度限制约为 2,000 个字符。实现者不应该把可以在对交互 URL 的 GET 请求响应中表达的信息(该响应在第 3.7.4 交互协议响应中定义)放入 交互 URL 的查询参数中。

:交互 URL 位于协调器上,而不是工作流服务上

协调器可以自由地将交互 URL 放在其 Web 源上的任意位置,因为消费软件预计会将其视为不透明的 (iuv 查询参数除外)。 但是,重要的是交互 URL 应托管在协调器上,而不是托管在 工作流服务上。这使协调器的 Web 源(DNS 域名)能够被消费者用作 一致的信任信号,并用于应用可能调节操作的业务规则。

3.7.2 交互 QR 码格式

交互 QR 码必须是一个交互 URL, 并按照 ISO18004:2024:QR Code Bar Code Symbology Specification 表示为 QR 码。为确保广泛的 互操作性,交互 URL 的长度应该尽可能短,不应该超过 400 个字母数字字符,并且不得超过 4,296 个字母数字字符。下面给出了一个交互 QR 码的示例:

一个由黑白点填充的正方形图像,其中编码了
一个交互 URL
10 https://app.example/interactions/z8n38Dp7a?iuv=1 的交互 QR 码

3.7.3 交互方案格式

调用一个能够处理 交互 URL 的应用可能很有用。本节为此目的定义了一个 interaction: 协议方案 格式。协议方案的格式必须符合以下语法:

交互协议方案
scheme          = "interaction:" interaction-url
interaction-url = URL

interaction-url 是任何符合 URL 标准 的 URL,并且 检索该 URL 处的资源会得到一个 交互协议响应

示例 18:一个交互方案 URL 的示例
interaction:https://app.example/interactions/z8n38Dp7a?iuv=1

3.7.4 交互协议 响应

交互 URL执行检索,会得到关于 如何开始与远程系统交互的说明。

当使用值为 application/jsonAccept 标头获取交互 URL 时, 必须返回一个包含 protocols 映射的单个 JSON 对象, 其中每个 都是协议标识符,并且每个 都是可用于 发起该交互的 URL。例如,对 https://app.example/interactions/z8n38Dp7a?iuv=1 交互 URL执行 HTTP GET,可能会得到以下任一响应:

示例 19:给定交互所支持的协议列表,其中 inviteRequest 由正在使用的工作流服务生成。
{
  "protocols": {
    "inviteRequest": "https://saas.example/workflows/123/exchanges/987/invite-request/response",
    "vcapi": "https://saas.example/workflows/123/exchanges/987",
    "OID4VP": "openid4vp://?client_id=https%3A%2F%2Fapp.example%2Fworkflows%2F123%2Fexchanges%2F987%2Fopenid%2Fclient%2Fauthorization%2Fresponse&request_uri=https%3A%2F%2Fapp.example%2Fworkflows%2F123%2Fexchanges%2F987%2Fopenid%2Fclient%2Fauthorization%2Frequest'"
  }
}
示例 20:协议列表仅包含 inviteRequest 选项的退化情形。
{
  "protocols": {
    "inviteRequest": "https://saas.example/interactions/123/invite-request/response"
  }
}

协议响应使协议执行能够通过 HTTPS 域信任模型委托给第三方 服务提供商,这类似于获取 交换协议一节中描述的委托机制。例如,网站 app.example 可以 通过在协议列表中包含 saas.example 域,将交换的操作委托给 合作伙伴 saas.example

当使用任何无法识别的 Accept 标头获取交互 URL 时, 必须返回一个 text/html 文档,其中包含指示人类 使用特定软件的说明,该软件知道如何处理交互 URL。

:映射到 交换 URL

一些协调器实现会将 protocols 端点实现为到某个交换实例的 protocols 端点的透传。 例如,对 https://app.example/interactions/z8n38Dp7a?iuv=1 执行 GET,会导致对 https://app.example/workflows/123/exchanges/987/protocols 的透传 GET,后者将返回上面的响应。以这种方式实现交互 URL 可以提供更容易的实现路径。

3.7.5 inviteRequest 交互协议

inviteRequest 交互协议由本地系统使用,用于通过特定 URL 向远程系统表示它希望获得前往远程系统的邀请,例如前往一个个人可以参与 用例特定交互的网站。如果选择了 inviteRequest 交互协议, 本地系统会使用 HTTP POST 发送数据,以指示远程系统 应该将该个人发送到哪里。下面展示了几个 POST 数据示例。 这些示例旨在强调,本规范并未规定 "url" 字段应如何格式化, 但确实建议此交互机制的实现者使用唯一 ID:

示例 21:对邀请请求的响应,用于在商店结账
{
  "url": "https://website.example/checkout/8372974",
  "purpose": "Checkout at ShopCo",
  "referenceId": "417bcaf2-14d9-11f0-99d7-9f094678517b"
}
示例 22:对邀请请求的响应,用于填写在线表单
{
  "url": "https://website.example/forms/7864165",
  "purpose": "Fill out online form",
  "referenceId": "d4a6e5b8-1715-4654-8e47-e68b311756d1"
}

3.7.6 vcapi 交互协议

vcapi 交互协议用于发起一个特定交换, 如第 3.6.5 参与交换所述。

示例 23:一个 VC-API 交互协议请求
{
  "verifiablePresentationRequest": {
    "query": [{
      "type": "QueryByExample",
      "credentialQuery": {
        "reason": "Please provide your student ID.",
        "example": {
          "@context": [
            "https://www.w3.org/ns/credentials/v2",
            "https://www.w3.org/ns/credentials/examples/v2",
          ],
          "type": "StudentIdCredential",
          "credentialSubject": {
            "studentId": ""
          },
        },
        "trustedIssuer": [{
          "issuer": "did:web:university.example"
        }]
      }
    }],
    "challenge": "5e34826e-14da-11f0-98a5-8b1c0a196728",
    "domain": "university.example"
  }
}

3.8 错误处理

当一个实现在处理文档时检测到异常时,可以使用 ProblemDetails 对象向其他 软件系统报告该问题。这些对象的接口遵循 [RFC9457] 来编码数据。一个 ProblemDetails 映射由以下 属性组成:

type
type 必须存在,并且其值必须是一个用于 标识问题类型的 URL。
title
title 应该为该问题提供一个简短但具体的人类可读 字符串。
detail
detail 应该为该 问题提供一个更长的人类可读字符串。

鼓励利用 (例如 detailinstance)来 提供有关错误的更多上下文反馈,同时注意 安全问题,因此不要披露敏感信息。

本规范定义了以下问题描述类型:

https://www.w3.org/TR/vcalm#UNKNOWN_OPTION_PROVIDED
向 API 调用提供了一个实现未知的选项。

实现可能报告的其他 ProblemDetails 列表 可在以下规范中找到:

示例 24:一个 ProblemDetails 对象示例
{
  "type": "https://www.w3.org/TR/vc-data-model#CRYPTOGRAPHIC_SECURITY_ERROR",
  "status": 400,
  "title": "CRYPTOGRAPHIC_SECURITY_ERROR",
  "detail": "The cryptographic security mechanism couldn't be verified. This is likely due to a malformed proof or an invalid verificationMethod."
}
议题 3

上述示例 type URL 将在 VCDM v2.0 成为 全球标准之后生效。为确保错误链接到适当的位置,你可以 暂时将 https://www.w3.org/TR/vc-data-model 的基 URL 替换为 www.w3.org/TR/vc-data-model-2.0

强烈建议实现者在生产环境中清理所有服务器错误, 因为不这样做可能导致信息披露。

建议在执行验证时避免抛出错误,而是 收集 ProblemDetails 对象并将其包含在验证结果中。

3.8.1 验证错误 与警告

本规范定义了验证错误和验证警告之间的区别。 错误是与密码学、数据模型以及格式不正确的上下文相关的 ProblemDetails,并且不可恢复。警告是 与状态和有效期相关的 ProblemDetails,并且可能是 可恢复的,或将后续操作留给应用自行决定。

如果包含错误,则 VerificationResponse 对象的 verified 属性必须设置为 false; 如果不包含错误,则该属性必须设置为 true

示例 25:包含警告和错误的验证响应示例。
{
  "verified": false,
  "document": verifiableCredential,
  "mediaType": "application/vc",
  "controller": issuer,
  "controllerDocument": didDocument,
  "warnings": [ProblemDetails],
  "errors": [ProblemDetails]
}

A. 隐私注意事项

A.1 委托

可验证凭证 [VC-DATA-MODEL-2.0] 是一种标准数据 模型, 旨在降低误用和欺诈风险。作为一种数据模型,可验证 凭证与协议无关,并且至少考虑两类 实体:签发者主体。 当可验证 凭证的主体是自然人或与自然人相关联时,与其模拟 祖先相比,对标准化可验证凭证 高效得多的处理可能会影响隐私和 人权。

以用于签发可验证 凭证的标准化 API 和协议形式出现的技术,进一步提升了处理 可验证凭证 的效率,并增加了不可预见的隐私和 人权后果的风险。

可验证凭证 签发包含请求阶段和交付阶段。 请求可能由主体或其他角色发起,而 交付 可以交付给一个可能由主体控制、也可能不由主体控制的客户端。 委托与两个阶段都高度相关。签发者可能会将 请求处理委托给单独的实体。主体也可能将请求 可验证凭证 的能力委托给 单独的实体。请注意,主体并不总是具有执行委托的能力或 条件。示例包括新生儿、宠物以及 患有痴呆症的人。因此,请求可能由并非 由主体委托的第三方执行。委托能力是提升 可验证凭证 处理效率的第三个维度,并且会对 隐私和人权产生影响。

本规范中描述的架构旨在通过效率与对隐私和 人权的尊重相结合来获得市场接受度。用于处理 可验证凭证 的 API 和协议并不会 偏向签发者角色的委托,而轻视主体角色的委托。

A.2 “回拨归属方”被认为 有害

验证者就某个特定 签发者联系 可验证凭证的 签发者,被认为是一种不良的隐私实践。这 种实践被称为“回拨归属方”,并可能导致 持有者签发者验证者以及 可验证凭证中表达的其他各方之间 的隐私预期不匹配。 回拨归属方使签发者能够将毫无戒备的各方与 某些可验证凭证的使用相关联, 这可能违反各实体对这些凭证使用方式的 隐私预期。例如,持有者预期这是他们与 验证者之间的私密交互,却变成 签发者会 获知该交互的情况。

某些交互中,以保护隐私的方式联系签发者可以维护 持有者的隐私预期。 例如,以尊重隐私的方式联系签发者以获取撤销状态 信息, 例如通过提供群体隐私的状态列表,只要签发者无法基于 对状态列表的检索而识别正在查询的是哪一个可验证凭证, 就可以接受。有关一种此类机制的更多信息, 请参见 位串状态列表 v1.0 规范。

敦促验证者 不要以会造成隐私侵犯的方式“回拨归属方”。在检索 可验证凭证中链接的内容时, 使用 Oblivious HTTP 等机制并 积极缓存结果,可以提升生态系统的隐私特性。

B. 安全注意事项

B.1 未知证明类型

持有者协调器实现(例如数字 钱包软件)可以 接收和存储包含软件无法理解的可验证凭证 证明,但是这些 证明不得由 该实现进行出示。一个包含多个可验证凭证 证明的凭证,其中一些 该实现理解而另一些不理解,只要所选证明为实现所理解, 且其他证明在出示之前被移除,就可以由该实现 出示。 实现会维护所理解证明的允许列表,并确保 任何不在允许列表中的证明 在出示前被剥离。

在去中心化生态系统中,实现可以将未知证明的存在 用作潜在的采用信号。实现者还必须理解,在 三方模型中,持有者 协调器充当签发者验证者之间的通道, 即使/当持有者 协调器不一定实现某些验证所需的 证明,也能使二者实现互操作。作为另一个领域中的示例: “Web 浏览器在添加自己的 PDF 阅读器 功能之前,就已经能够下载和存储 PDF 文件”——这种去中心化创新、互操作性和 渐进增强对于三方模型以及更广泛的可扩展去中心化生态系统都很 重要。通过不强迫人们仅仅为了存储带有至少一个 其当前软件尚不理解的证明的可验证凭证 而采用特定的新型不同软件,也有助于减少中心化。

即使没有用于验证某些证明的软件, 持有者协调器也可能能够出示这些证明中的一部分, 但这需要被确定地理解,而不是猜测。也就是说, 当把已存储可验证凭证 的副本添加到出示中时, 持有者软件 需要移除任何其并不明确知道可以安全出示的证明。 软件明确知道可以 安全出示的任何证明 都可以保留。例如,能够验证 ecdsa-rdfc-2019 证明但不能验证 ecdsa-jcs-2019 证明的数字钱包,仍然可以 出示其中任一种。其他证明, 例如提供选择性披露 和 / 或不可关联披露 特性的证明,需要 转换(也就是说, 基础证明会转换为派生证明加上“披露文档”),并且 因此,除非钱包已经实现了 派生证明的过程,否则钱包将无法出示这些证明。 钱包不得意外出示基础证明,这一点至关重要,因为它可能包含对持有者保密的信息。

B.2 对交互 URL 使用 HTTPS

本规范强烈建议将 HTTPS 用于交互 URL, 原因如下:

使用并非根植于 HTTPS 信任模型的协议方案,需要使用 单独的加密协议、密钥管理和信任模型,这些模型 通常开发和部署不够广泛,并且需要更多开发 和分析来确定威胁与隐私模型。

B.3 删除

本规范提供的 API 支持从 可验证凭证可验证 出示中删除 存储服务中的数据。这些删除的结果 以及它们可能造成的副作用不在本规范范围内。 但是,建议实现者了解删除可以 实现的各种方式。本规范至少考虑了两类删除。

部分 删除会将记录标记为待删除,但继续存储 原始信息的一部分或全部。如果对特定时间段内的所有凭证和/或出示 存在审计要求,或者如果恢复原始凭证可能是一个 有用功能,则这种操作模式可能很有用。

完全 删除会以不可恢复的方式清除与给定 可验证凭证可验证 出示相关的所有信息。当移除已经过时且超出任何审计需要的信息, 或响应任何类型的“被遗忘权” 请求时,这种操作模式可能很有用。

删除可验证凭证时, 需要考虑其状态 信息的处理。某些用例可能要求删除 某个特定可验证凭证 同时设置该可验证凭证的撤销 和暂停位, 使得对已删除凭证执行的任何类型 状态检查都会失败,并停止使用该凭证。

鉴于上述场景,建议实现者允许在删除后发生的系统操作 可配置,使系统灵活性足以 处理任何可验证凭证 用例。

B.4 载荷大小

较大的事务可能触发 DoS 事件。建议在实例级别配置 端点接受的载荷大小。

B.5 额外验证

在大多数情况下,仅验证证明可能不足以正确 处理接收到的数据。验证者服务预计会 根据其用例配置额外的 验证步骤。为定义此类额外 验证,实现者可以参考诸如 第 2.3 节:资源 完整性第 2.4 节: 上下文与词汇表 等规范,这些内容位于 可验证凭证数据完整性 1.0 规范中,其中可找到有关上下文处理和完整性验证的 更多信息。

不恰当的验证通常会导致安全漏洞。

通过问题详情返回验证响应对象时,可以说明 额外验证步骤。

B.6 安全编码实践

敦促实现者在实现本规范时使用行业标准的安全编码实践。 即使经验丰富的软件开发者也可能犯错,而使用安全编码清单和漏洞扫描 软件可以捕获可能导致安全妥协的错误。遵循 OWASP 安全编码实践清单 OWASP Web 安全测试指南等清单和指南,有助于降低 不安全实现的可能性。

B.7 其他安全注意事项

由于本规范描述的用于管理可验证凭证 生命周期的接口具有通用性质,其使用所带来的安全 影响可能并不会立即为读者所显见。 为理解在完整软件系统中可能需要考虑的安全 关注点,实现者被敦促阅读 可验证凭证数据模型 v2.0 规范中关于这种技术可如何使用的内容(特别是 可验证凭证安全注意事项一节),以及 可验证凭证数据完整性 1.0 规范(特别是 数据完整性安全注意事项一节)。

C. 状态列表管理

状态服务提供三个用于管理状态列表的主要操作:

:非规范性 状态列表操作

本规范中描述的状态列表操作(创建列表、获取列表 和设置状态)是非规范性的,并代表一种推荐的 实现方法。状态列表的创建和管理可能取决于本规范中未考虑的 各种因素,例如:

  • 特定于签发者或用例的业务需求和策略
  • 性能考虑,例如列表大小、更新频率和缓存策略
  • 基础设施约束,包括存储容量和托管能力
  • 可能影响状态信息管理方式的法规或合规要求
  • 与现有凭证管理系统或工作流的集成

只要生成的状态信息能够按照正在使用的状态机制规范(例如 位串状态列表 v1.0 规范)进行验证,实现者就可以根据 其具体需要自由设计状态列表管理系统。

为最大化隐私,鼓励验证者持有者处获取 状态信息,而不是 直接查询状态服务。当持有者 出示可验证凭证时, 鼓励其包含相应的 状态列表凭证或足够的状态信息,以便无需 验证者联系签发者即可完成验证。这种 方法 可以防止将状态检查与特定验证者可验证 凭证相关联。

C.1 创建状态列表

此端点用于创建新的状态列表凭证,可用于 跟踪可验证 凭证的状态。状态列表本身是一个 可验证凭证, 其中包含多个凭证的状态信息, 从而支持保护隐私的状态检查。状态列表凭证 会在响应中返回,并可公开访问以用于验证 目的。

为保持验证过程一致,状态列表凭证通常使用 与其将关联到的可验证凭证 相同的安全机制(证明类型和密码学套件)。这使验证者能够使用相同的验证方法 验证凭证及其关联的状态列表。

对于管理可验证凭证 状态的具体机制, 鼓励实现者参考知名的外部规范,例如 [VC-BITSTRING-STATUS-LIST] 规范,该规范 提供了如何实现状态列表凭证的规范性 示例。

POST /status-lists - 创建新的状态列表

/status-lists 端点在接收 POST 时使用以下模式:

属性 描述
statusPurpose [string] 状态列表的用途(例如 "revocation"、"suspension")。这决定了列表将跟踪 哪种类型的状态信息。
id [string] 状态列表的可选标识符。如果未提供,服务将生成一个。
options [object] 一个对象

/status-lists 端点在接收 POST 时可能产生以下任一响应:

响应 主体
201 状态列表已成功创建
content-type: application/json
以下形式的对象:
verifiableCredential [object]
以下形式的对象:
@context [array]
凭证的 JSON-LD 上下文。@context 数组中的每一项都必须是字符串。
id [string]
凭证的 ID。此属性可以为空。若未提供, 签发者不应该自动生成 id 属性,因为 可验证凭证并不要求 id 属性有效, 并且存在无法设置 id 属性的用例。
type [array]
凭证的 JSON-LD 类型。type 数组中的每一项都必须是字符串。
issuer [object]
字符串,或以下形式的对象:
id [string]
签发者 id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的数据完整性证明。 它必须是以下形式的对象:
type [string]
数据完整性证明类型。
cryptosuite [string]
密码学套件的名称。
created [string]
证明创建日期。
nonce [string]
证明创建者选择的一个值,用于出于隐私目的 随机化证明值。
verificationMethod [string]
用于验证证明的验证方法。
proofPurpose [string]
与 verificationMethod 一起使用的证明目的。
proofValue [string]
Linked Data 证明的值。
id [string]
已创建状态列表凭证的标识符,可用于 通过 GET 端点检索它。
400 错误请求

C.2 获取状态列表

此端点检索可公开访问的状态列表凭证。该 端点通常无需身份认证即可公开访问,以使 验证者持有者能够 检索状态信息。

该端点会根据所请求的媒体类型或服务配置的默认格式 以适当格式返回状态列表凭证。响应通常是 VerifiableCredentialEnvelopedVerifiableCredential,与引用该状态列表的 可验证凭证 所使用的格式一致。这允许 验证者使用与验证关联凭证相同的机制来 处理状态列表。

: 保护隐私的状态检索

对于保护隐私的状态机制,鼓励验证者持有者处获取状态 信息,而不是直接 查询此端点。当 持有者 出示包含状态信息 (例如 credentialStatus 属性)的可验证 凭证时,鼓励持有者也 提供相应的状态列表凭证或足够的状态信息,以便 进行验证。这种方法可以防止签发者将状态 检查与特定验证者可验证 凭证相关联,从而 保护隐私。

验证者 需要检查可验证凭证的状态时, 推荐流程如下:

  1. 验证者持有者请求一个可验证 出示
  2. 持有者 在出示中包含可验证 凭证以及 相应的状态列表凭证或状态信息。
  3. 验证者使用 持有者 提供的信息验证状态, 而无需直接联系签发者

此端点也可能对需要检索状态列表凭证以包含在出示中的持有者有用,或适用于从隐私角度来看 直接联系签发者可接受的情况。

GET /status-lists/{id} - 检索状态列表凭证

/status-lists/{id} 端点在接收 GET 时可能产生以下任一响应:

响应 主体
200 状态列表凭证已成功检索
content-type: application/json
以下形式的对象:
@context [array]
凭证的 JSON-LD 上下文。@context 数组中的每一项都必须是字符串。
id [string]
凭证的 ID。此属性可以为空。若未提供,签发者不应该 自动生成 id 属性,因为可验证 凭证并不要求 id 属性有效,并且存在 无法设置 id 属性的用例。
type [array]
凭证的 JSON-LD 类型。type 数组中的每一项都必须是字符串。
issuer [object]
字符串,或以下形式的对象:
id [string]
签发者 id。
validFrom [string]
validFrom 日期
validUntil [string]
validUntil 日期
credentialSubject [object]
一个对象
proof [object]
由 W3C VC Data Integrity 规范定义的数据完整性证明。 它必须是以下形式的对象:
type [string]
数据完整性证明类型。
cryptosuite [string]
密码学套件的名称。
created [string]
证明创建日期。
nonce [string]
证明创建者选择的一个值,用于出于隐私目的 随机化证明值。
verificationMethod [string]
用于验证证明的验证方法。
proofPurpose [string]
与 verificationMethod 一起使用的证明目的。
proofValue [string]
Linked Data 证明的值。
404 未找到状态列表

C.3 更新状态

此端点用于更新已签发可验证凭证 在状态列表中的状态。当凭证状态需要变更(例如被撤销 或暂停)时,此端点会更新状态列表 凭证中的相应条目。

请求通常会指定要更新的凭证、状态列表条目 信息(包括状态列表凭证标识符和该列表中的索引), 以及新的状态值。状态服务会相应地更新状态 列表凭证。

POST /credentials/status - 更新已签发凭证的状态

/credentials/status 端点在接收 POST 时使用以下模式:

属性 描述
credentialId [string] 标识凭证(该标识符不必出现在 VC 本身中)。
credentialStatus [object] 标识要更新的特定状态列表条目。它必须是 以下形式的对象:
id [string]
type [string]
statusPurpose [string]
statusListIndex [string]
statusListCredential [string]
status [boolean] 指定新的状态。
indexAllocator [string] 供服务使用,用于确定哪些索引正被使用/分配给 VC。

/credentials/status 端点在接收 POST 时可能产生以下任一响应:

响应 主体
200 凭证状态已成功更新
400 错误请求
404 未找到凭证

D. 工作流步骤和模板 示例

D.1 最小可行 步骤和凭证模板

下面是可被视为包含单个步骤的最小工作流的模板示例, 随后是最小凭证的示例。请注意,这两个“最小”模板仍然 取决于每个示例中所做的授权和变量选择。

示例 26:最小步骤模板
{
  "id": "https://localhost:18443/workflows/z19nXMUSyXawSMK6j65Vs4jb1",
  "sequence": 0,
  "controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
  "steps": {
    "verify": {
      "stepTemplate": {
        "type": "jsonata",
        "template": "{\"verifiablePresentationRequest\": verifiablePresentationRequest}"
      }
    }
  },
  "initialStep": "verify",
  "zcaps": {...}
}
示例 27:最小凭证模板
{
  "id": "https://localhost:18443/workflows/z19mYrRgRuwN9PnezmhoJhBoV",
  "sequence": 0,
  "controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
  "credentialTemplates": [
    {
      "type": "jsonata",
      "template": "{\"@context\": [\"https://www.w3.org/ns/credentials/v2\", \"https://www.w3.org/ns/credentials/examples/v2\"],\"type\": [\"VerifiableCredential\",\"ExampleNameCredential\"],\"credentialSubject\": {\"name\": name}}"
    }
  ],
  "steps": {
    "issue": {
      "issueRequests": [
        {
          "credentialTemplateIndex": 0,
          "result": "issuedExampleNameCredentialResult"
        }
      ]
    }
  },
  "initialStep": "issue",
  "zcaps": {...}
}

D.2 复杂示例

下面是更复杂工作流的示例。

第一个示例包含多个步骤,包含验证和签发,支持 ZCAP 和 OAuth2 授权,展示了带有和不带自定义变量的凭证模板复用,并包含出示模式 检查。 该示例使用可验证凭证数据模型 2.0(validFromhttps://www.w3.org/ns/credentials/v2)。

示例 28:示例工作流 1
{
  "id": "https://localhost:18443/workflows/z19mYrRgRuwN9PnezmhoJhBoV",
  "sequence": 0,
  "controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
  "meterId": "https://localhost:18443/meters/z1AG3Ud3apFhGaTBfRm7KZPRY",
  "credentialTemplates": [
    {
      "id": "urn:credential-template-1",
      "type": "jsonata",
      "template": "\n  {\n    \"@context\": [\n      \"https://www.w3.org/ns/credentials/v2\",\n      'https://www.w3.org/ns/credentials/examples/v2'\n    ],\n    \"id\": credentialId,\n    \"type\": [\n      \"VerifiableCredential\",\n      \"UniversityDegreeCredential\"\n    ],\n    \"validFrom\": validFrom,\n    \"credentialSubject\": {\n      \"id\": results.verify.did,\n      \"degree\": {\n        \"type\": \"BachelorDegree\",\n        \"name\": \"Bachelor of Science and Arts\"\n      }\n    }\n  }\n"
    }
  ],
  "steps": {
    "verify": {
      "createChallenge": true,
      "verifiablePresentationRequest": {
        "query": [
          {
            "type": "DIDAuthentication",
            "acceptedMethods": [
              {
                "method": "key"
              }
            ]
          },
          {
            "type": "QueryByExample",
            "credentialQuery": [
              {
                "reason": "We require a verifiable credential to pass this test",
                "example": {
                  "@context": [
                    "https://www.w3.org/ns/credentials/v2",
                    "https://www.w3.org/ns/credentials/examples/v2"
                  ],
                  "type": "UniversityDegreeCredential"
                }
              }
            ]
          }
        ],
        "domain": "https://localhost:18443"
      },
      "presentationSchema": {
        "type": "JsonSchema",
        "jsonSchema": {
          "title": "Presentation",
          "type": "object",
          "required": [
            "@context",
            "type",
            "verifiableCredential"
          ],
          "additionalProperties": false,
          "properties": {
            "@context": {
              "type": "array"
            },
            "holder": {
              "type": "string"
            },
            "type": {
              "type": "array"
            },
            "proof": {
              "oneOf": [
                {
                  "type": "object"
                },
                {
                  "type": "array"
                }
              ]
            },
            "verifiableCredential": {
              "oneOf": [
                {
                  "title": "Strict Degree Credential",
                  "type": "object",
                  "required": [
                    "@context",
                    "type",
                    "issuer",
                    "credentialSubject"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "@context": {
                      "type": "array",
                      "items": [
                        {
                          "const": "https://www.w3.org/ns/credentials/v2"
                        },
                        {
                          "const": "https://www.w3.org/ns/credentials/examples/v2"
                        }
                      ]
                    },
                    "id": {
                      "type": "string"
                    },
                    "issuer": {
                      "const": "did:key:z6Mkjc99Z627zYQTJXTXP5ohoFnjyGP74ooyRmRYabxz8ozo"
                    },
                    "type": {
                      "type": "array",
                      "items": [
                        {
                          "const": "VerifiableCredential"
                        },
                        {
                          "const": "UniversityDegreeCredential"
                        }
                      ]
                    },
                    "validFrom": {
                      "type": "string"
                    },
                    "credentialSubject": {
                      "type": "object",
                      "required": [
                        "degree"
                      ],
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "degree": {
                          "type": "object",
                          "required": [
                            "type",
                            "name"
                          ],
                          "additionalProperties": false,
                          "properties": {
                            "type": {
                              "const": "BachelorDegree"
                            },
                            "name": {
                              "const": "Bachelor of Science and Arts"
                            }
                          }
                        }
                      }
                    },
                    "proof": {
                      "oneOf": [
                        {
                          "type": "object"
                        },
                        {
                          "type": "array"
                        }
                      ]
                    }
                  }
                },
                {
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "title": "Strict Degree Credential",
                    "type": "object",
                    "required": [
                      "@context",
                      "type",
                      "issuer",
                      "credentialSubject"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "@context": {
                        "type": "array",
                        "items": [
                          {
                            "const": "https://www.w3.org/ns/credentials/v2"
                          },
                          {
                            "const": "https://www.w3.org/ns/credentials/examples/v2"
                          }
                        ]
                      },
                      "id": {
                        "type": "string"
                      },
                      "issuer": {
                        "const": "did:key:z6Mkjc99Z627zYQTJXTXP5ohoFnjyGP74ooyRmRYabxz8ozo"
                      },
                      "type": {
                        "type": "array",
                        "items": [
                          {
                            "const": "VerifiableCredential"
                          },
                          {
                            "const": "UniversityDegreeCredential"
                          }
                        ]
                      },
                      "validFrom": {
                        "type": "string"
                      },
                      "credentialSubject": {
                        "type": "object",
                        "required": [
                          "degree"
                        ],
                        "additionalProperties": false,
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "degree": {
                            "type": "object",
                            "required": [
                              "type",
                              "name"
                            ],
                            "additionalProperties": false,
                            "properties": {
                              "type": {
                                "const": "BachelorDegree"
                              },
                              "name": {
                                "const": "Bachelor of Science and Arts"
                              }
                            }
                          }
                        }
                      },
                      "proof": {
                        "oneOf": [
                          {
                            "type": "object"
                          },
                          {
                            "type": "array"
                          }
                        ]
                      }
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "nextStep": "issue"
    },
    "issue": {
      "issueRequests": [
        {
          "credentialTemplateId": "urn:credential-template-1"
        },
        {
          "credentialTemplateId": "urn:credential-template-1",
          "variables": {
            "credentialId": "urn:different",
            "validFrom": "2024-01-01T00:00:00Z",
            "results": {
              "verify": {
                "did": "did:example:1"
              }
            }
          }
        }
      ]
    }
  },
  "initialStep": "verify",
  "zcaps": {
    "issue": {
      "@context": [
        "https://w3id.org/zcap/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "id": "urn:uuid:560e68a8-6c39-454d-8a54-b16c7d1e35fe",
      "controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
      "parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fissuers%2Fz1A9Aay1eLcMPnBYEFkkqhZev",
      "invocationTarget": "https://localhost:18443/issuers/z1A9Aay1eLcMPnBYEFkkqhZev/credentials/issue",
      "expires": "2025-12-01T21:28:44Z",
      "proof": {
        "type": "Ed25519Signature2020",
        "created": "2025-12-01T21:23:44Z",
        "verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
        "proofPurpose": "capabilityDelegation",
        "capabilityChain": [
          "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fissuers%2Fz1A9Aay1eLcMPnBYEFkkqhZev"
        ],
        "proofValue": "z4ubKiW87sRfEqSWRwoLhPGLTMuR7VnYuGyunPkWCbc6oCqUQDQUEz4bWw3zYBWACTywWj4NyBoUJwyH9VVBYZTKY"
      }
    },
    "createChallenge": {
      "@context": [
        "https://w3id.org/zcap/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "id": "urn:uuid:07537e74-25d7-49fa-9d30-28728bbb4838",
      "controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
      "parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa",
      "invocationTarget": "https://localhost:18443/verifiers/z1A2cLHcMzzuGT7sBZiU7AtYa/challenges",
      "expires": "2025-12-01T21:28:44Z",
      "proof": {
        "type": "Ed25519Signature2020",
        "created": "2025-12-01T21:23:44Z",
        "verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
        "proofPurpose": "capabilityDelegation",
        "capabilityChain": [
          "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa"
        ],
        "proofValue": "zydEXjYSYFVAVkoHvET2QMqsHgVqxRQoYViU6DDPRncjdSj2VAW19dAFUPBrpYBTt1kwYHeVB9HNZhoHtQL7DJ2A"
      }
    },
    "verifyPresentation": {
      "@context": [
        "https://w3id.org/zcap/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "id": "urn:uuid:4f495517-f6bd-488f-b662-fa2f761ccd03",
      "controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
      "parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa",
      "invocationTarget": "https://localhost:18443/verifiers/z1A2cLHcMzzuGT7sBZiU7AtYa/presentations/verify",
      "expires": "2025-12-01T21:28:44Z",
      "proof": {
        "type": "Ed25519Signature2020",
        "created": "2025-12-01T21:23:44Z",
        "verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
        "proofPurpose": "capabilityDelegation",
        "capabilityChain": [
          "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa"
        ],
        "proofValue": "z3NmKFcY2o146jTgpoLi6hD6TwRV7uC2SzEQrvTQSi4Sg33xCm3jE2QtYoa5MBGFvax8DCpjpjWdzzdhXUxijXLUG"
      }
    }
  },
  "authorization": {
    "oauth2": {
      "issuerConfigUrl": "https://localhost:18443/.well-known/oauth-authorization-server"
    }
  }
}

第二个示例使用 stepTemplate 特性。 它预期在创建交换时将完整的 verifiablePresentationRequest 作为变量提供, 并包含一个 callbackUrl 以演示回调特性。

示例 29:示例工作流 2
{
  "id": "https://localhost:18443/workflows/z19nXMUSyXawSMK6j65Vs4jb1",
  "sequence": 0,
  "controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
  "meterId": "https://localhost:18443/meters/z1A7quFpnVP4NdDURjUv78JVj",
  "steps": {
    "verify": {
      "stepTemplate": {
        "type": "jsonata",
        "template": "\n          {\n            \"createChallenge\": true,\n            \"verifiablePresentationRequest\": verifiablePresentationRequest,\n            \"callback\": {\n              \"url\": callbackUrl\n            }\n          }"
      }
    }
  },
  "initialStep": "verify",
  "zcaps": {
    "createChallenge": {
      "@context": [
        "https://w3id.org/zcap/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "id": "urn:uuid:103c3199-ae29-48c0-a848-61752093909c",
      "controller": "did:key:z6MkezKzgnoN3fxvdnsNhyf8wacUTLt22gg6PpXi2DRFkdBA",
      "parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp",
      "invocationTarget": "https://localhost:18443/verifiers/z1AG62DcvrFkaszuQmcvZ1tjp/challenges",
      "expires": "2025-12-01T21:32:04Z",
      "proof": {
        "type": "Ed25519Signature2020",
        "created": "2025-12-01T21:27:04Z",
        "verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
        "proofPurpose": "capabilityDelegation",
        "capabilityChain": [
          "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp"
        ],
        "proofValue": "z21ZcYeG7wPae2kvznuqH9V6S3bb3M2Zfs1cEGf4KdYnHB12AAe1to6scLCgdjyLdLM1E3uWWUupkE6xGaNzVnJis"
      }
    },
    "verifyPresentation": {
      "@context": [
        "https://w3id.org/zcap/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "id": "urn:uuid:14b5563a-1f73-4c3b-9fbb-a93b11e1084d",
      "controller": "did:key:z6MkezKzgnoN3fxvdnsNhyf8wacUTLt22gg6PpXi2DRFkdBA",
      "parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp",
      "invocationTarget": "https://localhost:18443/verifiers/z1AG62DcvrFkaszuQmcvZ1tjp/presentations/verify",
      "expires": "2025-12-01T21:32:04Z",
      "proof": {
        "type": "Ed25519Signature2020",
        "created": "2025-12-01T21:27:04Z",
        "verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
        "proofPurpose": "capabilityDelegation",
        "capabilityChain": [
          "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp"
        ],
        "proofValue": "z5pHj7SvNzB8GamN77kYLCjt66J98pHr5dqVgXpZJ7zHKnA6A2RMgVMvPAc3xxCADbuYsCgioGDPAQjvYzF9XF33u"
      }
    }
  }
}

E. 与其他 规范的关系

可验证凭证的生命周期 包括创建 工作流、用于参与交换的初始交互、签发、 状态管理、本地凭证管理、出示、验证和校验。本 规范定义了一个基于 HTTP 的 API,用于可验证凭证 生命周期 管理,可供签发者持有者验证者使用。 还有其他规范,例如 Digital Credential APIOpenID for Verifiable Credential Issuance v1.0OpenID for Verifiable Presentations v1.0,它们可能看起来提供了与本 规范类似的功能。本节说明在本规范标准化之前已经 考虑过哪些其他规范,以及本 规范与生态系统中的其他规范有何不同。

从根本上说,本规范是唯一聚焦于 可验证凭证整个生命周期管理的规范。 它不依赖于 凭证格式、凭证查询语言和凭证交付协议。任何 可表示为可验证凭证封装的 可验证凭证的凭证格式都可以与本规范一起使用。类似地, OpenID for Verifiable Credential Issuance v1.0OpenID for Verifiable Presentations v1.0 等凭证交付协议可以用于 本规范定义的交互交换。最后, 本规范支持多种凭证查询语言,以便随着技术改进和市场垂直领域专业化 提供灵活性。

本规范为可验证凭证 生命周期管理的整体定义 API,因为不这样做会造成供应商 锁定的机会。不存在其他规范提供能够在可验证凭证 生命周期管理全过程中防止 供应商锁定的接口。

F. IANA 注意事项

当本规范成为 W3C 提议推荐标准时, 本节将提交给互联网工程指导组(IESG) 进行审查、批准并在 IANA 注册。

F.1 URI 方案注册

方案名称:
interaction
状态:
永久
使用此方案名称的应用/协议:
本规范第 3.7 启动交互
联系人:
Ivan HermanW3C 工作人员联系人
变更控制者:
W3C 可验证 凭证工作组
参考文献
VCALM v1.0

G. 致谢

工作组感谢以下个人对本规范所作的贡献:最终致谢名单 将在候选推荐标准阶段结束时编制。

本规范的部分工作由美国 国土安全部硅谷创新计划根据以下 合同资助: 70RSAT20T00000003、 70RSAT20T00000010、 70RSAT20T00000029、 70RSAT20T00000031、 70RSAT20T00000033 和 70RSAT20T00000043。 本规范的内容并不必然 反映美国政府的立场或政策,也不应推断出任何官方 认可。

本规范的开发 也得到了 W3C 凭证 社区组的支持,该社区组此前在其孵化期间由以下人员组合担任主席: Kim Hamilton Duffy、Heather Vescent、Wayne Chang、Mike Prorock、Harrison Tang、Will Abramson、Mahmoud Alkhraishi 和 Denken Chen。

H. 参考文献

H.1 规范性参考文献

[DCAPI]
Digital Credential API. W3C. W3C 工作草案。URL:https://www.w3.org/TR/digital-credentials/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. 现行标准。URL:https://infra.spec.whatwg.org/
[ISO18004]
ISO18004:2024: QR Code Bar Code Symbology Specification. ISO. 已发布。URL:https://www.iso.org/standard/83389.html
[OID4VCI]
OpenID for Verifiable Credential Issuance v1.0. OpenID Foundation. W3C 工作草案。URL: https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html
[OID4VP]
OpenID for Verifiable Presentations v1.0. OpenID Foundation. W3C 工作草案。URL:https://openid.net/specs/openid-4-verifiable-presentations-1_0.html
[RFC2119]
用于 RFC 中表示 要求等级的关键词. S. Bradner. IETF. 1997 年 3 月。当前最佳实践。URL:https://www.rfc-editor.org/info/rfc2119/
[RFC3986]
统一资源标识符(URI):通用 语法. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005 年 1 月。互联网 标准。URL:https://www.rfc-editor.org/info/rfc3986/
[RFC6749]
OAuth 2.0 授权 框架. D. Hardt, Ed. IETF. 2012 年 10 月。提议标准。URL:https://www.rfc-editor.org/info/rfc6749/
[RFC6750]
OAuth 2.0 授权框架: Bearer 令牌用法. M. Jones; D. Hardt. IETF. 2012 年 10 月。提议标准。 URL:https://www.rfc-editor.org/info/rfc6750/
[RFC7617]
'Basic' HTTP 认证 方案. J. Reschke. IETF. 2015 年 9 月。提议标准。URL:https://httpwg.org/specs/rfc7617.html
[RFC8174]
RFC 2119 关键词中大写与小写的歧义. B. Leiba. IETF. 2017 年 5 月。当前最佳实践。URL:https://www.rfc-editor.org/info/rfc8174/
[RFC9457]
HTTP API 的问题详情. M. Nottingham; E. Wilde; S. Dalal. IETF. 2023 年 7 月。提议标准。URL:https://www.rfc-editor.org/info/rfc9457/
[URL]
URL Standard. Anne van Kesteren. WHATWG. 现行标准。URL:https://url.spec.whatwg.org/
[VC-BITSTRING-STATUS-LIST]
位串状态列表 v1.0. Manu Sporny; Dave Longley; Mahmoud Alkhraishi; Michael Prorock. W3C. 2025 年 5 月 15 日。W3C 推荐标准。URL:https://www.w3.org/TR/vc-bitstring-status-list/
[VC-DATA-INTEGRITY]
可验证凭证数据完整性 1.0. Ivan Herman; Manu Sporny; Ted Thibodeau Jr; Dave Longley; Greg Bernstein. W3C. 2025 年 5 月 15 日。W3C 推荐标准。URL:https://www.w3.org/TR/vc-data-integrity/
[VC-DATA-MODEL-2.0]
可验证凭证数据模型 v2.0. Ivan Herman; Michael Jones; Manu Sporny; Ted Thibodeau Jr; Gabe Cohen. W3C. 2025 年 5 月 15 日。W3C 推荐标准。URL:https://www.w3.org/TR/vc-data-model-2.0/
[VC-RECOG-ENT]
Recognized Entities v1.0. W3C. W3C 工作草案。URL:https://www.w3.org/TR/vc-recognized-entities/

H.2 资料性参考文献

[DID-CORE]
去中心化标识符(DIDs)v1.0. Manu Sporny; Amy Guy; Markus Sabadello; Drummond Reed. W3C. 2022 年 7 月 19 日。W3C 推荐标准。URL: https://www.w3.org/TR/did-core/
[json-schema]
JSON Schema:用于描述 JSON 文档的媒体 类型. Austin Wright; Henry Andrews; Ben Hutton; Greg Dennis. Internet Engineering Task Force (IETF). 2022 年 6 月 10 日。Internet-Draft。URL:https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema
[RFC9458]
Oblivious HTTP. M. Thomson; C. A. Wood. IETF. 2024 年 1 月。提议标准。URL:https://www.rfc-editor.org/info/rfc9458/