diff --git a/AGENTS.md b/AGENTS.md index 09888c4..6017b89 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,12 @@ # workload-sts - AI Agent Guide +## Project Lifecycle + +- 本项目已由 SPIRE 替代并停止开发,详见 `docs/superseded-by-spire.md`。 +- 不再增加功能、依赖、部署物或发布流程;现有代码只作为 PoC 历史保留。 +- 除维护替代决策、修复敏感信息或协助归档外,新的 workload identity 工作应进入独立 + SPIRE 基础设施项目。 + ## Specification-Driven Development - 所有新功能和外部可观察行为变更都采用 specification-first:先更新 diff --git a/README.md b/README.md index fc65725..8b875db 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # workload-sts +> **项目已停止开发。** 本方案已由 SPIRE 的 workload attestation、SPIFFE Workload API、 +> JWT-SVID/X.509-SVID 和 OIDC Discovery Provider 替代。仓库仅保留设计与 PoC 历史, +> 不应部署或继续扩展。详见 [`docs/superseded-by-spire.md`](docs/superseded-by-spire.md)。 + 面向 workload identity 的 OAuth 2.0 Security Token Service。它验证 Kubernetes ServiceAccount JWT 等上游身份,执行签发授权,并生成短期、限定 audience 的 JWT assertion。 @@ -7,8 +11,8 @@ assertion。 项目只负责“验证身份后签发 assertion”。OpenBao 等下游资源服务器自行验证 JWT、 映射本地权限并管理自己的 token、lease 和凭据生命周期。 -项目目前处于 PoC 阶段,尚未提供可运行服务或稳定 API。RFC 8693 请求约束和 OpenBao -Transit RS256/JWKS 互操作已有可执行测试。 +项目在 PoC 阶段停止,未提供可运行服务或稳定 API。仓库中的 RFC 8693 与 OpenBao +Transit 代码只用于保存当时的技术验证,不构成受支持的软件。 ## 目标 @@ -84,13 +88,13 @@ ID。 ## 文档 +- SPIRE 替代决策:[`docs/superseded-by-spire.md`](docs/superseded-by-spire.md) - 系统边界与数据流:[`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 文档。 +其余文档均为替代决策前的历史材料,不再代表实施计划。 ## 计划中的最小纵向切片 diff --git a/docs/architecture.md b/docs/architecture.md index aa262fe..cb71904 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,5 +1,8 @@ # 系统架构 +> **历史文档:** 本架构已由 SPIRE 方案替代,不再作为实施目标。参见 +> [`superseded-by-spire.md`](superseded-by-spire.md)。 + 本文是 [`specification.md`](specification.md) 的架构视图。规范定义外部行为,本文解释 组件边界;二者冲突时以规范为准。当前 v0.1 设计已经批准。 diff --git a/docs/poc.md b/docs/poc.md index e981b19..173f291 100644 --- a/docs/poc.md +++ b/docs/poc.md @@ -1,5 +1,8 @@ # 首轮协议与签名 PoC +> **历史文档:** 此 PoC 已结束且不会演进为服务。项目由 SPIRE 替代,参见 +> [`superseded-by-spire.md`](superseded-by-spire.md)。 + | 项目 | 内容 | | --- | --- | | 状态 | Complete | diff --git a/docs/security.md b/docs/security.md index f571048..b9cc061 100644 --- a/docs/security.md +++ b/docs/security.md @@ -1,5 +1,8 @@ # 安全模型 +> **历史文档:** workload-sts 未投入生产,本安全设计已停止实施。替代方案见 +> [`superseded-by-spire.md`](superseded-by-spire.md)。 + | 项目 | 内容 | | --- | --- | | 状态 | Approved | diff --git a/docs/specification.md b/docs/specification.md index f56d66a..0a6d31e 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -2,13 +2,16 @@ | 项目 | 内容 | | --- | --- | -| 状态 | Approved | +| 状态 | Superseded by SPIRE | | 版本 | v0.1 | | 最后更新 | 2026-09-10 | 本文定义 workload-sts 的第一阶段外部合同、范围、安全边界和验收标准。内部包结构和 具体 OAuth2/JWT/HTTP 库不属于外部兼容性合同。 +> 本规格从未进入生产,现已停止实施。替代方案和理由见 +> [`superseded-by-spire.md`](superseded-by-spire.md)。以下内容仅作为历史设计记录。 + ## 1. 背景 homelab 中的 Kubernetes workload、CI worker、长期主机以及未来的外部 attestation diff --git a/docs/superseded-by-spire.md b/docs/superseded-by-spire.md new file mode 100644 index 0000000..f5bf746 --- /dev/null +++ b/docs/superseded-by-spire.md @@ -0,0 +1,98 @@ +# 由 SPIRE 替代 workload-sts + +| 项目 | 内容 | +| --- | --- | +| 状态 | Accepted | +| 日期 | 2026-09-13 | +| 影响 | 停止 workload-sts 开发,不部署现有 PoC | + +## 决策 + +停止实现和部署 workload-sts。workload identity 的签发、轮换、workload attestation 与 +OIDC/JWKS federation 改由 SPIRE 提供;OpenBao 继续负责 secret、policy、动态凭据和 +自身 token 生命周期。 + +仓库保留为设计和 PoC 历史,不删除代码,但不再接受功能开发。若未来出现 SPIRE 和目标 +Resource Server 无法表达的、已经确认的 token transformation 或 credential +materialization 需求,应基于实际用例重新立项,而不是恢复本规格。 + +## 原因 + +workload-sts 原计划自行实现: + +```text +验证 Kubernetes 或其他 workload credential + -> workload principal 映射 + -> audience/scope 策略 + -> 短期 JWT 签发 + -> OIDC metadata/JWKS +``` + +SPIRE 已原生提供其中决定系统安全性的部分: + +- SPIRE Agent 和 Server 执行 node attestation 与 workload attestation; +- Kubernetes workload 可按 namespace、ServiceAccount 等 selector 注册 SPIFFE ID; +- Linux、VM 和容器 workload 可使用 Unix、systemd、Docker 及相应 node attestor; +- workload 通过 SPIFFE Workload API 获取自动轮换的 X.509-SVID 或指定 audience 的 + JWT-SVID; +- SPIRE OIDC Discovery Provider 发布 discovery document 和 JWKS,使支持 OIDC/JWT 的 + Resource Server 可以直接信任 JWT-SVID; +- SPIFFE federation 与 OIDC federation 覆盖后续跨环境信任。 + +继续开发 workload-sts 会重复实现 attestation 后的身份签发、密钥轮换和 federation, +同时引入新的数据库、策略、签名服务和高价值网络端点,安全收益为负。 + +## 替代架构 + +面向 OpenBao 的基本流程为: + +```text +workload + -> local SPIRE Agent Workload API + -> JWT-SVID (sub = SPIFFE ID, aud = OpenBao audience) + -> OpenBao JWT auth + -> OpenBao client token +``` + +OpenBao 直接按受信 issuer、`sub`、audience 和 bound claims 映射 role/policy。本系统不再 +需要 OAuth Token Exchange、内部 principal UUID、Transit JWT signing key 或自己的 +JWKS endpoint。 + +Kubernetes、长期 Linux 主机、PVE VM 和 microVM 的具体 node/workload attestation 由 +新的 SPIRE 基础设施项目设计。PVE/microVM 生命周期和 vsock metadata 仍属于平台项目, +不进入身份控制面。 + +## 不再保留的需求 + +OAuth `scope` 和集中式 CEL 策略原本作为未来扩展点,但当前没有必须由中间 STS 统一 +表达的实际授权需求。OpenBao policy、Kubernetes RBAC 和各 Resource Server 继续负责 +最终授权。 + +如果以后出现下列具体需求,再单独评估小型 broker: + +- Resource Server 无法直接验证 JWT-SVID; +- 必须进行跨 trust domain 的 claim/token transformation; +- 必须返回非 JWT 凭据,且 OpenBao 或目标平台不能原生签发; +- 已有明确消费者需要 OAuth RFC 8693,而不能直接使用 Workload API。 + +仅有“未来可能需要 scope”不足以恢复 workload-sts。 + +## 后续工作 + +新的 SPIRE 项目需要决定: + +1. SPIFFE trust domain 与 SPIFFE ID 命名规范; +2. SPIRE Server/Agent 的部署和高可用边界; +3. Kubernetes、长期主机及 VM 的 node/workload attestor; +4. registration entry 的声明式管理方式; +5. OIDC Discovery Provider 的稳定 HTTPS issuer; +6. OpenBao JWT auth role、audience 和 SPIFFE ID 映射; +7. SVID TTL、key rotation、federation 与灾难恢复。 + +## 参考资料 + +- [SPIRE Use Cases](https://spiffe.io/docs/latest/spire-about/use-cases/) +- [SPIRE Concepts](https://spiffe.io/docs/latest/spire-about/spire-concepts/) +- [Configuring SPIRE](https://spiffe.io/docs/latest/deploying/configuring/) +- [SPIRE OIDC federation and scaling](https://spiffe.io/docs/latest/planning/scaling_spire/) +- [Using SPIRE JWT-SVIDs to authenticate to Vault](https://spiffe.io/docs/latest/keyless/vault/readme/)