#AI#大模型#DevOps

AI 云工作负载身份联邦:绑定 SPIFFE、OIDC 与 STS 交换边界

推理 worker、评测任务和模型构建器不应共享云密钥。本文分离源凭据、交换请求与输出令牌的受众,并用 profile 和资源策略阻断身份混淆。

本文要点

  • 主题聚焦:AI、大模型、DevOps
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年6月28日·更新于 2026年7月20日

推理 worker、离线评测、模型转换和索引构建常常访问不同的对象存储、队列与 KMS。如果它们共用一个长期云访问密钥,任一容器泄露都会扩大为整个平台权限。AI 平台密钥轮换 解决凭证生命周期,本篇进一步约束“谁能把哪份工作负载声明换成什么云权限”,且不把模型输出、请求参数或租户自报字段当成身份。

冻结身份交换契约

身份源应给每个工作负载稳定而细粒度的主体,例如 spiffe://prod.example/ai/inference/worker,并把生产、预发、构建和人工任务分开。SPIFFE ID 是名称,JWT-SVID、X.509-SVID 与云 OIDC token 是不同凭据类型,不能套用一组 claim 检查;信任材料和 Workload API socket 由平台注入,业务容器不能自选验证 profile。

令牌代理实现 cloud.exchange.v1,明确分开三类受众:subjectTokenAudience 是源 token 签给 STS/代理的受众;requestedAudience 或 RFC 8693 resource 是调用方申请的目标;issuedTokenAudience 是代理最终写入访问令牌、由资源服务验证的受众。代理先选择固定 subjectTokenProfile,再验证源凭据,不能把目标 API 名拿去验证源 token 的 aud。

json
{
  "schema": "cloud.exchange.v1",
  "subjectTokenProfile": "prod-jwt-svid-v2",
  "subjectTokenAudience": "sts.prod.example",
  "requestedAudience": "model-store.prod.example",
  "requestedResource": "models/prod/model-42",
  "issuedTokenAudience": "model-store.prod.example",
  "purpose": "read-model",
  "taskId": "task_01J..."
}

JWT-SVID profile 固定 trust domain/bundle、允许的 SPIFFE subject、算法、subjectTokenAudience、时间声明和最大寿命,再按 SPIFFE JWT-SVID 规则验签。X.509-SVID 没有 JWT 的 iss/aud/sub claim;代理应验证证书链、URI SAN 中的 SPIFFE ID、有效期和 key usage,并用 mTLS 证明私钥持有。云 OIDC profile 则固定 issuer/JWKS、源 audience、subject/attribute mapping、provider resource 和允许兑换的角色。任一 profile 都把请求目标映射为服务端允许集合,请求的 audience、resource 或 scope 只能缩小,不能改写主体或输出受众。

这与 MCP Server 鉴权边界 的用户、服务、工具三类身份分离相同:用户授权可以成为策略输入,但不能让 worker 冒充用户;tenant_id 从已验证会话与任务记录取得,不能从 Prompt 提取。

把四个绑定写进策略

联合身份策略按 profile 匹配信任根、主体、源受众和环境,再独立校验申请目标与输出受众。只校验 OIDC issuer 会让同一签发方下的测试任务进入生产;只匹配 SPIFFE ID 前缀会让相似 workload 越权;混淆三类 audience 会把发给日志系统的 token 交给 STS。claim/证书到云属性的映射需要版本号,未知字段、空主体、通配环境和规范化冲突均默认拒绝。

权限按用途拆成角色:推理只读固定模型 digest,构建器只能写 staging,发布器只能切已批准别名,评测任务不能解密生产对话。下游对象存储与 KMS 仍要校验资源标签、租户或前缀,不能认为“STS 已经认证”就放弃资源层授权。短期 capability lease 面向一次工具动作;这里的云令牌只代表受控工作负载,二者不能相互替代。

缓存键包含 profile、主体、三类 audience、resource、scope、policy version 和 task/session,但这只能防止代理误复用,不能阻止被窃 bearer token 重放。RFC 8693 本身不提供持续绑定或即时撤销。provider 支持时应签发 sender-constrained credential:用 RFC 8705 mTLS 证书绑定,或用 RFC 9449 DPoP 让资源服务验证 cnf、请求 URI/method、nonce 和 proof 防重放;私钥保留在任务 sidecar 或硬件边界内。

若 provider 只发 bearer token,资源侧应校验短期 task/session fence、租户和资源条件;做不到时只能依靠数分钟 TTL、进程/网络隔离与最小资源策略缩短风险窗口。禁用主体只会停止新兑换,已经签发的 bearer 在到期前仍可能发起新请求,不能声称它只允许既有调用结束。长任务必须在到期前重新交换,且不得回退到镜像中的静态密钥。

用负向矩阵验收而非只看成功登录

上线前生成固定测试矩阵:交换源受众与输出受众、把 requested audience 换成预发、JWT-SVID 换到 X.509 profile、OIDC issuer 换成同名测试域、scope 扩大、资源越界都必须失败。复制 bearer、重放 DPoP proof、换 mTLS 客户端证书、令牌过期、签名 key 撤销、STS 超时和旧策略副本也要覆盖,系统不能无限重试或放宽校验。

硬门槛包括:静态云密钥为零;成功交换能关联 profile、workload、三类 audience、task、策略和资源;错误日志不保存 token。具备 sender binding 或资源 fence 时,窃取 token 的跨任务调用为零;纯 bearer 模式则明确测量禁用到 token 到期的剩余暴露窗口,到期后成功调用必须归零。MCP 审计日志设计 只保存不可逆指纹与原因码。

迁移采用双轨观测:先让旧凭证继续服务,新交换链只做 shadow 决策;差异清零后按工作负载稳定分桶启用 STS,并保持旧路径不可被新实例自动选择。回滚只把分桶切回仍受限的旧角色,同时保留交换审计;若发现旧静态密钥已泄露,禁止回滚到它,改为暂停相关任务并重新签发受控身份。编程 Agent 沙箱权限 仍负责文件、命令和网络边界,身份联邦不能替代运行隔离。

工作负载身份的价值不在于“免密”,而在于每次云权限都能回答由谁签发、为哪个 audience、映射成哪个角色、多久失效,并能用负向调用证明其他组合确实进不来。

延伸阅读

Related

相关推荐