惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
雷峰网
雷峰网
S
SegmentFault 最新的问题
博客园 - 【当耐特】
博客园_首页
量子位
爱范儿
爱范儿
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
V
V2EX
美团技术团队
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
博客园 - 聂微东
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

土法炼钢兴趣小组的算法知识备份

国密算法与国密 TLS 系列索引 【系统架构设计】架构质量属性:不只是"高可用高性能" 【系统架构设计百科】告警策略:如何避免"狼来了" 【系统架构设计】CQRS:读写分离的架构哲学 【系统架构设计】空间架构:极端扩展场景的解法 【系统架构设计】微服务架构深度审视:优势、代价与适用边界 【系统架构设计】扩展性原理:水平、垂直与对角扩展 【系统架构设计】无状态设计:扩展的第一步也是最难的一步 【系统架构设计】缓存架构:从本地到分布式的多级缓存体系 【系统架构设计】管道与过滤器:Unix 哲学的架构表达 【系统架构设计】复杂性管理:架构的核心战场 【系统架构设计】消息队列架构:异步解耦的设计与陷阱 【系统架构设计】CDN 架构:全球加速的设计原理 【系统架构设计】连接池设计:被忽视的性能杀手 【系统架构设计】弹性设计模式:熔断器、舱壁与超时 【系统架构设计】高可用设计模式:冗余、故障转移与仲裁 【系统架构设计】容量规划:从拍脑袋到数据驱动 【系统架构设计】数据库扩展:分库分表的工程实践与替代方案 【系统架构设计】SLO 工程:可靠性的量化管理 【系统架构设计】性能建模:用数学思维分析系统瓶颈 【系统架构设计】混沌工程:主动验证系统的韧性 【系统架构设计】零拷贝与内存映射:数据搬运的极致优化 【系统架构设计】线程模型:从 thread-per-request 到协程 【系统架构设计】容灾架构:多活与灾备设计 【系统架构设计】数据库性能模式:索引、查询与连接管理 【系统架构设计】数据建模:从关系范式到文档模型的真实权衡 【系统架构设计】吞吐量优化:批处理、流水线与并发模型 【系统架构设计】流处理架构:从批处理到实时的范式迁移 【系统架构设计】搜索引擎架构:倒排索引之上的系统设计 【系统架构设计】时序数据架构:监控与 IoT 的存储设计
【身份与访问控制工程】服务身份:mTLS、SPIFFE/SPIRE 与 Wor...
Liao Tonglang · 2026-04-21 · via 土法炼钢兴趣小组的算法知识备份

前面的文章全部聚焦于”人的身份”——OIDC、SAML、MFA、Passkey 解决的都是”坐在键盘前的人是谁”。但在一个数百微服务的 K8s 集群中,每个服务之间的调用也需要身份。当 order-service 调用 payment-service 时,后者怎么知道”这个请求的确来自 order-service,而不是某个攻入集群内部的进程在伪造”?

这就是 Workload Identity(工作负载身份)——对软件工作负载(不是人)的身份管理。在零信任架构中(参见本站零信任架构篇),Workload Identity 和 User Identity 同等重要。本文从三个技术层面讨论:传输层(mTLS)、平台层(SPIFFE/SPIRE)、应用层(OAuth 2.0 JWT Profile)。

1.1 基本原理

普通 TLS(单向 TLS)只验证服务端:客户端确认”我连接的是真的 payment-service”。mTLS(双向 TLS)同时也验证客户端:服务端确认”连接我的是真的 order-service”。

sequenceDiagram
    participant Client as order-service
    participant Server as payment-service

    Client->>Server: 1. ClientHello
    Server->>Client: 2. ServerHello + Server Certificate (cert.payment)
    Client->>Client: 3. 验证 Server Cert (CA 链 + DNS SAN)
    Client->>Server: 4. Client Certificate (cert.order)
    Server->>Server: 5. 验证 Client Cert (CA 链 + SPIFFE ID)
    Server->>Client: 6. TLS 握手完成
    Client->>Server: 7. 加密的应用数据

1.2 证书管理与 X.509 扩展

mTLS 的部署难点在证书生命周期管理——不是”怎么签”(OpenSSL 一行命令),而是:

  1. 签发:谁为新部署的服务签发证书?
  2. 轮换:证书过期前怎么自动换新?
  3. 吊销:服务被下线后,它的旧证书怎么被标记为无效?
  4. 信任域:dev 环境的证书在 prod 环境能用吗?

