Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
本文档规定了一种 API,使 用户代理 能够中介 出示和签发数字 凭证,例如 驾驶执照、政府签发的身份证件,或 其他类型的数字凭证。 该 API 构建于 凭证管理 1 级 之上,并 被设计为不依赖于 凭证格式。
本节描述了本文档在 发布时的状态。当前 W3C 出版物列表和本技术报告的最新修订版可在 W3C 标准与草案 索引中找到。
本文档由 联邦身份工作 组作为 工作草案发布,并使用 推荐标准 轨道。
作为 工作草案发布并不意味着 W3C 及其成员认可该文档。
这是草案文档,可能随时被其他 文档更新、替代或废止。除作为进行中的工作之外, 不应以其他方式引用本文档。
本文档由一个 根据 W3C 专利 政策运作的小组生成。 W3C 维护着一个 与该小组交付成果相关的任何专利披露的公开列表; 该页面还包含 披露专利的说明。实际 知悉某项专利,并认为该专利包含 基本权利要求的个人, 必须依照 W3C 专利政策第 6 节 披露该信息。
本文档受 2025 年 8 月 18 日 W3C 流程文件管辖。
本节为非规范性内容。
本文档定义了一种 API,使网站能够请求 数字凭证的出示 和签发。
该 API 不依赖于凭证格式,并被设计为可扩展到多种 出示协议和 签发协议。参见 5. 协议。
该 API 被设计为支持以下目标:
可使用 此 API 出示和签发多种类型的数字凭证。这些类型的示例包括:
本节为非规范性内容。
以下示例说明如何使用 API 来请求和颁发数字凭证。
在使用 API 之前,重要的是要 检查用户 代理是否支持必要的特性。可以使用以下代码完成此操作:
if (typeof DigitalCredential !== "undefined") {
// 支持该 API
} else {
// 不支持该 API
}
userAgentAllowsProtocol()
静态方法可用于
检查用户代理是否允许将特定协议用于
数字凭证签发或出示。这对于在
进行 API 调用之前,检查用户浏览器允许哪些协议很有用。在实现了 DigitalCredential
的浏览器上(可通过上面所示的 typeof 检查检测),随着用户代理逐步采用对协议的支持,
协议标识符会被逐步添加到 DigitalCredentialProtocol
中,因此用未知
协议标识符调用此方法会安全地返回 false,而不会
抛出异常。注意,在未定义 DigitalCredential 的浏览器上调用此
方法会抛出 ReferenceError,因此在使用此
方法前,仍然需要上面所示的 typeof DigitalCredential !==
"undefined" 保护。
if (DigitalCredential.userAgentAllowsProtocol("example-protocol")) {
// 支持 DC API。继续签发或出示。
} else {
// 不支持 DC API。回退到例如
// 传统的基于 HTML 表单的方法。
showHTMLForm();
}
或者,可以检查对多个协议的支持, 过滤掉不受支持的协议:
const protocols = [
"example-issuance-protocol",
"another-issuance-protocol"
];
const supportedProtocols = protocols.filter(DigitalCredential.userAgentAllowsProtocol);
if (supportedProtocols.length > 0) {
// 至少支持一个协议。继续签发。
} else {
// 不支持任何协议。回退到其他签发方法。
}
由于协议标识符会被逐步添加到 DigitalCredentialProtocol
中,因此可以使用此方法优先选择较新的协议,同时
在旧版浏览器上优雅地回退到较旧的协议:
// 按偏好排序;在实现 DigitalCredential 的浏览器上,
// 未知协议会返回 false,而不是抛出异常。
const protocol = [
"example-new-protocol",
"example-legacy-protocol",
].find(DigitalCredential.userAgentAllowsProtocol);
if (protocol) {
// 使用此浏览器支持的最佳协议。
} else {
// 未找到受支持的协议。回退到其他方法。
}
以下示例展示了如何使用
API 请求数字凭证。该 API 的入口点是
navigator.credentials.get() 方法,
它用于
从用户代理请求数字凭证。如果
用户代理支持出示,它允许用户通过数字凭证选择器选择数字
凭证:
<button>验证身份</button>
<script>
const button = document.querySelector("button");
button.addEventListener("click", async () => {
const protocol = "example-request-protocol";
// 检查 DC API 和协议支持
if (!DigitalCredential.userAgentAllowsProtocol(protocol)) {
// 浏览器不允许使用此协议。
// 回退到其他验证方法。
showTraditionalVerificationForm();
return;
}
try {
const credential = await navigator.credentials.get({
digital: {
requests: [{
protocol,
data: { /* 出示请求数据 */ }
}]
}
});
// 将其发回验证方服务器以进行解密和验证
const response = await fetch("/verify-credential", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(credential)
});
// 检查响应
if (!response.ok) {
throw new Error("验证凭证失败");
}
// 渲染验证结果
displayVerificationResult(await response.json());
} catch (error) {
console.error("请求数字凭证时出错:", error);
}
});
</script>
以下示例展示了如何使用 数字
凭证 API 请求颁发数字
凭证。要颁发
数字凭证,站点会调用
navigator.credentials.create()
方法,
如果用户代理支持颁发,该方法将启动颁发
流程:
<button>请求签发数字凭证</button>
<script>
const button = document.querySelector("button");
button.addEventListener("click", async () => {
const protocol = "example-issuance-protocol";
// 检查 DC API 和协议支持
if (!DigitalCredential.userAgentAllowsProtocol(protocol)) {
// 浏览器不允许使用此协议。
// 回退到其他签发方法。
showTraditionalIssuanceForm();
return;
}
try {
const credential = await navigator.credentials.create({
digital: {
requests: [{
protocol,
data: { /* 签发请求数据 */ }
}]
}
});
} catch (error) {
console.error("签发数字凭证时出错:", error);
}
});
</script>
本规范允许通过 "digital-credentials-get" 策略控制特性,使用该 API 从远程/第三方源出示凭证。这 对于网站想要从托管在不同 源上的验证服务请求数字 凭证的场景很有用。Permissions Policy 可以设置在嵌入 想要使用该 API 的网站的 iframe 上。下面是一个如何在 iframe 上设置 Permissions Policy 的示例:
<iframe src="https://verifier-service.example.com"
allow="digital-credentials-get">
</iframe>
类似地,本规范允许通过 "digital-credentials-create" 策略控制特性,使用该 API 从远程/第三方源签发 凭证。这 对于网站想要使用不同源上的签发服务来请求 签发数字凭证的场景很有用。Permissions Policy 可以设置在嵌入签发方 界面的 iframe 上。下面是一个示例:
<iframe src="https://issuer.example.com"
allow="digital-credentials-create">
</iframe>
本节为非规范性内容。
以下事项属于本规范的范围:
以下事项不在范围内:
本节定义的目标是复用或建立 在各种数字凭证格式 和协议中通用的术语。这些定义正在积极演进。
本规范目前聚焦于与人相关的数字凭证。
本规范定义了以下出示协议的使用。
在 #401 中,我建议添加 以下内容:
<p>
[=user agent=] 必须实现在 [=table of exchange protocols=] 中列出的至少一个 [=digital credential/exchange protocol=]。
建议用户代理实现 [=table of exchange protocols=] 中列出的所有 [=digital credential/exchange protocols=]。
</p>
<aside class="note" title="检查用户代理允许哪些交换协议">
<p>开发者可以通过调用 `DigitalCredential.`{{DigitalCredential.userAgentAllowsProtocol()}} 静态方法,
检查用户代理允许哪些 [=digital credential/exchange protocols=]。
用法示例见 [[[#checking-if-protocol-is-allowed]]]。
</p>
</aside>
理由如下:
| 标识符 | 规范 |
|---|---|
| 出示协议 | |
openid4vp-v1-unsigned
|
OpenID for Verifiable Presentations 1.0 § A.3.1. 未签名请求 |
openid4vp-v1-signed
|
OpenID for Verifiable Presentations 1.0 § A.3.2. 已签名 请求 |
openid4vp-v1-multisigned
|
OpenID for Verifiable Presentations 1.0 § A.3.2.2. JWS JSON 序列化(多签名请求) |
org-iso-mdoc
|
ISO/IEC 18013-7:2025 符合 ISO 的 驾驶执照,第 7 部分:移动驾驶执照(mDL)附加功能 § 附录 C |
| 签发协议 | |
openid4vci-v1
|
OpenID
for Verifiable Credential Issuance 1.0 § 即将推出
议题:
API 集成
|
要在给定一个
DigitalCredentialGetRequest 或 DigitalCredentialCreateRequest
request 的情况下转换请求协议:
DigitalCredentialGetRequest:
protocol。
DigitalCredentialPresentationProtocol
中的任何枚举值,
返回失败。
DigitalCredentialPresentationProtocol
枚举值。
DigitalCredentialCreateRequest:
protocol。
DigitalCredentialIssuanceProtocol
中的任何枚举值,
返回失败。
DigitalCredentialIssuanceProtocol
枚举值。
凭证请求协调器 是一个由用户代理定义的组件,它通过顶级可遍历体中介数字 凭证 交互。每个顶级可遍历体都恰好有一个关联的 协调器。该协调器 确保在所有子可导航体中最多只有一个交互处于活动状态,编排 出示或 签发的端到端流程,并管理交互状态之间的转换。
凭证请求协调器维护一个活动 promise,用户
代理将其初始化为 null。通过这个 Promise,
协调器会把异步
凭证请求工作流的状态反映给脚本,并在
交互成功完成时以凭证
响应兑现,或在处理失败、
用户通过 UI 取消请求,或脚本通过 AbortSignal 中止
操作时拒绝。
凭证请求协调器维护一个中止信号,用户代理
将其初始化为 null。
凭证请求协调器维护一个中止算法,用户
代理将其初始化为 null。
用户代理可以根据用户或平台策略,将部分或全部协调器职责委托给 外部凭证管理器、平台组件或其他 可信 实体。
凭证请求协调器具有一组有限的 交互 状态,这些状态用于管理凭证 请求的生命周期:
要在给定 Document document、一组序列
DigitalCredentialGetRequest 值
或一组序列
DigitalCredentialCreateRequest
值 requests、一个 Promise
promise,以及一个可选的 AbortSignal signal 的情况下准备凭证
请求:
NotAllowedError"
DOMException
拒绝 promise。
null。
预先中止的信号
会在调用此算法之前,由请求
Credential和创建
Credential处理。
true,则返回。
AbortError" DOMException中止凭证请求。
给定一个由 DigitalCredentialGetRequest 或
DigitalCredentialCreateRequest
对象组成的序列 requests,验证凭证
请求:
false,则继续。
DigitalCredentialGetRequest,
则令 data 为 request 的 data;
或者如果
request 是
DigitalCredentialCreateRequest,
则令其为 request 的
data。
准备步骤最初声明:
除了协议定义的要求之外,[=user agent=] 还可以 根据本地策略、配置或 不断演进的安全考量应用额外的验证条件。例如,[=user agent=] 可能会拒绝 某个请求,如果该请求 (a) 寻求特定的凭证属性,(b) 使用或要求 [=user agent=] 被配置为不接受的密码算法(例如, 作为算法敏捷性或向后量子方案过渡的一部分),或 (c) 依赖于未被 [=user agent=] 所配置的信任决策接受的证书或信任锚。
最好对此进行扩展说明。
要在给定 JavaScript 值或 DOMException
error 的情况下中止
凭证请求:
null,
则返回。
要在给定一个(JavaScript 值)error 和一个
Promise promise 的情况下拒绝
凭证请求:
要在给定 Document
document、一个已验证凭证请求
validatedRequests 的列表、一个 Promise
promise,以及一个可选的 AbortSignal signal
的情况下发起
凭证请求:
当时在和 @mohamedamir 讨论……我们应当在规范中说明, 跨平台跨设备凭证交换应当(或建议)通过 CTAP 进行。
我们不能强制要求(即 MUST),因为:
NotAllowedError"
DOMException。
NotAllowedError"
DOMException。
TypeError。
InvalidStateError"
DOMException。
OperationError"
DOMException。
null 且
abortAlgorithm
不是 null,则从
abortSignal 中移除
abortAlgorithm。
null。
null。
DigitalCredential
实例,其
data
被初始化为
parsedResponseDataOrError,且其
protocol
被初始化为 protocol。
null。
数字凭证 API 利用 凭证管理第 1 级 规范,允许用户代理 协调颁发和出示数字 凭证。
该 API 允许从用户代理请求
数字凭证,用户代理随后
向用户呈现
数字凭证选择器,允许用户
选择一个
数字凭证来满足该请求。这是通过
网站调用
navigator.credentials.get() 方法完成的,该方法
运行
凭证管理第 1 级的
请求一个 Credential 算法。
然后,该算法回调到本规范的
DigitalCredential 接口的
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
内部方法。
此外,该 API 还允许请求
颁发数字凭证,这会
在用户代理和/或
持有者之间启动一个经协调的颁发流程。这是通过调用
navigator.credentials.create() 方法完成的,
该方法
运行
凭证管理第 1 级的
创建凭证算法。然后,
该算法回调到本
规范的 DigitalCredential 接口的
[[Create]](origin, options, sameOriginWithAncestors)
内部方法。
有关如何与 凭证管理第 1 级 规范集成的完整详情,请参见凭证管理 集成。
WebIDLpartial dictionary CredentialRequestOptions {
DigitalCredentialRequestOptions digital;
};
digital 成员
允许配置数字凭证请求的选项。
WebIDLdictionary DigitalCredentialRequestOptions {
required sequence<DigitalCredentialGetRequest> requests;
};
DigitalCredentialGetRequest
字典表示一个出示请求。它用于
指定出示协议和一些出示请求数据,用户代理可以将其与
凭证管理器(例如数字钱包)进行匹配。
WebIDLdictionary DigitalCredentialGetRequest {
required DOMString protocol;
required object data;
};
protocol 成员
表示出示协议。
protocol 成员的值
是
DigitalCredentialPresentationProtocol
中定义的协议标识符之一。
WebIDLpartial dictionary CredentialCreationOptions {
DigitalCredentialCreationOptions digital;
};
digital 成员
允许配置数字凭证签发的选项。
WebIDLdictionary DigitalCredentialCreationOptions {
required sequence<DigitalCredentialCreateRequest> requests;
};
DigitalCredentialCreateRequest
字典表示一个签发请求。它用于指定
签发协议和一些签发请求数据,以在
签发方和持有者之间传达签发请求。
WebIDLdictionary DigitalCredentialCreateRequest {
required DOMString protocol;
required object data;
};
protocol
成员表示签发协议。
protocol 成员的
值是
DigitalCredentialIssuanceProtocol
中定义的协议标识符之一。
DigitalCredential 接口表示一个概念性的
数字凭证。
DigitalCredential
接口强制所有操作进行用户中介,以确保用户控制和同意。
为了简化开发者在涉及
DigitalCredential 的
get()
调用中的体验,用户代理在
mediation 成员
缺失
或其值不是 "required"
时,不得抛出
错误。类似地,在涉及
DigitalCredential 的
create()
调用中,用户
代理在
mediation 成员
缺失或其值
不是 "required"
时不得抛出错误。
这使
"required"
中介成为该 API 的隐式且
不可覆盖的行为。
WebIDLtypedef (DigitalCredentialPresentationProtocol or DigitalCredentialIssuanceProtocol) DigitalCredentialProtocol;
[Exposed=Window, SecureContext]
interface DigitalCredential : Credential {
[Default] object toJSON();
readonly attribute DigitalCredentialProtocol protocol;
[SameObject] readonly attribute object data;
static boolean userAgentAllowsProtocol(DOMString protocol);
};
data 成员是
凭证的响应数据。它包含可解析为 JSON 的
对象类型子集。
userAgentAllowsProtocol()
方法允许数字
凭证验证方确定用户代理允许哪些出示协议和签发协议。
用户代理不得基于任何关于硬件可用性、软件存在或配置、 凭证管理器或数字凭证的信息, 或用户配置或 偏好,改变响应值。如果响应值发生变化,用户代理将引入 指纹识别风险,以及静默暴露关于用户行为或配置的其他细节的风险。 响应值应当仅随用户代理主版本而变化,并指示浏览器是否支持 将使用该协议的请求分发到底层平台或 提供方。
要在给定一个
DOMString protocol
时,检查用户代理是否允许协议,
执行以下步骤:
DigitalCredentialProtocol
的枚举值,
返回 false。
true,否则返回
false。
调用此方法时,用户代理必须返回在给定 protocol 时用户代理是否允许协议的结果。
数据结构(例如枚举)在本规范中支持
DigitalCredential。
WebIDLenum DigitalCredentialPresentationProtocol {
"openid4vp-v1-unsigned",
"openid4vp-v1-signed",
"openid4vp-v1-multisigned",
"org-iso-mdoc"
};
DigitalCredentialIssuanceProtocol
枚举
WebIDLenum DigitalCredentialIssuanceProtocol {
"openid4vci-v1",
};
调用时,[[DiscoverFromExternalSource]](origin, options,
sameOriginWithAncestors) 内部方法,如果用户代理不
支持出示请求(例如,平台
无法提供数字凭证选择器),
则使用相同参数调用
Credential 的
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
内部方法的默认实现。
否则:
signal。
Document。
NotAllowedError" DOMException 拒绝的 promise。
digital 的
requests 成员。
NotAllowedError" DOMException 拒绝的 promise。
调用时,[[Store]](credential, sameOriginWithAncestors)
必须使用相同参数调用 Credential 的
[[Store]](credential, sameOriginWithAncestors)
内部
方法的默认实现。
调用时,[[Create]](origin, options,
sameOriginWithAncestors) 内部方法,如果用户代理不
支持签发请求,则使用相同
参数调用 Credential 的[[Create]](origin, options, sameOriginWithAncestors)
内部方法的默认实现。否则:
signal。
Document。
NotAllowedError" DOMException 拒绝的 promise。
digital 的
requests 成员。
NotAllowedError" DOMException 拒绝的 promise。
DigitalCredential 接口对象具有一个名为
[[type]]
的内部槽,其值为 "digital"。
DigitalCredential 接口对象具有一个名为
[[discovery]]
的内部槽,其值为 "remote"。
本节为非规范性内容。
数字凭证
API 是一项强大特性,需要获得最终用户的明确许可。此
要求会在调用 CredentialsContainer 的
get()
方法时以规范性方式强制执行。
本规范定义了两个策略控制特性:
Credential
算法充当策略执行点。
Credential 算法充当
策略执行点。
本节为非规范性内容。
以下各节描述了该 API 的安全属性、 范围内威胁、安全所依赖的假设,以及 应用缓解措施后仍然存在的残余威胁。本 规范仅在中介凭证响应时, 定义用户代理行为的要求。
其他依赖协议、凭证 管理器实现、操作系统或传输安全的安全考量 被描述为期望或前提条件,但除非已被规范性 指定,否则本规范不对其作出 规范性要求。
本规范的威胁模型包括对该 API 以及生态系统中相邻标准的威胁。
范围内威胁是由 DC API 本身引入或处理的威胁。以下是本 规范的范围内威胁:
DigitalCredentialGetRequest
或 DigitalCredentialCreateRequest。
iframe)
请求或签发数字凭证,而没有
嵌入站点的明确许可,这可能导致
凭证收集或未授权访问敏感用户数据。
范围外威胁是由协议、 凭证管理器、OS 平台安全或 传输层处理的威胁。 即使“超出范围”,它们仍然相关,因为它们会影响 凭证出示和签发的端到端安全性。以下内容定义了本 规范的范围外威胁:
以下缓解措施通过本规范中的 规范性要求来处理范围内威胁。
Digital Credential API 的 WebIDL 接口仅在 安全上下文中暴露,从而降低通过 不安全上下文进行 篡改的风险(例如,恶意脚本通过网络 被注入)。请参阅 5 安全考量一节,该节属于 安全 上下文规范,以获取更多信息。
Digital Credentials API 通过两种 机制减少API 泛洪:
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
和 [[Create]](origin, options, sameOriginWithAncestors)
方法都会消耗用户激活,防止
没有用户交互的自动化请求或重复请求。
required”
(参见 DigitalCredential
接口),确保对于每个凭证
操作,都通过平台的凭证选择器界面取得用户许可。
关于防止凭证请求被滥用的其他指导, 请参阅 Credential Management Level 1 规范的 7 隐私考量一节。不过请注意,这些 保护有其局限性,因为站点仍可能使用诱导性设计模式 来鼓励不必要的用户交互,从而触发凭证 请求。
Digital Credentials API 通过与
权限策略集成(参见权限策略
集成),减少跨源滥用。
请求一个 Credential 和 创建一个 Credential 算法
分别作为 "digital-credentials-get" 和
"digital-credentials-create" 受策略控制的特性的策略执行
点。这两个特性是有意分开的:站点可以启用
"digital-credentials-get" 而不启用
"digital-credentials-create",反之亦然,
从而将每个
嵌入式上下文限制为仅具有其所需的能力。请参阅
权限策略规范的
权限策略一节,
以了解此集成提供的其他安全
属性。
本节为非规范性内容。
随着本文档的发展,本节仍在编写中。
数字凭证 API 集成到一个复杂的生态系统中,该生态系统具有 多个技术层和各种参与者(包括但不限于验证方、持有者和签发方),其中每一方 都必须考虑用户隐私的不同方面。本规范 不试图穷尽列出不同参与者的所有考量。我们希望 将这些各方引向多种其他资源,这些资源能够更全面地探讨 数字凭证威胁 模型:
相反,这些考量聚焦于数字凭证 API 本身,并描述用户代理在实现该 API 时如何履行其用户代理职责, 同时考虑到它所交互的生态系统的 相关隐私属性。
数字凭证的隐私考量并非静态。它们 会随着生态系统成熟而随时间演进,并可能受到 生态系统中其他行为者的行为、栈中其他 层的改进、对用户隐私的新威胁,以及不断变化的 社会规范和法规的影响。
预计参与数字凭证 API 设计和 实现的各个小组会主动监测 不断演进的隐私格局,并参与该 API 的相应 演进。
数字凭证 API 被设计为中介网站对 数字凭证的请求,并且不依赖于凭证 格式及其中包含的信息,也不依赖于用于 交换它的协议。这一点以及其他关键设计选择,均源于 为用户提供比现有替代方案(例如 [custom-schemes])更安全、更私密的凭证 交换体验这一目标,同时仍然兼容常见的交换 协议以便采用。
该 API 提供了验证方与 持有者之间的连接接口,即启动凭证出示协议 以及用户切换到持有者应用以 选择凭证的手段。过去为此目的 使用过的解决方案包括二维码和自定义 URL 方案。正如 在 Web 上出示 凭证和身份出示中 自定义方案的相关顾虑中所述, 这些解决方案存在安全、隐私和无障碍方面的顾虑。
随着数字凭证技术的采用受到 生态系统需求和监管要求的推动,Web 平台提供了一个 前述较不理想技术的替代方案,它 便于开发者使用,兼容现有的凭证 展示协议,而且最重要的是, 与前述替代方案相比,它为 用户提供了更好的用户隐私、安全性和可访问性属性。
数字凭证 API 赋予用户 代理代表用户进行 中介的能力(例如以数字凭证选择器的形式),以便对请求进行上下文化,并 防止 立即暴露给持有者应用。它还对 受支持协议施加某些最低要求,例如 响应 加密。
Digital Credentials API 服务于多种用例,这些用例具有 不同程度的数据披露,并面向在不同上下文中 具有不同偏好的各个用户。值得注意的是,由 此 API 调解的凭证交换的隐私属性,可能会受到 单个用户所处法律和监管环境的强制要求。
这意味着某些用户可能不希望,或不被允许,使用 保护隐私程度最高的方式来交换凭证信息。 尽管如此,用户代理仍需要为用户提供一种 默认保护隐私的体验,并保护他们免受伤害。
由于这种偏好和用例的范围很广,用户代理可能难以判断用户是否有意 暴露其个人信息,还是正被诱骗这样做。 因此,用户代理有责任确保每个 用户在交换开始之前,理解他们正在共享哪些数据, 以及谁将参与信息交换。
因为数字凭证 API 位于涉及多个 独立方的交换中心,所以这些各方用于交换 用户信息的出示协议和凭证格式,对于 用户代理保护用户隐私的目标至关重要。
我认为协议有两项要求需要进一步阐述:
必须经过隐私审查 [...]
以及
必须经过安全审查 [...]
从技术上讲,一个说“该协议在各方面都很糟糕”的审查也满足这些 标准。
如果有一组具体的隐私和安全 要求需要协议满足,会更有用;这样的审查便能够说明某一 标准是否已经达成。审查中可能会存在主观因素, 但也应当有每个协议都需要达到的最低门槛。
这超出了当前纳入标准中的现有要求。我手头没有完整清单,但 应该可以制定出一个清单。一旦制定完成,该清单应当纳入规范。例如, 该协议是否依赖于回拨? 该协议(或其传递的格式)是否保证出示的不可链接性? 或者——鉴于不可链接性对某些用例并不适用——在什么 条件下 API 要求协议提供不可链接性?协议包含哪些 透明度便利措施?哪些隐蔽信道是可接受的?
选择性 披露是 数据最小化 的一项基本技术, 它允许持有者共享 验证方所请求的最低必要信息。协议应当通过允许验证方指定所需的 确切声明来促进选择性披露。
不可链接性 是一种属性,它确保如果用户多次出示 凭证中的属性,验证方无法将这些单独的 出示相互关联,以推断它们涉及同一用户 (验证方—验证方可链接性),或者确保验证方无法与签发方串通, 将某个凭证从凭证管理器交换给签发方进行报告(验证方—签发方 可链接性)。前者是一种可由 持有者和签发方维持的属性,例如通过为 各个验证方签发新的凭证。
虽然后者是可以实现的,例如通过 零知识 证明, 但 API 的设计选择(例如加密响应)使得 用户代理无法证明验证者-签发者 不可链接性在实践中已经实现。尽管如此,仍要求协议 尽可能限制可链接性。
请注意,不可链接性仅针对 无法链接到特定用户身份的属性。名称、驾驶执照号码或电话号码等 本质上可链接的属性,并不会从不可链接性中受益。
通过 Digital Credentials API,用户 代理可以帮助 验证者和凭证管理器交换不可链接的 属性,但由于响应加密,它无法保证 在验证者和 凭证管理器之间没有传递 可链接的信息。建议 用户代理 在其用户许可体验中考虑这一事实。
此 API 的不可链接性目标是哪一级?我们能否 规范性地强制支持任何特定不可链接性 特性?
“回传”是指 这样的场景:数字凭证的展示或验证会导致向 签发者或另一个中心实体发出通知或通信,这可能导致 对个人的跟踪和 画像分析。
与不可链接性类似,在用户已授予 继续处理凭证请求的许可之后,用户 代理无法 确保签发者没有主动参与凭证展示的创建或 验证。从那一点开始, 由凭证管理器拥有此决策权。 虽然某些凭证 管理器可以被视为用户 代理,但通常 建议实现 Digital Credentials API 的用户代理设计其许可 体验,以防止在用户确认之前 将 请求暴露给凭证管理器 (同时牢记集成多个协作用户代理的 考量)。
要求协议支持一些机制,使签发者、 凭证管理器和验证者能够避免或减少 对“回传”机制的依赖。
此 API 的不可链接性目标是哪一级?规范在多大程度上 可以要求限制签发方参与?
在凭证交换中,颁发者参与的一种常见情形 是进行凭证撤销检查。当出示意图实现验证者-颁发者不可关联时, 这尤其具有挑战性。 当凭证出示通过使用 例如 零知识 证明 而变得不可关联时, 协议中使用的凭证格式预期会支持 离线撤销方法,例如密码学 累加器。还预期协议设计和 规范会尽可能不鼓励验证者为了 撤销目的而参与。
我们应该讨论不可链接撤销技术是否足够 实用,因而可以被规范性要求。
用户理解和参与是凭证出示中不可协商的属性。 协议应当帮助所有 涉及方通过提供对知情许可和/或同意至关重要的 信息来促进用户参与。
为了防止用户信息在“传输”过程中暴露给其他方, 例如加载在验证方 页面上的浏览器扩展,并鼓励 验证方安全存储用户凭证,协议需要在凭证交换中支持并 强制使用加密 响应。
与#49以及我们已经进行过的其他若干 讨论有关:我们是否想说响应必须始终加密 (如果是,用哪些算法),还是可以将其保留为可选?
不必要的凭证请求是整个 数字凭证生态系统的关键隐私风险。它们可能以不同方式 并出于不同动机表现出来:
这里的一个挑战是确定什么构成“有效”目的, 以及哪些请求因而是“不必要的”,这需要 凭证交换中所有相关方的参与。
若要更详细地探讨如何确定和处理 不必要的使用,将政府签发的 凭证与其他凭证分开考虑是合理的,因为它们在数据的敏感性、 滥用可能造成的潜在伤害,以及法律和监管考量方面 可能存在差异。
适用于这两类凭证的风险缓解和确保用户控制的 一个关键组成部分,是用户 代理检查 凭证请求元数据,并基于该元数据做出决策或进行 UI 呈现的能力。本规范通过协议要求来确保此类用户 代理访问,即传输未加密的请求 并包含相关信息(参见5. 协议 和6.2 准备凭证请求)。
政府签发的 数字凭证包括旅行证件、个人执照、 福利和公共卫生计划证明、车辆登记, 以及其他由政府机关签发的文件,或其他 表示这些信息的文件。这些文件高度 敏感,因为它们可能包含永久、不可撤销、唯一的 标识符,而这些标识符对于个人身份以及 与重要公共服务交互的能力至关重要。
这些凭证对用户和攻击者的高价值意味着 存在显著的窃取风险,并且向未授权第三方泄露会带来 显著的潜在危害。这包括出于跟踪和 个性化目的请求政府身份信息。
政府凭证在线可用性提高所带来的一个主要顾虑是 杰文斯悖论, 即通过降低访问摩擦而增加对凭证需求的可能性。 这种效应并非由 数字凭证 API 本身固有造成,而是由整个生态系统中 数字凭证采用率不断提高所造成;不过,它很可能会因用户 代理实现 数字凭证 API 而获得额外动力。因此,实现该 API 的 用户代理需要考虑这一效应,因为它可能 给用户带来有害结果:
上述政府签发数字凭证的风险提出了一项 挑战,这无法由生态系统中的单一参与者 解决,并且需要在各个主权国家内部 围绕通过现实世界凭证访问在线服务的风险和收益 开展更广泛的政策讨论。
希望签发数字凭证的政府 也能制定法律和法规,明确界定这些 凭证能够如何以及出于何种目的使用。参与交换的所有各方, 无论是否有法律义务这样做, 都被建议支持任何政府验证方认证 方案(如果存在)。对 验证方认证方案(例如 EUDI 访问和注册证书)的支持(及集成)可以缓解 不必要凭证请求泛滥的风险。然而, 不能保证存在此类方案,这会显著 增加凭证交换中的风险。
实现数字凭证 API 的用户 代理还可以采取其他实际步骤,以降低风险、提高用户 理解,并防止某些类型的危害:
此外,用户 代理设计一种能够考虑缺少这些缓解措施的权限 体验至关重要,例如,在没有任何验证者认证方案的情况下 交换来自政府凭证的个人信息。建议 对这些类型的交换应用更高程度的阻力,以及清晰的用户消息, 以突出所涉及的风险。
非政府签发的凭证包括所有其他非 政府签发且不表示政府签发文件的数字 文档、证书和证明。 这可能包括在职证明、(非政府)教育 凭证,或电影票。尤其是,其交换很可能 受法律和法规限制较少。虽然这些文件通常 不表现出与政府签发凭证相同的风险,但它们 也可能包含可识别或敏感信息。
非政府凭证被窃取和泄露的影响及可行性, 在很大程度上取决于每种具体凭证类型的内容。 一般而言,这可能导致失去控制权以及敏感私人信息暴露, 还可能导致冒充和数据盗窃,从而增加对受影响个人进行 后续攻击的可能性。
非政府凭证的灵活性和缺乏监管,为 跨站点跟踪和通过长期标识符(例如电子邮件 地址或电话号码)链接身份带来了滥用可能。参与基于 数字凭证的跟踪 方案的验证方可能会创造用户激励, 使用户在没有充分理解其隐私影响的情况下, 接受跨多个站点共享标识符凭证(Web 的“会员 卡”)。
即使不愿在此类方案中共享其信息的用户 也可能受到提示疲劳影响,并可能面临被排斥而无法使用这些服务的 风险。
对于非政府签发的凭证,建议 用户代理理解所请求的凭证 格式及其 隐私属性,并构建一个风险框架,用于决定 向用户显示的上下文,以及适合每种凭证类型的 摩擦程度。参与这些凭证交换的协议和格式 通常预期支持选择性披露和不可链接性等特性, 但这些特性在信息交换中可能并不总是合适或必要, 尤其是在涉及低风险 凭证(例如电影票)时。
能够识别被请求凭证类型的用户代理 被鼓励定制其许可体验,以 最好地适配所请求的凭证,并帮助用户理解 共享该凭证的后果。
用户代理不应被期望理解所有 凭证 请求。不识别所请求凭证类型的用户代理,建议在其权限体验中显著增加用户 阻力,并向用户清楚传达 与网站共享未知凭证的风险。请注意, 这可能需要在 不同用户 代理之间进行集成,以应用 适当程度的阻力和透明度。例如, 浏览器可能会将有关凭证请求的知识委托给 操作系统,而操作系统可能要求凭证管理器 注册已知凭证类型,并拒绝针对 未知凭证类型的交换请求。
向用户提供适当透明度的需求,与使生态系统能够在没有明确用户代理认可的情况下开发新凭证 格式的愿望相冲突。
考虑为发出不必要和滥用性请求的验证方 建立一个可互操作的滥用举报系统。
虽然该 API 确保在没有 许可提示的情况下绝不会共享任何用户数据(参见 [[[#user-permission-and-transparency|用户 许可与透明度]] 一节),但 数字凭证 API 可能返回的现实世界标识符所具有的持久性和唯一性, 使其成为跟踪器和 指纹识别者的潜在目标。
即使使用选择性披露,攻击者也可能将来自 数字凭证的数据(例如用户的年龄,或凭证 颁发者、时间戳;参见 [[[#leaking-incidental-data|泄露 附带数据]] 一节)组合起来,以重新识别用户和/或对用户进行指纹识别。
对第三方攻击者(例如嵌入在验证方页面上但并未为跟踪目的与其主动 协作的脚本)而言,这种攻击可能更难,因为响应 加密是强制性的,并且响应应当在 验证方服务器上解密。因此,验证方可以确保不将解密后的信息 反射回客户端 JavaScript。然而,并非所有 验证方都会选择这样做。
为确保凭证的真实性,向 验证方出示凭证通常会包含比 验证方请求访问的内容更多的信息。它通常至少 包含签发方和凭证管理器的签名, 并可能包含其他元数据。
这些附加信息可用于重新识别和 指纹识别用户,当进行原本 不可链接的出示时,这一点尤其相关。
虽然数字凭证 API 不控制 凭证响应的内容,但用户代理可以通过清晰突出显示除了所请求内容外 哪些信息可能会被共享给验证方,并更广泛地通过识别和阻止验证方经由 API 进行指纹识别,来帮助保护用户免受这种类型的跟踪。
数字凭证 API 通过
userAgentAllowsProtocol()
暴露关于用户代理支持哪些出示和签发协议的信息。
它通过不基于例如用户设备上安装了哪些
凭证管理器应用来自定义响应,来缓解浏览器
指纹识别以及暴露关于用户设备
配置的信息。因此,返回的信息充其量相当于一个
用户代理版本。
数字凭证 API 不允许站点在未先经过 用户许可 流程的情况下获知某个 凭证是否可用。 暴露凭证的存在会对用户 隐私构成风险,因为凭证的存在属于个人信息, 用户可能并不愿意与站点共享;并且结合其他信号后, 可能被用于在未经用户许可的情况下识别用户。 这也会对言论自由构成风险,因为 网站可能越来越多地开始要求用户出示这些 凭证才能访问服务,从而排除 不愿出示凭证的个人。
数字凭证 API 使得通过 凭证与网站共享高度个人化、 敏感且有风险的用户信息成为可能,这可能赋予通过 永久、唯一、不可撤销、跨上下文 标识符在线上和线下跟踪用户的能力。它还会暴露用户浏览活动的一部分, 以及他们向特定网站和/或 凭证管理器表明身份的意图。 用户代理在凭证请求中的一项关键责任,是从用户那里获得 继续进行信息交换的 许可。
用户要就是否继续进行凭证交换作出 知情决定,需要以下 重要上下文细节:
建议用户代理在其实现中确保 在发生任何与用户相关的信息交换之前,将所列细节 完全披露给用户。
这些是否应当在规范中成为规范性内容?
该 API 是否应当被设计为让站点可以提供上下文内 说明?
我们需要描述处理多个凭证出示请求和响应时的 顾虑、权衡以及可能的缓解措施。
根据用户系统的技术架构, “用户 代理”的定义很可能包括 软件栈中多个协作层,例如浏览器 和操作系统。这些层的最高优先级 必须是安全且信息充分的用户许可体验。因此, 集成对用户安全可能至关重要。某些层可能持有 其他层无法访问的信息,例如 用户凭证的可用性。过度提示或在 上下文不足的情况下提示,可能导致可被利用的混淆和 提示盲视。
因此,提示用户授予许可的用户代理 被鼓励在其认为安全的情况下集成软件层,以获得理想的用户体验。 例如,如果 浏览器信任操作系统的 API 合同会显示 适当的提示,那么浏览器自身可以不显示提示。
作为用户许可流程的一部分,用户 代理需要 确保用户保留选择是否将 凭证请求转发给凭证管理器以及选择哪个凭证 管理器的权力。这是因为信息披露 会作为请求的一部分发生,并且凭证 管理器在请求时有能力保留或共享这些信息。
由用户 代理中介的许可并不同于同意,后者 具有特定的法律定义,可能会因不同的法律 和监管环境而异,并且在与 凭证管理器共享信息之前,可能需要由凭证管理器收集, 或者在发起 请求之前由验证方自身收集。随着获取同意的框架和法规仍在 制定中,该 API 旨在支持交换 必要信息,这些信息可能包括以下内容:
随着更多此类信息以结构化格式变得可用, 我们期望用户代理和本规范也利用这些信息来 改进用户许可体验。
实现者在专门为此 API 设计凭证选择器时,需要考虑无障碍性。在签发或 出示期间呈现的模态对话框内容, 其中可以包括文本、二维码和其他视觉媒体,应当被标注并 暴露给辅助技术。
出于用户代理自动化和应用测试的目的,本文档 为 WebDriver BiDi 规范定义了扩展模块。用户代理 对其提供支持是可选的。
digitalCredentials 模块包含用于管理和
模拟凭证管理器在
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
和 [[Create]](origin, options, sameOriginWithAncestors)
调用期间的远端行为的命令。
CDDLdigitalCredentials.VirtualWalletAction = "decline" / "respond" / "wait" / "clear"
digitalCredentials.SetVirtualWalletBehaviorParameters = {
action: digitalCredentials.VirtualWalletAction,
? context: text,
? protocol: text,
? response: { * text => any },
}
digitalCredentials.VirtualWalletAction
类型表示不同类型的
虚拟钱包动作。
"decline"
"respond"
"wait"
"clear"
CDDLdigitalCredentials.SetVirtualWalletBehavior = (
method: "digitalCredentials.setVirtualWalletBehavior",
params: digitalCredentials.SetVirtualWalletBehaviorParameters
)
CDDLdigitalCredentials.SetVirtualWalletBehaviorResult = EmptyResult
给定 session 和 command parameters,
digitalCredentials.setVirtualWalletBehavior 命令的远端步骤为:
action"]。
context"],
否则为
null。
protocol"],
否则
为 null。
response"],
否则
为 null。
"respond":
null 或 response 为
null,则返回一个
错误,其错误代码为invalid argument。
DigitalCredentialProtocol
的枚举值,
则返回一个错误,其错误代码为invalid argument。
null 或 protocol 不是
null,则返回
一个错误,其错误代码为invalid argument。
"clear":
null 的成功。
要在给定一个 Promise
promise 和一个全局对象 global 的情况下处理虚拟钱包行为,运行以下步骤:
false。
null,则将 behavior 设置为当前 WebDriver
session 的默认活动虚拟钱包行为。
null,则返回 false。
"wait",则返回 true。
"decline":
NotAllowedError"
DOMException拒绝 promise。
true。
"respond":
action
§13.1.1
"clear"
§13.1.1
context
§13.1.1
[[Create]](origin, options, sameOriginWithAncestors)
DigitalCredential 的内部槽
§8.3
DigitalCredentialGetRequest 的成员
§7.3.2
DigitalCredentialCreateRequest 的成员
§7.6.2
DigitalCredential 的属性
§7.7.2
"decline"
§13.1.1
CredentialRequestOptions 的成员
§7.1.1
CredentialCreationOptions 的成员
§7.4.1
DigitalCredential 接口
§7.7
DigitalCredentialCreateRequest
字典
§7.6
DigitalCredentialCreationOptions
字典
§7.5
DigitalCredentialGetRequest 字典
§7.3
DigitalCredentialIssuanceProtocol
枚举
§7.8.3
DigitalCredentialPresentationProtocol
枚举
§7.8.2
DigitalCredentialProtocol
§7.7
DigitalCredentialRequestOptions
字典
§7.2
digitalCredentials.SetVirtualWalletBehavior
§13.1.2.1
"digitalCredentials.setVirtualWalletBehavior"
§13.1.2.1
digitalCredentials.SetVirtualWalletBehaviorParameters
§13.1.1
digitalCredentials.SetVirtualWalletBehaviorResult
§13.1.2.1
digitalCredentials.VirtualWalletAction
§13.1.1
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
DigitalCredential 的内部槽
§8.1
[[discovery]]
DigitalCredential 的内部槽
§8.5
method
§13.1.2.1
"openid4vci-v1"
DigitalCredentialIssuanceProtocol 的枚举值
§5.
"openid4vp-v1-multisigned"
DigitalCredentialPresentationProtocol 的枚举值
§5.
"openid4vp-v1-signed"
DigitalCredentialPresentationProtocol 的枚举值
§5.
"openid4vp-v1-unsigned"
DigitalCredentialPresentationProtocol 的枚举值
§5.
"org-iso-mdoc"
DigitalCredentialPresentationProtocol 的枚举值
§5.
params
§13.1.2.1
DigitalCredentialGetRequest 的成员
§7.3.1
DigitalCredentialCreateRequest 的成员
§7.6.1
DigitalCredential 的属性
§7.7.1
DigitalCredentialRequestOptions 的成员
§7.2.1
DigitalCredentialCreationOptions 的成员
§7.5.1
"respond"
§13.1.1
response
§13.1.1
[[Store]](credential, sameOriginWithAncestors)
DigitalCredential 的内部槽
§8.2
text
§13.1.1
[[type]] DigitalCredential 的内部槽
§8.4
userAgentAllowsProtocol()
DigitalCredential 的方法
§7.7.3
"wait"
§13.1.1
[[Create]](origin, options, sameOriginWithAncestors)
(用于 Credential)
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
(用于 Credential)
[[Store]](credential, sameOriginWithAncestors)(用于
Credential)
create()(用于
CredentialsContainer)
Credential 接口
CredentialCreationOptions
CredentialRequestOptions
CredentialsContainer 接口
get()(用于 CredentialsContainer)
mediation(用于
CredentialRequestOptions)
mediation(用于
CredentialCreationOptions)
required(用于
CredentialMediationRequirement)
signal(用于
CredentialRequestOptions)
signal(用于
CredentialCreationOptions)
AbortSignal)
AbortSignal)
AbortSignal 接口
AbortSignal)
AbortSignal)
AbortController)
AbortController)
Document)
Document)
iframe
元素
object
类型
list)
iteration)
list)
list)
struct)
AbortError 异常
boolean
类型
[Default] 扩展属性
DOMException 接口
DOMString 接口
[Exposed] 扩展属性
InvalidStateError 异常
NotAllowedError 异常
object
类型
OperationError 异常
Promise 接口
ReferenceError 异常
[SameObject] 扩展属性
[SecureContext] 扩展属性
exception)
TypeError 异常
WebIDLpartial dictionary CredentialRequestOptions {
DigitalCredentialRequestOptions digital;
};
dictionary DigitalCredentialRequestOptions {
required sequence<DigitalCredentialGetRequest> requests;
};
dictionary DigitalCredentialGetRequest {
required DOMString protocol;
required object data;
};
partial dictionary CredentialCreationOptions {
DigitalCredentialCreationOptions digital;
};
dictionary DigitalCredentialCreationOptions {
required sequence<DigitalCredentialCreateRequest> requests;
};
dictionary DigitalCredentialCreateRequest {
required DOMString protocol;
required object data;
};
typedef (DigitalCredentialPresentationProtocol or DigitalCredentialIssuanceProtocol) DigitalCredentialProtocol;
[Exposed=Window, SecureContext]
interface DigitalCredential : Credential {
[Default] object toJSON();
readonly attribute DigitalCredentialProtocol protocol;
[SameObject] readonly attribute object data;
static boolean userAgentAllowsProtocol(DOMString protocol);
};
enum DigitalCredentialPresentationProtocol {
"openid4vp-v1-unsigned",
"openid4vp-v1-signed",
"openid4vp-v1-multisigned",
"org-iso-mdoc"
};
enum DigitalCredentialIssuanceProtocol {
"openid4vci-v1",
};
digitalCredentials.VirtualWalletAction = "decline" / "respond" / "wait" / "clear"
digitalCredentials.SetVirtualWalletBehaviorParameters = {
action: digitalCredentials.VirtualWalletAction,
? context: text,
? protocol: text,
? response: { * text => any },
}
digitalCredentials.SetVirtualWalletBehavior = (
method: "digitalCredentials.setVirtualWalletBehavior",
params: digitalCredentials.SetVirtualWalletBehaviorParameters
)
digitalCredentials.SetVirtualWalletBehaviorResult = EmptyResult
除标记为非规范性的章节外,本规范中的所有编写指南、图示、示例和注均为非规范性内容。 本规范中的其他所有内容均为规范性内容。
本文档中的关键词 MAY、MUST、MUST NOT、OPTIONAL 和 SHOULD 应按 BCP 14 [RFC2119] [RFC8174] 中所述进行解释,但仅限于它们以这里所示的 全大写形式出现时。
部分编辑希望感谢以下个人对本规范提供的 反馈和贡献:Christian Bormann (SPRIND)、John Bradley (Yubico)、Rick Byers (Google)、Brian Campbell (Ping Identity)、Lee Campbell (Google)、Nick Doty (CDT)、Heather Flanagan (Spherical Cow Consulting)、Ryan Galluzzo (NIST)、Joseph Heenan (Authlete)、Dominique Hazael-Massieux (W3C)、Bjorn Hjelm (Yubico)、Johann Hofmann (Google)、Mike Jones (Self-Issued Consulting)、Tobias Looker (MATTR)、Matthew Miller (Cisco)、Theresa O'Connor (Apple Inc.)、Simone Onofri (W3C)、Helen Qin (Google)、Wendy Seltzer (Invited Expert)、Manu Sporny (Digital Bazaar)、Orie Steele (Transmute)、Ted Thibodeau Jr (OpenLink Software)、David Waite (Ping Identity),以及 Kristina Yasuda (SPRIND)。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: