Reviewed-on: #3
workload-sts
项目已停止开发。 本方案已由 SPIRE 的 workload attestation、SPIFFE Workload API、 JWT-SVID/X.509-SVID 和 OIDC Discovery Provider 替代。仓库仅保留设计与 PoC 历史, 不应部署或继续扩展。详见
docs/superseded-by-spire.md。
面向 workload identity 的 OAuth 2.0 Security Token Service。它验证 Kubernetes ServiceAccount JWT 等上游身份,执行签发授权,并生成短期、限定 audience 的 JWT assertion。
项目只负责“验证身份后签发 assertion”。OpenBao 等下游资源服务器自行验证 JWT、 映射本地权限并管理自己的 token、lease 和凭据生命周期。
项目在 PoC 阶段停止,未提供可运行服务或稳定 API。仓库中的 RFC 8693 与 OpenBao Transit 代码只用于保存当时的技术验证,不构成受支持的软件。
目标
- 按 OAuth 2.0 Authorization Server 和 Token Exchange 标准语义提供接口,优先复用 成熟协议库。
- 第一阶段验证 Kubernetes projected ServiceAccount JWT,并为其他 credential issuer 保留独立 verifier 扩展点。
- 将已验证的上游身份映射为稳定的 workload principal。
- 根据 principal、audience、scope 和请求上下文判断是否允许签发,由服务端选择唯一的 token profile。
- 要求每个请求显式提交
client_id;v1 不认证该字段,只以client_id_claimed记录, 为以后注册 public/confidential client 保持稳定请求形状。 client_id长度为 3–63,只允许小写字母、数字和中横线,且必须以字母或数字开头和 结尾。- 使用短期 JWT 隔离上游证明与下游访问凭据;一个 token 只面向明确的 audience。
- 让 OpenBao 保持机密、PKI、动态凭据和自身 token 生命周期的权威后端。
- 让 Kubernetes、OpenBao 和普通 OAuth2 Resource Server 使用各自的原生 JWT 验证 能力,而不要求业务系统理解上游身份来源。
- 提供结构化且不泄露 bearer token 的交换审计。
- 使用 OpenTelemetry trace/metric SDK 与标准 HTTP instrumentation,且不采集 token、 请求体或高基数身份字段。
非目标
- 不提供用户目录、密码登录、MFA 或交互式 OIDC 登录;人工身份由现有 IdP 提供。
- 不读取、缓存或代理 OpenBao 中的机密。
- 不替调用方登录 OpenBao,也不签发、续期或撤销调用方的 OpenBao client token;服务 自身可以使用独立的 Kubernetes identity 获取访问 Transit 所需的最小权限运行凭据。
- 不定义或同步 OpenBao policy、Kubernetes RBAC 或下游应用权限。
- 不管理 Gitea Actions job、runner、Kubernetes Pod、PVE VM 或 microVM 生命周期。
- 不实现 PVE/microVM vsock metadata service 或平台 attestation。
- 不自创策略表达式语言、workload identity 格式或私有 token exchange 协议。
- 第一阶段不直接返回 OpenBao token、SSH certificate、数据库密码或云凭据;以后增加 credential materializer 必须通过新的规格和安全评审。
核心流程
以 Kubernetes 中的 CI workload 登录 OpenBao 为例:
CI Pod
|
| projected ServiceAccount JWT
| aud = https://identity.ad.ddupan.top
v
workload-sts
| 1. 验证 Kubernetes issuer、signature、audience 和时效
| 2. 映射 workload principal
| 3. 检查 OpenBao audience 的签发策略
| 4. 签发短期 JWT assertion
v
OpenBao JWT auth
| 验证 iss、sub、aud 和 bound claims
| 映射本地 role/policy
v
OpenBao client token
workload-sts 的职责在签发 JWT assertion 后结束。Bao token 的 TTL、renewal、
revocation、lease 以及 CI job 结束后的清理由 OpenBao 和调用方负责。
协议身份
当前设计使用:
OAuth issuer: https://identity.ad.ddupan.top
OAuth issuer 是稳定的网络协议身份,不与进程部署位置绑定。SPIFFE 可以作为未来的上游 身份协议,但第一阶段不建立 SPIFFE trust domain,也不把内部 principal 伪装成 SPIFFE ID。
文档
- SPIRE 替代决策:
docs/superseded-by-spire.md - 系统边界与数据流:
docs/architecture.md - 规范行为与待决策项:
docs/specification.md - 威胁模型与安全要求:
docs/security.md - 首轮库与签名 PoC 结论:
docs/poc.md
其余文档均为替代决策前的历史材料,不再代表实施计划。
计划中的最小纵向切片
- 发布 Authorization Server metadata 和 JWKS。
- 验证一个 Kubernetes projected ServiceAccount JWT。
- 按 RFC 8693 处理一次 token exchange。
- 根据 SA binding 中的 issuance rule、请求 scope 和 CEL 条件决定是否签发。
- 签发
aud指向 OpenBao 的短期 JWT。 - 由 OpenBao JWT auth 验证该 JWT 并返回受限 Bao token。
代码与发布物托管在
git.ddupan.top/panxiao81/workload-sts。