SPIFFE

简要概述

SPIFFE(Secure Production Identity Framework for Everyone),是一个软件身份标识的开源标准,以组织和平台无关的方式实现身份标识,是云原生身份认证的“基础设施”。

它定义了以全自动方式获取和验证加密身份所需的接口,是语言、技术栈无关的,为构建分布式系统的通用身份的控制平面提供了标准的支撑。

在实施 SPIFFE 模型必须满足以下前提:

  1. 网络通信是不可信的,可能被攻破;
  2. 运行 SPIFFE 实现的组件的硬件及其运维人员是可靠的。

关键术语

Workload

工作负载是一个单一的软件组件,使用特定配置为了特定的目的而部署,它可以包括多个运行中的软件实例,都执行相同的任务,如:

  1. 一个 MySQL 数据库实例;
  2. 处理队列中的应用程序;
  3. 运行 Web 应用程序的服务部署在虚机集群上,前面有一个负载均衡器;
  4. 独立部署的系统集合,它们共同工作,比如一个使用数据库服务的 Web 应用程序,Web 应用程序和数据库也可以分别被视为单独的工作负载。

对于 SPIFFE 而言,工作负载往往比物理或虚拟节点更精细,通常到节点上的单个进程。这对于在容器编排中托管的工作负载至关重要,其中多个工作负载可以共存(但相互隔离)在单个节点上,也可能跨越多个节点,比如在多台节点上同时运行的弹性扩展的 Web 服务器。

虽然工作负载的粒度会根据上下文而变化,但在使用 SPIFFE 前提下,必须保证一个工作负载与其他之间足够隔离,以防恶意工作负载在颁发后窃取另一个工作负载的凭证,这种隔离的强度和实现方式不在 SPIFFE 的范围之内。

SPIFFE ID

格式为一个统一资源标识符(URI),由字符串组成,用于唯一明确定义一个工作负载,如下:

spiffe://信任域(trust_domain)/工作负载标志(workload identifier)

工作负载标识符唯一标识信任域内的特定工作负载。也可以分配给工作负载运行的中间系统,如一组虚拟机。例如,spiffe://acme.com/billing/payments 是一个有效的 SPIFFE ID。

Trust Domain

信任域对应于系统的信任根(域名格式)可以代表一个人、组织、环境或部门,它们部署运行着独立的 SPIFFE 基础设施,如:

dev.example.com
prod.example.com

在同一信任域中识别的所有工作负载都会被分配身份文件,这些文件可以根据信任域的根密钥进行验证。它用于组织和隔离不同部门的身份和信任,不同信任域之间的工作负载具有不同的信任关系,这有助于确保在多个组织或环境之间建立安全的身份验证和授权机制。

这种模型使得 SPIFFE 能够处理分布式系统中的身份验证和授权需求,特别是在云原生环境中,其中不同实体需要进行身份验证和授权,一般建立信任域按照以下建议执行:

  1. 将位于不同物理位置,如不同数据中心或云区域
  2. 将不同安全实践环境,如开发、测试、或生产环境

这是为了确保在不同的环境中,工作负载具有适当的隔离和信任,不同的信任域之间可能会有不同的信任关系和安全政策,因此将它们分开有助于更好地管理和维护身份验证和授权的机制,有助于提高安全性和降低潜在的风险。

SPIFFE Verifiable Identity Document (SVID)

SVID(SPIFFE Verifiable Identity Document)是工作负载向资源或调用方证明其身份的文件。

一个有效的 SVID 必须被信任域内的授权机构签名,它包含一个单一的 SPIFFE ID,代表服务身份。它在一份加密可验证的文件中编码 SPIFFE ID,目前支持两种格式:X.509 证书或 JWT 令牌。

由于 JWT 令牌容易受到重放攻击的影响,即攻击者在传输中获得令牌后可以使用它来冒充工作负载,因此建议在可能的情况下使用X.509-SVID。但在某些情况下,JWT令牌格式可能是唯一的选择,例如,当您的架构在两个工作负载之间有一个L7代理或负载均衡器时。

SPIFFE Workload API

提供 X.509 格式的身份证件(X.509-SVID)接口:

  1. 身份信息:以 SPIFFE ID 形式描述的身份;
  2. 私钥:与 SPIFFE ID 关联的私钥,可用于代表工作负载对数据进行签名。相应的短期X.509证书也被创建,即X.509-SVID。这可以用于建立TLS或以其他方式对其他工作负载进行身份验证。
  3. 证书集:称为信任捆绑(trust bundle)的一组证书,工作负载可以使用它来验证另一个工作负载呈现的X.509-SVID。

提供 JWT 格式的身份文件(JWT-SVID)接口:

  1. 身份信息:以 SPIFFE ID 形式描述的身份;
  2. JWT 令牌:身份文件中包含的 JWT 令牌;
  3. 证书集:称为信任捆绑(trust bundle)的一组证书,工作负载可以使用它来验证其他工作负载的身份。

以上两种 API 不要求调用工作负载具有对自身身份的任何了解,也不要求在调用 API 时具有任何身份验证令牌,这意味着您的应用程序不需要与工作负载一起部署任何身份验证密钥。这个与 AWS EC2 实例元数据 APIGoogle GCE 实例元数据 API 类似。

为了保证密钥泄漏导致风险的最小化,所有私钥(及相应的证书)都是短暂的且经常轮换,并在过期之前由工作负载自动刷新(工作负载可以在相应的密钥过期之前从工作负载API请求新的密钥和信任捆绑),这种自动轮换和刷新的机制有助于提高安全性,防止潜在的长时间持有同一密钥的风险。

为 grpc 接口,定义见 workloadapi.proto

Trust Bundle

当使用 X.509-SVID 时,目标工作负载使用信任捆绑来验证源工作负载的身份,信任捆绑是一组一个或多个证书颁发机构(CA)根证书,工作负载应该将其视为可信任的,它包含 X.509 和 JWT-SVID 的公钥材料。

用于验证 X.509 SVID 的公钥材料是一组证书,用于验证 JWT 的公钥材料是原始公钥,信任捆绑的内容经常进行轮换,当工作负载调用工作负载 API 时,它会检索信任捆绑。

信任包中不会包含除公钥以外的其他敏感内容,可以被随意传播。




最后修改 2023.11.14: feat: 添加零信任模型 (a9801ad)