基础设施与最小 PoC 已完成(2026-09-14)。 SPIRE、OIDC discovery 与 OpenBao JWT exchange 已上线并完成端到端验证;详细操作见 platform/spire/RUNBOOK.md。本 issue 保持 open,用于跟踪真实 CI/AI Agent、非 Kubernetes workload、SeaweedFS STS、HA 与恢复验证。
platform/spire/RUNBOOK.md
为 Kubernetes、CI、AI Agent、长期 Linux 服务及未来的 Proxmox/microVM 临时计算实例建立统一的 workload identity:运行中的 workload 不持有预置长期凭据,而是由基础设施完成节点与进程证明后,取得短期、自动轮换的身份。
统一的机器主体使用 SPIFFE ID,例如:
spiffe://ddupan.top/k8s/<cluster>/ns/<namespace>/sa/<service-account> spiffe://ddupan.top/ci/gitea/<repository> spiffe://ddupan.top/agent/<class>/<instance> spiffe://ddupan.top/compute/instance/<instance-id> spiffe://ddupan.top/host/<host>/service/<systemd-unit>
采用职责分离,而不是自研完整 OIDC/IAM:
人类身份:现有 Samba AD + Authelia AD 用户目录、交互式登录、MFA、OIDC及 legacy forward-auth 机器身份:SPIFFE/SPIRE Node Attestation、Workload Attestation、X.509-SVID、JWT-SVID 机密与凭据:OpenBao Secret、PKI、SSH CA、动态凭据及目标服务凭据交换 资源执行面:各目标服务 OpenBao policy、SeaweedFS IAM policy、Kubernetes RBAC、Compute/DBaaS RBAC
Authelia 与 SPIRE 分别作为当前的人类身份 issuer 和机器身份根。消费端可以同时信任两个 issuer;不强制把 SPIRE JWT 再包装成人类 IdP 签发的 Token。Keycloak 仅作为未来人类 IAM 明确出现协议或管理能力缺口时的备选,不属于本方案依赖,也不安排迁移。
SPIRE 负责回答“当前调用进程是否有资格获得某个 SPIFFE ID”,不承担人类登录或通用资源授权。目标服务根据稳定的 SPIFFE ID 映射本地角色,避免为每个 workload 重复维护独立身份。
后续评估 x509pop、sshpop、TPM DevID 或自定义 NodeAttestor,替代通用 join token。
x509pop
sshpop
GitHub-hosted Actions 等无法直接访问本地 SPIRE Agent 的环境,保留外部 OIDC federation/适配器方案。适配器只负责验证外部 proof 并映射稳定 principal,不拥有用户目录、签名根或资源 policy。
只验证以下最短链路:
Kubernetes 测试 Pod -> SPIRE workload attestation -> 获取 aud=openbao 的 JWT-SVID -> OpenBao JWT auth 验证 SPIRE OIDC Discovery/JWKS -> 映射专用 Bao policy -> 签发短期 Bao token -> lookup-self 验证最小 policy,并主动 revoke-self
验收标准:
sub
aud
openbao
lookup-self
revoke-self
AssumeRoleWithWebIdentity
credential-exec
语义上只维护两类规则:
JWT 的 audience、claims 和下游 role mapping 是授权传递与执行机制,不应成为额外的人工事实源。多个 workload 共享同一平台角色时,只新增主体到角色的绑定,不复制整份资源 policy。
现有 SeaweedFS 继续由 Helm 管理。seaweedfs-operator 的 IAM CRD 要求关联 Operator 管理的 Seaweed CR,不适合作为当前 brownfield Helm 部署仅为 IAM 而引入,因此不采用 Operator 接管路线。
seaweedfs-operator
Seaweed
迁移期间继续把现有 -s3.config 视为静态 S3 身份的唯一运行配置。长期目标是使用 SPIRE JWT-SVID 调用 SeaweedFS Web Identity/STS,逐步移除 workload 的长期 AK/SK;Terraform/OpenTofu backend 等兼容性未经验证的调用方暂时保留独立、最小权限且可轮换的静态身份。
-s3.config
SPIRE 基础设施已通过 #51 上线并完成首次验收:
spire
bdacc03e
[email protected]
2/2
localpv-zfs-ceph
k8s_psat
issuer
jwks_uri
https://spire-oidc.ad.ddupan.top
下一步仍是增加显式测试 workload/ClusterSPIFFEID,暴露 OIDC HTTPS route,并验证 JWT-SVID 登录 OpenBao。
ClusterSPIFFEID
SPIRE → OpenBao JWT-SVID 端到端 PoC 已完成:
jwt-spire
spire-poc
aud=openbao
spiffe://ddupan.top/ns/spire-poc/sa/spire-jwt-poc
No changes
由此已验证完整链路:Kubernetes workload → SPIRE Workload API → JWT-SVID → OpenBao JWT auth → 短期最小权限 token。下一步可将 PoC role 替换/扩展为真实 CI 与 AI Agent workload policy。
详细使用文档已通过 #54 合并。新增 platform/spire/RUNBOOK.md,覆盖:
no identity issued
SPIRE README 与 OpenBao README 均已增加入口,并修正 PoC 状态。
No dependencies set.
The note is not visible to the blocked user.
状态与优先级
基础设施与最小 PoC 已完成(2026-09-14)。 SPIRE、OIDC discovery 与 OpenBao JWT exchange 已上线并完成端到端验证;详细操作见
platform/spire/RUNBOOK.md。本 issue 保持 open,用于跟踪真实 CI/AI Agent、非 Kubernetes workload、SeaweedFS STS、HA 与恢复验证。目标
为 Kubernetes、CI、AI Agent、长期 Linux 服务及未来的 Proxmox/microVM 临时计算实例建立统一的 workload identity:运行中的 workload 不持有预置长期凭据,而是由基础设施完成节点与进程证明后,取得短期、自动轮换的身份。
统一的机器主体使用 SPIFFE ID,例如:
架构决策
采用职责分离,而不是自研完整 OIDC/IAM:
Authelia 与 SPIRE 分别作为当前的人类身份 issuer 和机器身份根。消费端可以同时信任两个 issuer;不强制把 SPIRE JWT 再包装成人类 IdP 签发的 Token。Keycloak 仅作为未来人类 IAM 明确出现协议或管理能力缺口时的备选,不属于本方案依赖,也不安排迁移。
SPIRE 负责回答“当前调用进程是否有资格获得某个 SPIFFE ID”,不承担人类登录或通用资源授权。目标服务根据稳定的 SPIFFE ID 映射本地角色,避免为每个 workload 重复维护独立身份。
初始身份与证明方式
Kubernetes
Proxmox / microVM 临时实例
后续评估
x509pop、sshpop、TPM DevID 或自定义 NodeAttestor,替代通用 join token。长期 Linux 主机及服务
x509pop、sshpop或未来的 TPM attestation;外部 CI
GitHub-hosted Actions 等无法直接访问本地 SPIRE Agent 的环境,保留外部 OIDC federation/适配器方案。适配器只负责验证外部 proof 并映射稳定 principal,不拥有用户目录、签名根或资源 policy。
首个 PoC(已完成,2026-09-14)
只验证以下最短链路:
验收标准:
sub是预期 SPIFFE ID,aud严格绑定openbao;lookup-self/revoke-self最小权限,不允许读取业务 secret;后续阶段
AssumeRoleWithWebIdentity签发短期 S3 凭据;credential-exec从 Workload API 获取 JWT-SVID,再为子进程注入目标系统的短期凭据;Policy 边界
语义上只维护两类规则:
JWT 的 audience、claims 和下游 role mapping 是授权传递与执行机制,不应成为额外的人工事实源。多个 workload 共享同一平台角色时,只新增主体到角色的绑定,不复制整份资源 policy。
SeaweedFS 与静态凭据
现有 SeaweedFS 继续由 Helm 管理。
seaweedfs-operator的 IAM CRD 要求关联 Operator 管理的SeaweedCR,不适合作为当前 brownfield Helm 部署仅为 IAM 而引入,因此不采用 Operator 接管路线。迁移期间继续把现有
-s3.config视为静态 S3 身份的唯一运行配置。长期目标是使用 SPIRE JWT-SVID 调用 SeaweedFS Web Identity/STS,逐步移除 workload 的长期 AK/SK;Terraform/OpenTofu backend 等兼容性未经验证的调用方暂时保留独立、最小权限且可轮换的静态身份。安全与恢复约束
已否决或后置的方向
设计基于 CRD 的凭据签发与轮换控制器to 后置:评估凭据签发与轮换的声明式管理后置:评估凭据签发与轮换的声明式管理to 设计并验证基于 SPIFFE/SPIRE 的统一 Workload IdentitySPIRE 基础设施已通过 #51 上线并完成首次验收:
spireKustomization 均已收敛到 main revisionbdacc03e[email protected]与[email protected]HelmRelease Ready2/2Ready,成功连接共享 PostgreSQLlocalpv-zfs-cephk8s_psat完成 node attestation2/2Readyissuer与jwks_uri均使用https://spire-oidc.ad.ddupan.top下一步仍是增加显式测试 workload/
ClusterSPIFFEID,暴露 OIDC HTTPS route,并验证 JWT-SVID 登录 OpenBao。SPIRE → OpenBao JWT-SVID 端到端 PoC 已完成:
https://spire-oidc.ad.ddupan.topjwt-spirebackend、spire-pocrole 与最小 policyaud=openbaoJWT-SVID,并以精确 subjectspiffe://ddupan.top/ns/spire-poc/sa/spire-jwt-poc登录成功spire-pocpolicy,TTL 300 秒,无 default policylookup-self成功,随后主动revoke-self,并验证 token 已失效ClusterSPIFFEID已删除,registration entries 已回收No changes由此已验证完整链路:Kubernetes workload → SPIRE Workload API → JWT-SVID → OpenBao JWT auth → 短期最小权限 token。下一步可将 PoC role 替换/扩展为真实 CI 与 AI Agent workload policy。
详细使用文档已通过 #54 合并。新增
platform/spire/RUNBOOK.md,覆盖:no identity issued、JWT login 400、CSI mount、数据库连接排障SPIRE README 与 OpenBao README 均已增加入口,并修正 PoC 状态。