Skip to content

本文为 SPIFFE 官方规范 The X.509 SPIFFE Verifiable Identity Document 的中文译本,仅供学习参考;若与英文原文有出入,以英文版为准。

X.509 SPIFFE 可验证身份文档

稳定性:Stable(稳定) - 参见 STABILITY.md

本备忘录的状态 (Status of this Memo)

本文档为互联网社区规定了一项身份文档标准,并征求各方对其改进的讨论与建议。本文档的分发不受限制。

摘要 (Abstract)

SPIFFE 标准提供了一套规范,用于描述一个能够在异构环境和组织边界之间引导(bootstrap)并向各类服务颁发身份的框架。它定义了一种身份文档,称为 SPIFFE 可验证身份文档(SPIFFE Verifiable Identity Document,SVID)。

SVID 本身并不代表一种新的文档类型。相反,我们提出了一套规范,定义如何将 SVID 信息编码进现有的文档类型中。

本文档定义了一项标准,规定如何将 X.509 证书用作 SVID。本文假定读者对 X.509 有基本了解。有关 X.509 的具体信息,请参阅 RFC 5280

1. 引言

或许 SPIFFE 最重要的功能就是保护进程到进程之间的通信。核心标准支持认证(authentication),然而,利用加密身份来构建安全的通信通道同样是非常值得追求的。随着 TLS 被广泛采用,并借助基于 X.509 的认证加以实现,将 X.509 用作 SPIFFE SVID 显然具有明显的优势。

本规范阐述如何将 SVID 信息编码进 X.509 证书、必须设置的各项约束(constraint),以及如何验证 X.509 SVID。

2. SPIFFE ID

在 X.509 SVID 中,对应的 SPIFFE ID 被设置为主体备用名称扩展(Subject Alternative Name extension,即 SAN 扩展,参见 RFC 5280 section 4.2.1.6)中的一个 URI 类型条目。X.509 SVID 必须(MUST)恰好包含一个 URI SAN,进而也就恰好包含一个 SPIFFE ID。包含多个 SPIFFE ID 的 SVID 会带来与审计和授权逻辑相关的难题,而包含多个 URI SAN 的 SVID 则会带来与 SPIFFE ID 验证相关的难题。验证方(validator)在遇到包含多个 URI SAN 的 SVID 时,必须(MUST)拒绝该 SVID。更多信息请参见验证一节。

X.509 SVID 可以(MAY)包含任意数量的其他 SAN 字段类型,包括 DNS SAN。

3. 层级结构 (Hierarchy)

本节讨论叶子证书(leaf certificate)、根证书与中间证书之间的关系,以及对每一类证书所施加的要求。

3.1. 叶子证书(leaf certificate)

叶子证书(leaf certificate)是一种 SVID,用于标识某个调用方或资源,并且适合在认证过程中使用。叶子证书(与签名证书(signing certificate)相对,见第 3.2 节)是唯一可用于标识资源或调用方的证书类型。

叶子证书的 SPIFFE ID 必须(MUST)带有非根(non-root)路径组件。Subject 字段并非必填,然而,根据 RFC 5280 第 4.1.2.6 节,若省略 Subject,则 URI SAN 扩展必须(MUST)被标记为关键(critical)。有关区分叶子证书与签名证书的 X.509 特有属性,请参见第 4.1 节

3.2. 签名证书(signing certificate)

X.509 SVID 签名证书(signing certificate)是指在密钥用途(key usage)扩展中设置了 keyCertSign 的证书。它还在基本约束(basic constraints)扩展中将 cA 标志设置为 true(参见第 4.1 节)。也就是说,它是一张 CA 证书。

签名证书本身应当(SHOULD)也是一个 SVID。若存在 SPIFFE ID,则签名证书的 SPIFFE ID 禁止(MUST NOT)带有路径组件,并且应当(SHOULD)位于它所签发的任何叶子 SVID 所属的信任域(trust domain)内。签名证书可以(MAY)用于在相同或不同的信任域中签发更多的签名证书。

签名证书禁止(MUST NOT)用于认证目的。它们仅作为验证材料(validation material),并可按照典型的 X.509 方式串联成链,如 RFC 5280 所述。有关签名证书的 X.509 特有限制的更多信息,请参见第 4.3 节第 4.4 节

4. 约束与用途 (Constraints and Usage)

叶子证书与签名证书携带不同的 X.509 属性——其中一些用于安全目的,另一些则用于支持其专门的功能。本节描述这两类 X.509 SVID 的约束(constraint)与密钥用途(key usage)配置。

