posts/claude-identity-backed-api-keys.md
Claude 新 API key 绑上身份,也不等于安全
一个 API key 最尴尬的时刻,不是它泄露了。
是告警响了以后,整个群里没人知道它到底是谁的。
你去翻 CI secret,名字叫 ANTHROPIC_API_KEY。再去看账单,只能看到某个 workspace 在烧钱。创建它的人半年前换了项目,服务还在跑,key 也还活着。大家围着一串 sk-ant-... 猜来猜去,像在机房里捡到一把没有标签的钥匙。
好家伙,钥匙能开门,门禁却不知道谁进来了。
Claude Platform 在 8 月 27 日的版本说明里补了一块很小、但很工程的拼图。Claude Console 现在能创建 personal key 和 service account key。前者代表一个真实用户,后者代表一个非人类服务身份。关联身份离开组织,key 会跟着失效。旧的 workspace key 还可以用,不过官方已经把它放进 legacy 一栏。
这不是模型升级,没有跑分,也没有一百万上下文。放在一串 release notes 里,甚至很容易被划过去。
但如果你在给 Agent 搭生产链路,这条更新比很多模型参数更值得看。因为它把 API key 从一串「谁拿到谁能用」的字符串,往「谁正在调用、拥有什么权限、何时应该失效」推进了一步。
只推进了一步。
key 终于有主人了
先把三类 key 摊开,不然后面很容易聊串。
personal key 代表一个真实用户。这个用户能访问哪些 workspace,key 就能在创建时被限定到其中一个,或者覆盖其有权使用 API 的多个 workspace。用户离开组织后,个人 key 会被归档。以后即使把人重新邀请回来,旧 key 也不会复活。
它最适合本地开发、个人原型和自己的脚本。你在终端里试一个 prompt,跑一段短任务,用 personal key 很自然。调用归在自己名下,出问题也知道该找谁。
但把 personal key 塞进团队共享的 GitHub Actions,就开始变味了。所有调用都像是某个员工亲手发起的,那个人一离职,部署一起趴窝。让一个人的身份长期扛着一条公共流水线,审计看着清楚,责任其实还是糊的。
service account key 代表一个非人类身份。服务账号没有邮箱、密码和 Console 登录,它在组织里有自己的名字,再通过成员关系进入需要访问的 workspace。一个定时摘要任务可以叫 daily-brief-agent,一个代码审查服务可以叫 pr-reviewer-prod。谁在花 token,终于不用靠 key 名字猜。
官方文档里有一句很关键。workspace key 自己就是 credential,而 service account 是一个可以拥有 credentials 的身份。
这两者差得挺远。
前一种管理的是字符串,后一种管理的是调用者。字符串可以轮换,调用者还能被授权、撤权、归档、审计。一个服务账号可以拥有新旧两把 key 完成无停机轮换,却仍保持同一个工作负载身份。厉害了,认证系统终于开始像认证系统,不再像共享剪贴板。
剩下的 workspace key 最省事,也最容易变成老 bug。它不属于任何人,只属于创建它的 workspace。创建者离开组织,key 不受影响。只要它没有过期、被禁用、删除,workspace 也还在,它就会继续工作。
稳定吗?很稳定。
稳定到没人负责也能继续跑。
所以 Claude 没有立刻砍掉 workspace key,已有系统不会突然断电,但官方路线已经很明确,新集成优先身份型 key 或 Workload Identity Federation,简称 WIF。

