初始化项目文档与设计规范

This commit is contained in:
2026-09-11 15:44:26 +00:00
commit cc30a7cb6a
6 changed files with 1181 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
# workload-sts
面向 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 RS256/JWKS 互操作已有可执行测试。
## 目标
- 按 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 为例:
```text
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 和调用方负责。
## 协议身份
当前设计使用:
```text
OAuth issuer: https://identity.ad.ddupan.top
```
OAuth issuer 是稳定的网络协议身份,不与进程部署位置绑定。SPIFFE 可以作为未来的上游
身份协议,但第一阶段不建立 SPIFFE trust domain,也不把内部 principal 伪装成 SPIFFE
ID。
## 文档
- 系统边界与数据流:[`docs/architecture.md`](docs/architecture.md)
- 规范行为与待决策项:[`docs/specification.md`](docs/specification.md)
- 威胁模型与安全要求:[`docs/security.md`](docs/security.md)
- 首轮库与签名 PoC 结论:[`docs/poc.md`](docs/poc.md)
v0.1 规范已经批准;首轮 PoC 决定不引入 Fosite,使用 chi 路由、窄协议层、Go JOSE 和
官方 OpenBao API。详见 PoC 文档。
## 计划中的最小纵向切片
1. 发布 Authorization Server metadata 和 JWKS。
2. 验证一个 Kubernetes projected ServiceAccount JWT。
3. 按 RFC 8693 处理一次 token exchange。
4. 根据 SA binding 中的 issuance rule、请求 scope 和 CEL 条件决定是否签发。
5. 签发 `aud` 指向 OpenBao 的短期 JWT。
6. 由 OpenBao JWT auth 验证该 JWT 并返回受限 Bao token。
代码与发布物托管在
`git.ddupan.top/panxiao81/workload-sts`。