4.1. 基本约束(basic constraints)

基本约束(basic constraints)X.509 扩展用于标识证书是否为签名证书,以及包含该证书的有效认证路径(certification path)的最大深度。它定义于 RFC 5280, section 4.2.1.9

有效的 X.509 SVID 签名证书可以(MAY)设置 pathLenConstraint 字段。签名证书必须(MUST)将 cA 字段设置为 true,而叶子证书必须(MUST)将 cA 字段设置为 false

4.2. 名称约束(name constraints)

名称约束(name constraints)指定了一个命名空间,认证路径(certification path)中后续证书里的所有 SPIFFE ID 都必须(MUST)位于其中。它们用于将被攻陷的签名证书的影响范围(blast radius)限制在指定的信任域(trust domain)之内,定义于 RFC 5280, section 4.2.1.10。本节仅适用于签名证书。

名称约束(name constraints)的类型划分方式与主体备用名称(Subject Alternative Name)相同。由于 SVID 唯一关注的名称就是 SPIFFE ID,而 SPIFFE ID 被定义为 SAN 类型 URI,因此我们仅定义 URI 类型名称约束的语义。

在实际环境中,对 URI 类型名称约束的支持明显不足。不支持它们的库将拒绝此类证书,从而导致路径验证(path validation)无法成功完成。尽管名称约束是 SPIFFE 希望使用的一项 X.509 特性,但作者也认识到,缺乏广泛支持可能会带来相当大的实现和/或部署方面的痛点。因此,X.509 SVID 签名证书可以(MAY)由实现者自行酌情施加 URI 名称约束,但在这一方面务须谨慎。SPIFFE 社区正致力于在各种平台上启用对 URI 名称约束的支持,并且可以预期,随着更广泛支持的实现,本节所定义的要求将在未来版本中变得更加严格。

4.3. 密钥用途(key usage)

密钥用途(key usage)扩展定义证书中所含密钥的用途。当某个密钥可能被用于多种操作、需要对其加以限制时,便可采用该用途限制。密钥用途扩展定义于 RFC 5280, section 4.2.1.3

密钥用途扩展必须(MUST)在所有 SVID 上设置,并且必须(MUST)被标记为关键(critical)。

SVID 签名证书必须(MUST)设置 keyCertSign。它们可以(MAY)设置 cRLSign

叶子 SVID 必须(MUST)设置 digitalSignature。它们可以(MAY)设置 keyEncipherment 和/或 keyAgreement;这些通常只对 RSA 密钥的证书才有意义,而且即便如此往往也并不需要。叶子 SVID 禁止(MUST NOT)设置 keyCertSigncRLSign

4.4. 扩展密钥用途(extended key usage)

该扩展指明证书中所含密钥可用于的一个或多个用途,作为对密钥用途(key usage)扩展中所指明的基本用途的补充或替代。它定义于 RFC 5280, section 4.2.1.12

叶子 SVID 应当(SHOULD)包含此扩展,并且它可以(MAY)被标记为关键(critical)。当包含该扩展时,必须(MUST)设置 id-kp-serverAuthid-kp-clientAuth 字段。

签名证书可以(MAY)包含扩展密钥用途(Extended Key Usage)扩展。请注意,各 X.509 证书验证库对中间 CA 证书中扩展密钥用途扩展的处理差异很大。某些 X.509 实现会将中间 CA 证书中的 EKU 约束施加到信任链中位于其下方的所有证书上,而另一些则不会。

5. 验证 (Validation)

本节描述如何验证 X.509 SVID。该过程采用标准的 X.509 验证,外加一小组 SPIFFE 特有的验证步骤。

5.1. 路径验证(path validation)

对给定 SVID 的信任验证基于标准的 X.509 路径验证(path validation),并且必须(MUST)遵循 RFC 5280 的路径验证语义。

证书路径验证需要叶子 SVID 证书以及一个或多个 SVID 签名证书。验证所需的签名证书集合称为 CA bundle(CA 包)。实体检索相关 CA bundle 的机制不在本文档的范围之内,而是定义在 SPIFFE Workload API 规范中。

5.2. 叶子验证 (Leaf Validation)

在对某个资源或调用方进行认证时,有必要执行超出 X.509 标准所涵盖范围的验证。具体而言,我们必须确保:1)该证书是叶子证书;2)其签名机构获得授权来签发它。