K8s 生态的 cert-manager(基于 ACME 协议,与 Let’s Encrypt 集成的证书自动管理工具)解决了第 1-2 个问题。对于 mTLS 中的内部证书,cert-manager 可以维护一个内部 CA,为每个 Pod 自动签发短期证书(如 24 小时有效期),并通过 cert-manager-csi-driver 将证书挂载到 Pod 的文件系统或 tmpfs。

X.509 证书的 SAN(Subject Alternative Name)扩展中的 URI 类型是编排系统中最常用的服务身份表达方式。例如:URI:spiffe://cluster.local/ns/payment/sa/payment-sa

1.3 mTLS 的局限性

mTLS 解决的问题:传输层的身份——确认对方有合法证书。

mTLS 不解决的问题: - 证书管发本身:谁是 CA?CA 信任什么? - 身份模型:证书中的身份怎么映射到”这个服务有权访问这个 API”? - 应用层授权:mTLS 通过后,order-service 能不能 POST 到 payment-service 的 /refund 端点?

这就是 SPIFFE 和 OAuth 2.0 Token Exchange 进入讨论的原因。

二、SPIFFE/SPIRE:平台层的身份框架

2.1 SPIFFE ID

SPIFFE(Secure Production Identity Framework for Everyone,CNCF Graduated)定义了一种通用的工作负载身份标识格式——SPIFFE ID:

spiffe://trust-domain/ns/namespace/sa/service-account
spiffe://cluster.prod.example.com/ns/payments/sa/payment-processor

URI 结构: - spiffe:// 固定 scheme - trust-domain:信任域——通常对应一个 K8s 集群或一个组织边界 - /ns/{namespace}/sa/{service-account}:K8s 工作负载的典型路径。也可以是 /node/{hostname} 或自定义路径

2.2 SPIRE:SPIFFE 的参考实现

SPIRE(SPIFFE Runtime Environment)是 SPIFFE 的 CNCF 参考实现,负责 SPIFFE ID 的发放和验证。

SPIRE 的核心组件:

flowchart TD
    SPIRE-Server["SPIRE Server<br/>(集群级别)"]
    SPIRE-Agent1["SPIRE Agent<br/>(Node 1)"]
    SPIRE-Agent2["SPIRE Agent<br/>(Node 2)"]

    Workload1["Pod: payment-service<br/>SA: payment-sa"]
    Workload2["Pod: order-service<br/>SA: order-sa"]

    SPIRE-Agent1 --> SPIRE-Server
    SPIRE-Agent2 --> SPIRE-Server

    Workload1 -->|"Workload API (Unix socket)"| SPIRE-Agent1
    Workload2 -->|"Workload API (Unix socket)"| SPIRE-Agent2

    SPIRE-Agent1 -->|"Node Attestation"| SPIRE-Server
    SPIRE-Agent2 -->|"Node Attestation"| SPIRE-Server
    Workload1 -.->|"mTLS with SVID"| Workload2

关键概念:

  • SVID(SPIFFE Verifiable Identity Document):一个可验证的身份文件——通常是 X.509 证书(含 SPIFFE ID 在 SAN URI 中)或 JWT。
  • Node Attestation:SPIRE Agent 在加入集群时向 SPIRE Server 证明”我是一个合法的节点”——通过云平台元数据(AWS instance-identity-document)、TPM 或手动 token。
  • Workload Attestation:SPIRE Agent 在发放 SVID 前验证调用方是真的 workload——通过检查进程的 UID/GID、K8s 的 ServiceAccount token review 或 Unix socket 调用者。
  • Workload API:每个 Node 上的 SPIRE Agent 通过 Unix Domain Socket 提供 gRPC API,Pod 通过 Volume 挂载该 socket 来获取 SVID。

2.3 SPIRE 与 Istio/Service Mesh 的关系

SPIRE 和 Istio 不是竞品,是互补的:

  • Istio:做流量层(mTLS 加密、负载均衡、路由、可观测)。
  • SPIRE:做身份层(身份证明、证书管发、多集群多云的统一信任域)。

Istio 可以配置为使用 SPIRE 作为其 CA,而不是使用 Istio 自带的内置 CA。这样 SPIRE 负责”这个 workload 是谁”,Istio 负责”用这个身份的证书做 mTLS 和鉴权”。

