第十九章:SPIFFE — 通用工作负载身份框架

“人有身份证,机器也需要身份证。SPIFFE 就是机器世界的身份证标准。”

        mindmap
  root((SPIFFE))
    SPIFFE ID
      trust domain
      path
      格式规范
    SVID
      X.509-SVID
      JWT-SVID
      短生命周期
    Trust Bundle
      信任根
      联邦信任
    Workload API
      Unix Socket
      gRPC
      自动轮换
    设计哲学
      平台无关
      自动化
      零配置
    

19.1 工作负载身份的挑战

在云原生时代,机器身份(工作负载身份)面临独特的挑战:

挑战

描述

数量级

工作负载数量远超人类用户(数十万级)

动态性

容器随时创建和销毁,IP 地址不固定

异构性

跨 Kubernetes、VM、裸机、多云

凭证管理

手动管理证书/密钥不可扩展

信任建立

如何证明”这个进程确实是它声称的服务”

传统方式的问题:
┌──────────┐    ┌──────────┐
│ Service A │───▶│ Service B │
│          │    │          │
│ 如何证明  │    │ 如何验证  │
│ "我是A"? │    │ "它是A"? │
└──────────┘    └──────────┘

方案1: 硬编码密钥 → 泄露风险、无法轮换
方案2: 环境变量   → 容易被窃取
方案3: K8s Secret → 仅限 K8s、明文存储
方案4: Vault      → 需要先认证才能获取密钥(鸡生蛋问题)
方案5: SPIFFE ✅  → 自动化、短生命周期、平台无关

19.2 SPIFFE 是什么

SPIFFE(Secure Production Identity Framework For Everyone)是一套开源标准,为工作负载提供统一的身份框架。它是 CNCF 毕业项目。

SPIFFE 定义了三个核心规范:

  1. SPIFFE ID:工作负载的唯一身份标识

  2. SVID:可验证的身份文档

  3. Workload API:工作负载获取身份的接口

19.3 SPIFFE ID

SPIFFE ID 是一个 URI,格式为:

spiffe://trust-domain/path

示例:
spiffe://example.org/ns/production/sa/web-server
spiffe://example.org/region/us-east/service/payment
spiffe://bank.com/department/trading/app/risk-engine

组成部分

说明

示例

scheme

固定为 spiffe

spiffe://

trust domain

信任域,类似 DNS 域名

example.org

path

工作负载路径,自由定义

/ns/prod/sa/web

Trust Domain 设计原则

推荐的 Trust Domain 命名:
✅ prod.example.com      — 生产环境
✅ staging.example.com   — 预发布环境
✅ cluster1.example.com  — 按集群划分
❌ example.com           — 太宽泛
❌ my-app                — 不像域名

路径设计建议:
/ns/{namespace}/sa/{service-account}     — Kubernetes 风格
/region/{region}/service/{service-name}  — 按区域划分
/env/{environment}/app/{app-name}        — 按环境划分

19.4 SVID — 可验证身份文档

SVID(SPIFFE Verifiable Identity Document)是工作负载的”身份证”,有两种形式:

X.509-SVID

最常用的形式,基于 X.509 证书:

Certificate:
    Subject: O=SPIRE
    Subject Alternative Name:
        URI: spiffe://example.org/ns/prod/sa/web-server  ← SPIFFE ID
    Issuer: O=SPIRE, CN=SPIRE CA
    Validity:
        Not Before: 2024-01-01 00:00:00 UTC
        Not After:  2024-01-01 01:00:00 UTC  ← 1小时有效期!
    Public Key Algorithm: ECDSA P-256

关键特性:

  • SPIFFE ID 存储在证书的 SAN URI 字段

  • 短生命周期(通常 1 小时),自动轮换

  • 用于 mTLS 双向认证

JWT-SVID

基于 JWT 的身份文档,适用于 L7 场景:

{
  "alg": "ES256",
  "kid": "key-1",
  "typ": "JWT"
}
.
{
  "sub": "spiffe://example.org/ns/prod/sa/web-server",
  "aud": ["spiffe://example.org/ns/prod/sa/api-server"],
  "exp": 1709510400,
  "iat": 1709506800
}
.
[signature]

X.509-SVID vs JWT-SVID

维度

X.509-SVID

JWT-SVID

用途

mTLS(L4)

HTTP Header(L7)

验证方式

TLS 握手

Token 验证

受众绑定

✅(aud claim)

代理穿透

性能

高(TLS 层)

中(应用层)

适用场景

服务间直连

API Gateway、L7 代理

19.5 Trust Bundle

Trust Bundle 是信任域的根证书集合,用于验证 SVID:

Trust Domain: example.org
Trust Bundle: [Root CA Certificate]

验证流程:
1. Service A 出示 X.509-SVID
2. Service B 用 example.org 的 Trust Bundle 验证证书链
3. 验证 SAN 中的 SPIFFE ID
4. 信任建立 ✅

19.6 Workload API

Workload API 是工作负载获取 SVID 的标准接口:

┌──────────────┐    Unix Domain Socket    ┌──────────────┐
│   工作负载    │◀────────────────────────▶│  SPIRE Agent │
│  (应用进程)   │    /run/spire/sockets/   │              │
│              │    agent.sock             │  自动签发     │
│  获取 SVID   │                          │  自动轮换     │
│  获取 Bundle │                          │  缓存管理     │
└──────────────┘                          └──────────────┘
// Go 示例:使用 Workload API 获取 SVID
import "github.com/spiffe/go-spiffe/v2/workloadapi"

ctx := context.Background()
source, err := workloadapi.NewX509Source(ctx,
    workloadapi.WithClientOptions(
        workloadapi.WithAddr("unix:///run/spire/sockets/agent.sock"),
    ),
)
defer source.Close()

// 获取 SVID
svid, err := source.GetX509SVID()
fmt.Printf("SPIFFE ID: %s\n", svid.ID)
fmt.Printf("证书有效期: %s\n", svid.Certificates[0].NotAfter)

// 用 SVID 建立 mTLS 连接
tlsConfig := tlsconfig.MTLSClientConfig(source, source, tlsconfig.AuthorizeID(
    spiffeid.RequireID(spiffeid.Must("example.org", "/ns/prod/sa/api-server")),
))

19.7 SPIFFE 与传统方案对比

方案

平台无关

自动轮换

短生命周期

零配置

标准化

K8s ServiceAccount

AWS IAM Role

手动 mTLS

HashiCorp Vault

SPIFFE/SPIRE

19.8 小结

  • SPIFFE 是工作负载身份的开放标准(CNCF 毕业项目)

  • SPIFFE ID 格式:spiffe://trust-domain/path

  • SVID 有两种形式:X.509-SVID(mTLS)和 JWT-SVID(L7)

  • 短生命周期(1小时)+ 自动轮换 = 大幅降低凭证泄露风险

  • Workload API 通过 Unix Socket 提供零配置的身份获取

  • SPIFFE 是平台无关的,可以跨 K8s、VM、多云使用