在为认证目的验证 X.509 SVID 时,验证方必须(MUST)确保基本约束(basic constraints)扩展中的 cA 字段被设置为 false,并且密钥用途(key usage)扩展中未设置 keyCertSigncRLSign。验证方还必须(MUST)确保 SPIFFE ID 的 scheme 被设置为 spiffe,并且必须(MUST)确保该 SPIFFE ID 带有非根(non-root)路径组件。包含多个 URI SAN 的 SVID 必须(MUST)被拒绝。

随着对 URI 名称约束的支持日益普及,本文档的未来版本可能会更新本节所提出的要求,以便更好地利用名称约束验证。

6. 在 SPIFFE Bundle 中的表示 (Representation in the SPIFFE Bundle)

本节描述如何将 X509-SVID CA 证书发布到 SPIFFE bundle,以及如何从中消费。有关 SPIFFE bundle 的更多信息,请参阅 SPIFFE Trust Domain and Bundle 规范。

6.1. 发布 SPIFFE Bundle 元素 (Publishing SPIFFE Bundle Elements)

对于给定的信任域(trust domain),X509-SVID CA 证书在 SPIFFE bundle 中被表示为符合 RFC 7517 的 JWK 条目,每张 CA 证书对应一个条目。

每个 JWK 条目的 use 参数必须(MUST)被设置为 x509-svid。此外,每个 JWK 条目的 kid 参数禁止(MUST NOT)被设置。

除了 RFC 7517 所要求的参数外,每个表示 X509-SVID CA 证书的条目必须(MUST)包含 x5c 参数,其值等于该条目所表示的 CA 证书经 base64 编码的 DER 形式。该值必须(MUST)恰好包含一张 CA 证书,并且该证书应当(SHOULD)为自签名(self-signed)。

6.2. 消费 SPIFFE Bundle (Consuming a SPIFFE Bundle)

在消费来自外部信任域(foreign trust domain)的 SPIFFE bundle 时,有必要提取出 X509-SVID CA 证书以供实际使用。SPIFFE bundle 可能包含许多不同 SVID 类型的条目,因此第一步是识别出表示 X509-SVID CA 证书的那些条目。

对于 bundle 中每个 use 参数被设置为 x509-svid 的 JWK 条目,检查其 x5c 参数是否已设置且至少含有一个值。如果 x5c 未设置或为空,则该条目必须(MUST)被忽略。

x5c 参数的第一个值是该条目所表示的、经 base64 DER 编码的 CA 证书。如果 x5c 参数包含多个值,则除第一个之外的所有值都必须(MUST)被忽略。X509-SVID CA bundle 即为从各个 x509-svid JWK 条目中提取出的 CA 证书的并集。如果 bundle 中不存在任何 x509-svid JWK 条目,则该信任域不支持 X509-SVID。

7. 结论 (Conclusion)

本文档为基于 X.509 的 SPIFFE 可验证身份文档的签发与验证提出了一系列约定与标准。它构成了现实世界中 SPIFFE 服务认证与 SVID 验证的基础。通过遵循 X.509 SVID 标准,便有可能构建一套可互操作、且与平台无关的身份与认证系统。

附录 A. X.509 字段参考 (Appendix A. X.509 Field Reference)

扩展字段描述
Subject Alternative NameuniformResourceIdentifier此字段被设置为等于 SPIFFE ID。仅允许出现该字段的一个实例。
Basic ConstraintsCA当且仅当 SVID 为签名证书时,此字段必须被设置为 true
Basic ConstraintspathLenConstraint如果实现者希望强制施加有限的 CA 层级深度(例如从现有的私有密钥基础设施(PKI)继承而来),则可设置此字段。
Name ConstraintspermittedSubtrees如果实现者希望使用 URI 名称约束,则可设置此字段。它将在本文档的未来版本中成为必需项。
Key UsagekeyCertSign当且仅当 SVID 为签名证书时,此字段必须被设置。
Key UsagecRLSign当且仅当 SVID 为签名证书时,此字段方可被设置。
Key UsagekeyAgreement当且仅当 SVID 为叶子证书时,此字段方可被设置。
Key UsagekeyEncipherment当且仅当 SVID 为叶子证书时,此字段方可被设置。
Key UsagedigitalSignature当且仅当 SVID 为叶子证书时,此字段必须被设置。
Extended Key Usageid-kp-serverAuth此字段可为叶子证书或签名证书设置。
Extended Key Usageid-kp-clientAuth此字段可为叶子证书或签名证书设置。

内容基于 SPIFFE/SPIRE 官方开源资料整理与翻译,仅供学习交流;商标与版权归各自所有者。SPIFFE 与 SPIRE 是 CNCF 项目。