三、OAuth 2.0:应用层的服务身份

mTLS + SPIFFE 解决了传输层和平台层的身份。但很多场景中,服务需要”应用层”的身份令牌——不带 TLS 层的 OAuth 2.0 Access Token,用于调用 REST API 时的 Bearer 认证。

3.1 Client Credentials Grant

最简单的服务间 OAuth 模式:服务作为 OAuth 客户端,用 client_id + client_secret 请求 Access Token。

POST /token
Authorization: Basic base64(client_id:client_secret)
grant_type=client_credentials&scope=payment:write

→ { "access_token": "eyJhbG...", "token_type": "Bearer", "expires_in": 3600 }

Client Credentials Grant 的问题:

  • secret 分发:每个服务需要拿到 client_secret——K8s Secret 或 Vault 注入。
  • 身份不是 SPIFFE ID:Access Token 中的 sub 是 OAuth client 的 ID(如 payment-service),不是 SPIFFE ID(spiffe://cluster.local/ns/payment/sa/payment-sa)。如果要让两者对齐,需要在 IdP 层面建立映射。
  • 无平台亲和性:同一个 client_secret 可以在集群内外、跨云使用——这不是安全漏洞,但在零信任模型中这是”信任面太宽”。

3.2 JWT Profile for OAuth 2.0(RFC 7523)

更好的方案是:服务用它已有的 SVID(SPIFFE 证书或 JWT)来向 OP 换取 OAuth Access Token。这称为 JWT Profile for OAuth 2.0(RFC 7523)。SPIRE 可以生成 JWT-SVID,这个 JWT 本身就是 RFC 7523 格式的 assertion:

POST /token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=eyJhbG...jwt_svid...

OP 验证 JWT-SVID:
  - 签名(用 SPIRE 信任域的 JWKS)
  - issuer (spiffe://cluster.local)
  - subject (spiffe://cluster.local/ns/order/sa/order-sa)
  - audience (OP 的 token endpoint)
  - 有效期

→ { "access_token": "eyJhbG...", "token_type": "Bearer" }

这种方式把平台身份(SPIFFE ID)和 OAuth 令牌链在了一起——Access Token 中可以编码对应的 SPIFFE ID,使得资源服务器能追溯到”调用方到底是哪个 K8s workload”。

四、三种层次的选型

层次 技术 粒度 部署复杂度 身份信任根
传输层 mTLS 连接 高(需要 CA 和证书管发) TLS 证书的 CA 链
平台层 SPIFFE/SPIRE 工作负载(Pod/进程) 中-高(需要部署 SPIRE) 节点证明(云平台/TPM)
应用层 OAuth 2.0 Client Credentials / JWT Profile 应用逻辑身份 低-中 OP 的客户端 secret 或 SPIFFE SVID

工程选择不是一个”选哪个”的问题——三者在零信任架构中是同时需要的:

  1. mTLS 保证传输加密和连接级别的相互认证。
  2. SPIFFE/SPIRE 提供平台级别的、可审计的、自动化的身份发行。
  3. OAuth 2.0 Token Exchange 将平台身份转化为应用可用的 Bearer Token,方便在 HTTP API 中传递。

对于没有 K8s 或 Service Mesh 的小规模部署,Client Credentials Grant + HashiCorp Vault 管理 secret 是务实的起点。


上一篇风险感知认证:设备信任、异常登录与挑战升级 下一篇RBAC、ABAC、ReBAC:权限模型怎么选

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-06-12 · architecture / security

零信任安全架构深度系列

零信任是 IAM 的自然延伸——当身份变成新边界,VPN 的'拨入即信任'模型必须被'永不信任、始终验证'取代。本系列从 NIST SP 800-207 规范、Google BeyondCorp 六篇论文、SPIFFE/SPIRE 联邦到微分段、持续验证、ZTNA 和零信任迁移的工程策略,系统拆解零信任的每一种组件和每一步实施。

2026-06-13 · architecture / security

【身份与访问控制工程】IAM 全景:为什么这是高价值赛道

从 2020 年 SolarWinds 到 2024 年 Okta 支持系统泄露,身份基础设施的安全失败反复证明一件事:IAM 不是 IT 支撑系统,而是安全架构的承重墙。本文建立现代 IAM 的全景地图——从认证协议、令牌体系、权限模型到身份治理与平台选型,给出 5 个贯穿全系列的核心问题。