身份绑定不是最小权限
到这里很容易产生一个错觉。key 有主人了,离职会失效,安全问题解决。
没那么快。
身份绑定回答的是「谁在调用」,没有自动回答「它为什么能访问这么多东西」。如果一个 service account 被加进五个 workspace,它的 all-workspaces key 就可能在五个空间里活动。如果一个 personal key 没限定 workspace,它可以继承那个人已有的跨工作区权限,调用管理端点时甚至需要更谨慎。
Claude 的认证文档把边界写得很具体。单 workspace key 只在目标空间工作,请求也不用再带 anthropic-workspace-id。没有限定 workspace 的身份型 key,每次请求都要明确传目标空间。普通业务服务没必要顺手拿到跨 workspace 和 Admin API 能力,单空间应该是默认答案。
可以把它想成办公楼门禁。员工卡上有名字,确实比前台抽屉里那张万能卡强。但如果员工卡默认能开财务室、机房和仓库,有名字也救不了权限过宽。
这里还有另一层,personal key 和 service account key 仍然是静态 secret。
它们还是一串长期存在的字符,还是会进入 secret manager、CI 配置、容器环境变量和开发机。它们会过期,会被复制,会在错误日志里露出来,也可能被一份旧部署配置悄悄留上几个月。
Claude Console 现在允许创建 key 时设置 3 小时、1 天、7 天、30 天、自定义时长或永不过期,组织还能限制最大有效期。这个能力很实用,但过期时间只能在创建时决定,后面不能改。迁移仍要经历新旧凭据并存、真实请求验证、旧 key 撤销这条链。
如果团队只是把 workspace-prod-key 换名为 service-account-prod-key,然后把新字符串原封不动塞回同一个长期 CI secret,审计归属变好了,secret 分发问题还在原地。
棒棒的,标签升级了,炸弹没拆。
生产环境真正该看的是 WIF
对已经跑在云平台、GitHub Actions 或 Kubernetes 里的工作负载,Claude 官方给的更完整答案不是另一种静态 key,而是 Workload Identity Federation。
WIF 这名字听着挺黑话,用人话讲,它让现有平台替工作负载证明身份。
GitHub Actions 能拿到 GitHub 签发的 OIDC 令牌,Kubernetes 能拿到投射进 Pod 的 service account token,AWS、Google Cloud 和 Microsoft Entra ID 也有自己的工作负载身份。Claude 验证这些签名和规则后,再发一个绑定到 service account 的短期访问令牌。
链路大概是这样。
工作负载身份
→ 上游平台签发短期 JWT
→ Claude 校验 issuer、claims 与规则
→ 换取绑定 service account 的短期 token
→ SDK 在过期前刷新
真正值钱的地方,是生产环境里不再需要一把长期 sk-ant-...。没有静态 key 要塞进 CI,没有永不过期的字符串等着轮换,也少了一类误提交到仓库和日志里的事故。
短期令牌当然不是魔法。上游身份提供方被配坏,WIF 也会跟着坏。规则里的 subject、claims 和 OAuth scope 设得太宽,短期 token 依然能干太多事。官方文档也明确提醒,联邦认证强不强,取决于签发 JWT 的上游身份系统,仍要配合条件访问、工作负载绑定和审计日志。
不过两类风险的形状已经不同。
静态 key 泄露后,攻击窗口可能持续到人工发现并撤销。WIF token 通常几分钟到一小时就过期,下一次换取还要重新满足身份规则。风险没有消失,爆炸半径和存活时间都被压小了。

对生产 Agent 来说,这个变化尤其重要。Agent 不只发一轮聊天请求,它可能定时醒来、访问文件、调用工具、重试失败步骤,再把结果写回外部系统。一把泄露的长期 key 叠上长时间运行和高权限工具,才是最让人睡不着的组合。
所以我的判断挺直接。
personal key 是给人的,service account key 是给暂时还离不开静态 secret 的共享工作负载,WIF 才是已有平台身份的生产任务该去的方向。三者不是高级、中级、低级套餐,而是三种不同运行环境的答案。
迁移别从换 key 开始
真要动手,不建议一上来把所有 workspace key 批量删除。那种操作很有仪式感,也很容易让半夜告警突然拥有姓名。
先建一张凭据台账。每把 key 至少要有用途、负责人、工作负载身份、存放位置、最近使用时间、workspace 范围、有效期和撤销方式。Claude 的 List API Keys 与 List Workspaces 能帮管理员把平台侧资产捞出来,代码仓库、CI 和 secret manager 里的引用还得自己盘。
台账可以长成这样。
workload: pr-reviewer
owner: platform-team
environment: production
identity: svc-pr-reviewer
workspace: code-review-prod
credential: wif
token_ttl_seconds: 600
break_glass_key_expiry: 24h
这里的 break_glass 是应急凭据,不是让大家继续依赖静态 key。它应该短期、单 workspace、受审批、默认禁用,并且每次启用都有告警。WIF 配置错误时可以救火,不能长期坐在驾驶位。
个人实验脚本迁到 personal key,设置短有效期。团队共享脚本给它独立的 service account,别再借某个员工的身份跑。GitHub Actions、Kubernetes 和云服务继续往 WIF 迁,让平台身份接管长期 secret。
每次迁移都做一遍真实验收。请求能不能成功只是第一格,还要看用量是否归到正确身份,workspace 是否准确,旧 key 撤销后有没有隐藏任务继续报错,告警能否区分 key 过期、账号被移除、workspace 无权和 token exchange 失败。
尤其别漏掉 credential precedence。WIF 文档提醒,环境里的 ANTHROPIC_API_KEY 优先级高于联邦身份。你以为服务已经切到 WIF,容器里一枚旧环境变量可能还在默默接管认证。迁移验证不能只看请求成功,要确认到底是哪种凭据赢了。
这才是这次小更新真正有意思的地方。
Claude 没有替团队完成 secret 管理,它只是终于给 key 安上了身份。接下来还得把权限范围、有效期、轮换、联邦认证和失效告警接起来。少一环,那串字符串依旧会在某个角落活得比项目还久。
一把钥匙有了名字,是好事。
但生产系统需要的,从来不只是名字。