第 14 章 第四部分:工程细节

认证与多云适配

OAuth 2.0 + PKCE 认证流程、令牌源优先级、WIF 零静态密钥、AWS Bedrock(含 Mantle 端点)/ Azure Foundry / Google Cloud's Agent Platform 三大云平台适配

Claude Code OAuth PKCE AWS Bedrock Azure Google Cloud's Agent Platform 多云 WIF

14.1 四种认证方式

Claude Code 支持四种认证方式,覆盖从个人开发者到企业级部署的全部场景:

认证方式适用场景凭证类型
OAuth 2.0 + PKCEClaude.ai 订阅用户Access Token + Refresh Token
API 密钥直接 API 调用 / CI/CDAPI Key
多云认证AWS Bedrock / GCP Vertex / Azure Foundry云平台凭证
Workload Identity Federation企业级零静态密钥部署短效访问令牌

令牌源按以下优先级检查(官方为 7 级):

  1. Cloud provider credentials——设置了 CLAUDE_CODE_USE_BEDROCK / CLAUDE_CODE_USE_VERTEX / CLAUDE_CODE_USE_FOUNDRY 时
  2. ANTHROPIC_AUTH_TOKEN——以 Authorization: Bearer 头发送,用于经 LLM 网关或代理路由的场景
  3. ANTHROPIC_API_KEY——以 X-Api-Key 头发送,用于 Claude Console 密钥直连
  4. apiKeyHelper 脚本输出——用于从 vault 获取短效令牌的动态/轮换凭证
  5. CLAUDE_CODE_OAUTH_TOKEN——claude setup-token 生成的长生命周期 OAuth 令牌,用于无法浏览器登录的 CI 与脚本
  6. Anthropic profile and federation credentials——ant CLI 与 Workload Identity Federation 使用的凭证
  7. Subscription OAuth credentials from /login——Claude Pro / Max / Team / Enterprise 用户的默认方式

⚠️ 原稿两处偏差已更正。其一,原稿标题称「8 级」但只列 7 条,多出的编号是插入在第 1 级之后的非标准 1.5(Claude apps gateway session)。官方的表述是:gateway session 不在这个列表内(sits outside this list)——它是与 Bedrock、Google Cloud’s Agent Platform 同级的 provider selection,且优先级高于它们。存在 gateway session 时,即使设置了 CLAUDE_CODE_USE_BEDROCK 等变量,CLI 仍用 gateway token 认证,上面第 2–6 级的 bearer token / API key / apiKeyHelper / profiles 一概不被使用。把它塞进编号链会让人误以为它只是”插队的一级”。

其二,也是更要紧的一处:原稿完全缺了官方第 6 级。本章 14.1 把 WIF 列为四种认证方式之一,但优先级表没给 WIF 凭证任何位置——读者按原表排查”为什么我的 WIF 没生效”,会误以为 WIF 排在 /login 之后。实际它排在 /login 之前(详见 14.3.1)。

gateway session 小结:它是 provider selection,不是优先级条目;优先级高于所有云提供商变量;存在时上面第 2–6 级均不生效。若托管设置把 forceLoginMethod 设为 "gateway" 或设置了 forceLoginGatewayUrl,且未通过变量选择云提供商,则会话只使用 gateway 登录。

apiKeyHelper TTL 配置:CLAUDE_CODE_API_KEY_HELPER_TTL_MS 环境变量自定义刷新间隔(默认 5 分钟或 HTTP 401 触发),若响应超过 10 秒则显示慢速警告。

第五条通道:证书客户端认证(private_key_jwt)。上表四种方式覆盖的是客户端与 Anthropic(或云)之间的认证。v2.1.284 起还有一条方向不同的通道:Claude apps gateway 与它的 IdP 之间支持 private_key_jwt——面向那些颁发证书凭证而不是 client secret 的 IdP。它不改变客户端的认证方式,改的是网关替你去做 OIDC 时拿什么证明自己。把它列在这里的理由是:排查「网关侧登录失败」时只看客户端凭证是不够的,还有一层网关↔IdP 的认证。

托管登录策略会把优先级链短路,且现在会告诉你短路在哪一级。v2.1.284 起,当 managed settings 通过 forceLoginMethod 或 forceLoginOrgUUID 要求登录、而你又配置了 API key / token / apiKeyHelper 时,启动拒绝信息会点名正在使用的凭证、它的设置位置、以及如何移除。这与 14.3.1 的三源排序表是一体两面:那张表讲「没有任何策略干预时谁优先」,这条讲「有策略时优先链不作数」,并且把定位成本从上节的 ~/.claude/debug/ 日志搬到了启动报错里。

源码引用:认证系统核心参见 src/services/oauth/,多云认证参见 src/utils/auth.ts。

14.2 OAuth 2.0 + PKCE

Claude Code 的 OAuth 实现使用 PKCE(Proof Key for Code Exchange)扩展——这是针对公开客户端(无法安全存储 client secret 的应用)的安全增强。

认证流程:

1. 生成 code_verifier(随机字符串)
2. 计算 code_challenge = SHA256(code_verifier)
3. 构建授权 URL(包含 code_challenge)
4. 打开浏览器让用户登录
5. 本地启动 HTTP 服务器监听回调
6. 收到 authorization_code
7. 用 code + code_verifier 交换 access_token
8. 将 token 存储到 macOS 钥匙链 / 安全存储

终端代码粘贴(WSL2/SSH/容器)。v2.1.126 改进了 OAuth 登录:当运行在 WSL2、SSH 远程会话或容器中时,浏览器回调无法到达 localhost。此时 claude auth login 接受终端中粘贴的 OAuth 授权码,绕过浏览器回调限制。这一改进将 OAuth 登录成功率提升约 30%。

登录过期预警。v2.1.203+ 起,当 /login 凭证距过期 5 天内时,启动时显示警告”Your login expires in 3 days · run /login to renew”(仅对 claude.ai 或 Claude Console 登录生效)。这一机制帮助用户在凭证过期前主动续期,避免会话中断。

Agent SDK 月度独立额度。2026-06-15 起,订阅计划上通过 claude setup-token 生成的 1 年期 OAuth 令牌,以及 claude -p / Agent SDK 的非交互式使用,从独立的月度 Agent SDK 额度中扣除——与交互式使用额度完全分离。这意味着 CI/CD 管道和自动化工作流不再消耗日常交互式配额,对 DevOps 用户是一个关键的计费模型改进。

buildAuthUrl 函数构建授权 URL,支持多种登录方式(标准登录、SSO、Magic Link、Google)和组织级别的认证。

源码引用:OAuth PKCE 实现参见 client.ts,加密工具参见 crypto.ts。

14.3 多云适配

企业用户可能不直接使用 Anthropic API,而是通过云平台的中间层访问 Claude 模型。Claude Code 支持三大云平台:

术语变更(2026-09-11):Google 侧的 Vertex AI 已更名为 Google Cloud’s Agent Platform,官方文档(含 IAM 与各云平台页面)已统一使用新名。本书下文除引用旧环境变量名(CLAUDE_CODE_USE_VERTEX)外,一律改用新名。环境变量名本身未变——CLAUDE_CODE_USE_VERTEX 仍是启用开关,改名只发生在产品命名层。

平台环境变量认证方式特色
AWS BedrockCLAUDE_CODE_USE_BEDROCK=1STS 临时凭证跨区域推理 + Mantle 端点 + Auto Mode(Opus 4.7/4.8,2026-06-16)
Google Cloud’s Agent Platform(原 Vertex AI)CLAUDE_CODE_USE_VERTEX=1ADC 凭证元数据服务器 + Auto Mode(Opus 4.7/4.8,2026-06-16)
Microsoft Foundry(原 Azure Foundry)CLAUDE_CODE_USE_FOUNDRY=1AD Token / API Key1M 上下文 + Auto Mode(Opus 4.7/4.8,2026-06-16)

Vertex 侧的环境变量。除 ADC 之外,官方还列出 ANTHROPIC_VERTEX_BASE_URL 与 ANTHROPIC_VERTEX_PROJECT_ID——前者覆盖 Vertex 端点 URL,后者指定项目 ID。原稿只讲 ADC,未收这两项。

平台切换通过 getAPIProvider() 函数实现,优先级为 Bedrock > Vertex > Foundry > firstParty。

模型标识符映射

各平台使用不同的模型标识符,通过 ModelConfig 类型统一管理:

📌 本表快照于 Claude Code v2.1.285(2026-09-29)。这张表在 2026-09-11 手工修过一次(opus-4-6 → opus-5),18 天后再次漂移(Opus 5.5 于 v2.1.280 / 09-22 成为默认 Opus,Sonnet 5.5 于 v2.1.284 / 09-28 成为 Anthropic API 上的默认 Sonnet)。凡这类枚举表,标快照版本比逐次追更划算——读者看到的数字若是半年前的,至少知道该自己核,而不是照抄。

// 快照于 v2.1.285(2026-09-29)
const CLAUDE_OPUS_5_5_CONFIG = {
  firstParty: 'claude-opus-5-5',
  bedrock:    'us.anthropic.claude-opus-5-5',
  vertex:     'claude-opus-5-5',
  foundry:    'claude-opus-4-8',
};

const CLAUDE_SONNET_5_5_CONFIG = {
  firstParty: 'claude-sonnet-5-5',
  bedrock:    'us.anthropic.claude-sonnet-5-5',
  vertex:     'claude-sonnet-5-5',
  foundry:    'claude-sonnet-5',
};

⚠️ Foundry 那一行为什么没跟着改成 5.5。官方 microsoft-foundry 页面在本表快照时点名的仍是 claude-opus-4-8 与 claude-sonnet-5,没有 5.5。Bedrock 侧官方明确写「Primary model:Opus 5.5,例如 us-* 区域下为 us.anthropic.claude-opus-5-5」,Vertex 侧写「Primary model:claude-opus-5-5」。三个云的代次并不同步,把 Foundry 一并「同步」成 5.5 是我按提案字面执行前回源挡下来的一处——代次落后本身就是事实,不该抹平。

另有一条容易被「默认模型」这个词带偏的:Bedrock 与 Vertex 的 small/fast 模型默认仍是 Sonnet 4.5(如 us.anthropic.claude-sonnet-4-5-20250929-v1:0、claude-sonnet-4-5@20250929),不是 Sonnet 5.5。会话标题生成这类后台任务走的是这一档。

模型 ID 随版本变化,请以 /model 选择器实际列出的为准。

同一批官方示例中还出现的 ID:Bedrock 侧有 us.anthropic.claude-opus-5、eu.anthropic.claude-opus-5、global.anthropic.claude-opus-5、us.anthropic.claude-opus-4-8、us.anthropic.claude-sonnet-4-6、claude-haiku-4-5-20251001-v1;Vertex 侧用 @ 加日期后缀,如 claude-sonnet-4-5@20250929、claude-haiku-4-5@20251001。注意两侧命名规则不同:Bedrock 是点分前缀 + 可选区域,Vertex 是日期后缀。

Bedrock 还支持跨区域推理,通过模型 ID 前缀指定区域:us.anthropic.*(美洲)、eu.anthropic.*(欧洲)、apac.anthropic.*(亚太)、global.anthropic.*(全局路由)。

Bedrock Service Tier。v2.1.122 新增 ANTHROPIC_BEDROCK_SERVICE_TIER 环境变量,支持选择 Bedrock 服务层级:

层级说明适用场景
default标准服务通用场景
flex弹性容量,成本更低非延迟敏感的批处理
priority优先调度,延迟最低生产关键路径

Service Tier 通过 X-Amzn-Bedrock-Service-Tier HTTP Header 发送,为企业用户提供了延迟与成本之间的精细控制。

provider 白名单:allowedProviders

前面所有内容回答的都是「怎么连上某个云」。v2.1.285 新增的 allowedProviders 回答的是另一个问题:这台机器被允许连哪些 provider。

它是 managed setting——写在 policy 文件里,开发者无法从自己的 config 放宽。可枚举的取值共 8 个:Anthropic API、custom endpoint、Bedrock、Mantle、Vertex AI、Foundry、Claude Platform on AWS、Cloud gateway。白名单之外一律拒绝。

这一条把本章的讨论从「认证」推进了一层。此前 14.1 的 7 级令牌源优先级隐含的前提是:只要拿到正确类型的凭证,链路就该通。加上 allowedProviders 之后,前提变成:凭证正确 ≠ 这个 provider 可用。管理员可以在凭证完全合法的情况下,把 Bedrock 从一台机器的可选范围里划掉,此时 CLAUDE_CODE_USE_BEDROCK=1 不是「不生效」,而是被策略拒绝。

它与 14.1 那两条托管登录策略(forceLoginMethod / forceLoginOrgUUID)构成同一组治理手段:前者管「你必须用哪种登录方式」,后者管「你能用哪个 provider」。两者都位于用户配置之上,也都由管理员而非开发者决定。

14.3.0 Bedrock Mantle 端点

Mantle 是一个 Amazon Bedrock 端点,但它以原生 Anthropic API 形状服务 Claude 模型,而非 Bedrock Invoke API 形状。 它复用同一套 AWS 凭证、IAM 权限和 awsAuthRefresh 配置——认证侧没有任何新东西,变的是请求/响应的 API 形状。

维度说明
开启CLAUDE_CODE_USE_MANTLE=1(或 true);/status 的 provider 行显示 Amazon Bedrock (Mantle)
模型 ID前缀 anthropic.、无版本后缀,如 anthropic.claude-sonnet-5、anthropic.claude-haiku-4-5
可用模型取决于组织被授予的权限,额外 ID 见 AWS 的 onboarding 材料
环境变量CLAUDE_CODE_USE_MANTLE、ANTHROPIC_BEDROCK_MANTLE_BASE_URL(覆盖默认端点 URL)

可与 Invoke API 并行。Mantle 上的可用模型未必覆盖你当前在用的全部模型。把 CLAUDE_CODE_USE_BEDROCK 与 CLAUDE_CODE_USE_MANTLE 一并设置,即可在同一会话里调用两个端点:符合 Mantle 格式的 ID 走 Mantle,其余走 Invoke API,此时 /status 显示 Amazon Bedrock + Amazon Bedrock (Mantle)。

想在 /model 选择器里露出 Mantle 模型,需把其 ID 列进 availableModels。⚠️ 这里有个反直觉的坑:列出 anthropic.claude-haiku-4-5 会把裸 haiku 别名从选择器中移除——两个条目指向同一模型族,合并时只保留更具体的那个。要保留可选项,须一并列出想留的版本前缀或完整 ID。

从本书视角看,Mantle 的意义在于:它是”多云认证层”向”统一 API 形状”收敛的信号。 云厂商的差异被压缩到端点选择与 ID 命名规则,认证侧仍是同一条 AWS 凭证链。这与 14.5 教训二”多云不再是劣化版”的论点方向一致,只是收敛发生在 API 形状而非功能清单上。

服务端视角:gateway 侧的 Mantle 与两项 Bedrock upstream 配置。上面讲的是客户端直连 Mantle。若部署形态是 Claude apps gateway 居中,同一件事落在 upstream 配置上:

版本项内容
v2.1.283(09-25)mantle upstream providergateway 新增 Mantle 端点作为 Bedrock 的 upstream 选项
v2.1.281(09-23)assume_rolegateway 经 STS 承担一个 IAM 角色再调 Bedrock,可跨 AWS 账号,可选每位开发者一个会话
v2.1.281(09-23)guardrail: {id, version}对该 upstream 的每个请求施加 Amazon Bedrock guardrail;要求所有 Bedrock upstream 要么都设要么都不设

assume_role 与 14.3.1 的 WIF 是同源主题的不同落点:WIF 让客户端凭身份换短效令牌,assume_role 让网关凭身份承担角色——思路都是「用身份换凭证,而不是存凭证」,差别只在执行者是客户端还是网关。「每位开发者一个会话」这个可选项尤其值得注意:它把角色承担粒度从「一个网关一个身份」细化到「一个人一个会话」,代价是 STS 调用次数与可观测性复杂度。

guardrail 的「要么都设要么都不设」是一条容易踩的硬约束:它不是逐 upstream 的开关,混设会被拒。

Bedrock 上的 1M 上下文

Claude Sonnet 5、Opus 4.6 及之后、Sonnet 4.6 在 Amazon Bedrock 上支持 1M token 上下文窗口。其中有一条容易踩空的细节:Sonnet 5 在 Invoke API 与 Mantle 端点上始终以 1M 运行,没有 [1m] 变体可选;其他模型则在 Invoke API 上选择 1M 变体时由 Claude Code 自动启用扩展上下文窗口。

换句话说,“选一个 [1m] 后缀的模型 ID”这个操作对 Sonnet 5 不成立——它没有可选项。读者若照其他模型的习惯去找 claude-sonnet-5[1m],会找不到。

自建网关这条路径此前完全没写。v2.1.285 起,走自定义 ANTHROPIC_BASE_URL 的会话同样会用上模型自带的 1M 上下文窗口(适用 Opus 4.7+、Sonnet 5+、Fable)。官方给的兜底动作是:若你的网关在 200K 处截断,执行 /autocompact 200k。

这一条的位置比看上去重要。上面讲 Bedrock 的 1M 覆盖的是「云厂商托管」形态,而企业里更常见的出口是自建网关 + WIF 统一出网——即 14.3.1 那条链路。此前这类部署会安静地停在 200K,且没有任何报错提示窗口被截断;现在窗口与直连对齐,剩下的变量只有网关自己肯不肯放那么长。

源码引用:多云认证参见 bedrock.ts,模型配置参见 configs.ts,API 提供商选择参见 providers.ts。

14.3.1 Workload Identity Federation

2026 年 5 月,Anthropic 为 Claude API 引入了 Workload Identity Federation(WIF)——这是认证架构的根本性变革,从”持有静态凭证”转向”证明身份获取临时令牌”。

三要素架构

要素标识符前缀作用
Service Accountsvac_定义身份主体(“谁在请求”)
Federation Issuerfdis_定义信任的 IdP(“谁签发的身份”)
Federation Rulefdrl_定义映射规则(“IdP 身份如何映射到 Anthropic 身份”)

令牌交换流程

WIF 基于 RFC 7523 jwt-bearer grant:

1. 工作负载从 IdP 获取 OIDC JWT
   (来源:AWS IAM / GCP ADC / Azure IMDS /
    GitHub Actions / Kubernetes / SPIFFE/SPIRE)

2. 用 OIDC JWT 换取 Anthropic 短效访问令牌
   (sk-ant-oat01-...)

3. SDK 自动处理令牌交换和刷新

双层刷新策略

刷新层触发条件目的
Advisory令牌过期前 120 秒提前刷新,避免请求中断
Mandatory令牌过期前 30 秒强制刷新,确保不使用过期令牌

令牌有效期约束:Anthropic 令牌有效期 = min(rule.ttl, 2 × 剩余 IdP JWT 有效期)。这保证了 Anthropic 令牌永远不会长于上游身份的有效期——安全性的核心保证。

支持的 IdP

AWS IAM Identity Center、GCP Application Default Credentials、Azure Instance Metadata Service、GitHub Actions OIDC、Kubernetes Service Account Token、SPIFFE/SPIRE SVID。

JWKS 源配置模式。Anthropic 官方 WIF 文档明确了三种 JWKS(JSON Web Key Set)源配置方式:

模式配置方式适用场景
discovery(默认)通过 /.well-known/openid-configuration 自动发现 JWKS 端点公网可达的标准 IdP(AWS、GCP、Azure)
explicit_url直接指定 JWKS 端点 URLIdP 支持 OIDC 但发现端点不可用
inline上传密钥集(JSON Web Key Set 内联)私有 Kubernetes 集群等不可从公网访问的签发者

URL 约束:所有 JWKS 端点必须使用 HTTPS 协议、端口 443、公网 DNS 解析的域名。这对于私有 Kubernetes 集群部署场景(需使用 inline 模式绕过公网访问限制)尤其重要。

GCP X.509 证书型 WIF:v2.1.121+ 扩展了 GCP 的 WIF 支持——除了默认的 ADC metadata server 方式,还支持 X.509 证书型 Workload Identity Federation。通过将 GOOGLE_APPLICATION_CREDENTIALS 设为凭证配置文件路径即可启用,为 GCP 上的 WIF 提供了更灵活的认证路径。

WIF/profile 凭证在优先级链中的位置

本节前面的技术细节(三要素、RFC 7523、双层刷新、JWKS 三模式)回答的是”WIF 怎么工作”,但没有回答”WIF 凭证在优先级链里站哪一位”——而这恰恰是排查问题时最先需要的。

答案是:profile 与 federation 凭证占 14.1 优先级表的第 6 级,即排在 /login 订阅凭证之前。Claude Code 按下表顺序检查三个来源,命中第一个已设置的即停止:

来源由什么设置相对 /login 的排位
Named profileANTHROPIC_PROFILE之上——不论该 profile 是哪种 auth mode
Federation variablesANTHROPIC_FEDERATION_RULE_ID 与 ANTHROPIC_ORGANIZATION_ID 两个都设置之上
Active profile配置目录中的 active_config 文件,或名为 default 的 profileauth mode 为 oidc_federation 时之上;为 user_oauth 时排在可用的 /login 凭证之下

最后一条的 user_oauth 例外不是随意定的。官方给出的设计意图是:防止一个残留的 ant auth login profile 把你已用 /login 登录的账号的请求挪走。排序规则在这里保护的是”用户显式做过的事”(/login)优先于”某次 CLI 操作留下的痕迹”。

边界条件:Claude Code 在 bare mode、Claude Desktop、cloud sessions 中不读取 profile 或 federation 变量,这些会话的 /status 不显示 Profile 行。

怎么确认选中了哪个来源:运行 /status,有 Profile 行时它会取代 Login method 行;profile 生效时 Organization 与 Email 行显示该 profile 的账号。带 --debug 启动还会在 ~/.claude/debug/<session-id>.txt 写入 Using Anthropic profile auth 行;若因存在可用的 /login 凭证而跳过了 user_oauth active profile,调试日志会写明改用 claude.ai 登录。

14.4 凭证缓存、模型可用性与错误处理

本节原有内容只覆盖凭证这一条链路。v2.1.281–2.1.285 的几处改动指向了平行的另一条:模型可用性。它们是两件不同的事,各有各的 TTL,各有各的失效模式。

各平台的凭证都有缓存机制,AWS STS 凭证缓存 TTL 为 1 小时,GCP ADC 凭证也是 1 小时。缓存通过 memoizeWithTTLAsync 实现。

认证错误的统一处理:

平台错误检测恢复策略
BedrockCredentialsProviderError / 403清除缓存 → 重新认证
VertexGoogle 认证库错误 / 401清除缓存 → ADC 刷新
FoundryAzure AD 错误重新获取 Token

自动凭证刷新。Claude Code 新增 awsAuthRefresh 和 gcpAuthRefresh 设置——当检测到凭证过期时,自动运行刷新命令(如 aws sso login 或 gcloud auth application-default login),并流式输出以便用户完成浏览器认证流程。awsCredentialExport 设置则支持 aws sts assume-role 场景的凭证导出。这将”清除缓存→重新认证”的手动策略升级为”自动检测过期→自动刷新→无感恢复”的自动化流程。

✅ 「待验证」标注已摘除(2026-09-11):awsAuthRefresh、awsCredentialExport、gcpAuthRefresh 三项现已在官方 settings-reference 中各有独立条目,属官方确认。原稿自标的「来自第三方文档站点,非官方」⚠️ 已删除。

补充一项当时未记的区分:awsAuthRefresh 用于刷新流程写入 .aws 的场景,awsCredentialExport 用于刷新流程打印凭证的场景(如 aws sts assume-role)——两者不是替代关系,而是对应不同的刷新命令输出方式。

模型可用性:第二条链路

凭证有效 ≠ 模型可用。 下面三条都发生在「认证已经成功之后」,属于 v2.1.285:

机制行为
降级Bedrock / Vertex AI 会话在管理员移除默认模型访问时,改为切到同层级的旧可用模型,不再直接失败;会话标题与摘要随之回退
可用性缓存Bedrock / Vertex 的启动模型检查,账户不可用的模型记住最长 1 天,不再每次启动都重查
签名修正Bedrock / Mantle / Claude Platform on AWS 请求打到非默认端口的 base URL 时,SigV4 签名的 Host 头现在包含端口

同版本还把 Bedrock、Vertex、Mantle 的启动模型检查改为与其它请求一样带上 User-Agent / x-app / session ID 头,并标识自己为 Claude Code。

⚠️ 提案原文把改用同类请求头的三家写成了「Bedrock / Mantle / Claude Platform on AWS」,其中第三家应为 Vertex。官方 changelog v2.1.285 的两条是分开的:一条是 SigV4 Host 头含端口(Bedrock / Mantle / Claude Platform on AWS),另一条是启动模型检查带头(Bedrock / Vertex / Mantle)。按提案合并写会把两个不同的集合混成一个。

降级那条值得单独看一眼。「管理员撤掉默认模型」在组织里是常规操作——换代次、控成本、收权限都可能触发。旧行为是直接失败,用户看到的是认证类报错,排查方向被误导到凭证上;新行为是静默换模型,代价是会话标题与摘要也在同一时刻回退,用户看到的是「自己在用的模型变了」而没有提示。可用性缓存最长 1 天进一步拉长了感知延迟:上午刚被撤掉的模型访问权,下午恢复了,但若 Claude Code 已缓存「不可用」,要等缓存过期才重新检查。

凭证机制的两条负向边界

上面写了「有这个机制」,官方随后补的是「这个机制怎么漏」:

  • 进程残留(v2.1.281):gcpAuthRefresh / awsAuthRefresh 的登录进程在 Claude Code 退出或刷新超时后仍在运行,Windows 上还占着 localhost 回调端口。占着回调端口意味着下一次登录可能起不来——这是「自动化刷新」引入的新失效模式,手动刷新时不存在。
  • 钥匙串锁定(v2.1.281):macOS 上写入凭证时若登录钥匙串处于锁定状态(例如刚从睡眠唤醒),会丢掉已存的 MCP OAuth token 或删掉钥匙串条目。这把「凭证存储」的可靠性挂在了操作系统的锁状态上。
  • 多会话竞态(v2.1.285):两个会话争抢恢复同一个崩溃进程留下的 login refresh lock 时,会出现罕见认证失败。本章 14.1 的优先级链与 14.4 的刷新流程都隐含单会话假设,这条是该假设的边界。

三条合起来指向同一件事:自动刷新把凭证管理从「用户动作」变成「后台进程」,于是进程生命周期、OS 锁状态、跨会话并发这三类原本与认证无关的问题,全都变成了认证问题。

14.5 多云适配给 Agent 产品的教训

OAuth PKCE 和多云认证的技术细节在文档中都能找到,但 Claude Code 的实现揭示了几个不那么显而易见的教训:

教训一:认证是用户流失的第一道坎

如果用户需要手动配置 API Key、手动刷新 Token、手动切换云平台——他们会在第一步就放弃。Claude Code 的多级令牌源自动探测(云平台凭证 → Gateway Session → 环境变量 → OAuth 令牌)说明 Anthropic 在认证体验上投入了大量工程:用户不应该”配置”认证,认证应该”自动发生”。

教训二:多云不是三个 if-else

Bedrock、Vertex、Foundry 三个平台的差异不只是 endpoint 不同——它们的认证方式、模型标识符、区域策略、错误码格式都不同。ModelConfig 类型用统一的数据结构屏蔽了这些差异,上层代码完全不需要知道底层用的是哪个平台。

但更关键的是优先级策略(Bedrock > Vertex > Foundry > firstParty)——当用户同时设置了多个平台环境变量时,系统需要有确定性的选择逻辑而不是报错。

云平台功能对齐:2026-06-16,Auto Mode(后台安全检查替代逐次权限确认)从 Anthropic 直连扩展到 Bedrock、Vertex、Foundry 三大云平台(仅限 Opus 4.7/4.8)。2026 年 7 月进一步完善:Google Cloud(07-10)和 Azure(07-11)相继上线 Auto Mode GA——标志着 Auto Mode 在核心云平台达到生产就绪状态。多云部署不再是”劣化版”,而是功能几乎对等的选择。

⚠️ 启用方式已过时(与第 13 章 13.6.3 同步更正)。原稿写「启用方式:CLAUDE_CODE_ENABLE_AUTO_MODE=1 + Shift+Tab 切换到 auto mode」。该 opt-in 在三大云平台上已被取消:自 v2.1.207(2026-07-11) 起,Bedrock、Google Cloud’s Agent Platform、Foundry 上的 Auto mode 不再需要 CLAUDE_CODE_ENABLE_AUTO_MODE,管理员改用 settings 中的 disableAutoMode(或 permissions.disableAutoMode)关闭。这与上文的「Google Cloud 07-10 / Azure 07-11 上线 Auto Mode GA」实为同一批变更,可合并理解:GA 与取消 opt-in 是同一次发布动作的两面。

旧写法在云平台上的实际后果是:读者设了环境变量却发现没变化(变量已无作用),或反过来以为必须设才能用(其实早已默认可用)。

Gateway 消费统管:v2.1.225(2026-08-07)新增 Gateway 控制台消费限额可视化——用户可直接在 Gateway 控制台查看消费限额和用量,覆盖 AWS + GCP + Azure 多云消费,为多云场景的统一计量计费提供 UI 层基础。同版本还引入跨机器会话消息传递功能,对 OAuth Token 同步和会话状态迁移提出新的技术需求。

auto mode 的分类器改走服务端。v2.1.278(09-19)起,Claude API 与企业用户,以及 Bedrock / Vertex / Foundry / 网关上的 auto mode 默认改用服务端分类器,不再收分类器开销;在这些平台上可用 CLAUDE_CODE_AUTO_MODE_SERVER=0 退出,回退到计费分类器时会告警,/status 里多一行 Auto mode server 显示本次会话跑在哪一侧。这是「多云不是三个 if-else」的又一实例:同一个功能在 Anthropic 直连与三大云上有不同的计费路径,退出开关也只在云侧存在。

教训三:凭证 TTL 与模型可用性 TTL 是两条独立的 TTL

AWS STS 凭证缓存 1 小时、MCP 认证失败缓存 15 分钟——这些 TTL 不是随便选的。太短会导致频繁认证请求(影响体验和被限流),太长会在凭证被撤销后仍然使用过期凭证(安全风险)。缓存 TTL 是安全策略的一部分,不是性能参数。

v2.1.285 之后还要补一句:模型可用性的缓存是另一条 TTL,最长 1 天(见 14.4)。两条 TTL 的语义并不相同——凭证 TTL 到期是「不确定还能不能用」,故必须重取;模型可用性 TTL 到期是「上次查到不能用」,故到期前会继续使用旧结论。管理员上午撤权限、下午恢复,用户在缓存期内仍然被降级到旧模型,且不会收到任何提示。把两类缓存放在同一个 TTL 框架下讨论,会漏掉这条不对称。

教训四:从凭证到身份

Workload Identity Federation 代表了一种范式转变——从”持有凭证即拥有权限”到”证明身份即获得临时凭证”。这对 Agent 产品意味着:Agent 不应存储长期 API Key,而应通过身份证明获取短期令牌。

WIF 的令牌有效期约束设计(不超过 2× 上游身份有效期)提供了一个安全最佳实践:即使在 Agent 的长运行会话中,任何时刻的有效凭证都有有限的生命周期。这与传统 API Key 的”永久有效直到手动撤销”形成了鲜明对比——静态 API Key 的时代正在结束。

教训五:认证不等于安全

2026 年 6 月,Claude Code 引入了文件系统级安全增强:在写入可执行配置文件(shell 启动文件如 .zshenv、git config、构建工具配置如 .npmrc/.bazelrc)前会主动提示——即使在 acceptEdits 模式下也不跳过。这意味着即使凭证验证通过,文件和命令安全性仍需独立保护。这是”最小权限”原则在文件系统层的延伸:凭证验证不等于文件安全,令牌有效不代表操作安全。

v2.1.281–2.1.285 的改动给这条教训又加了两层。

第一层,从凭证层推进到 provider 层。 14.1 的 7 级优先级回答的是「用哪个凭证」,allowedProviders(v2.1.285)回答的是「这台机器能用哪个 provider」。拿到合法凭证并不等于某个云可用——认证通过只是这条链上的第一关。

第二层,认证配置本身可以是攻击面。 v2.1.284 修复了 ANTHROPIC_FOUNDRY_RESOURCE 未经校验就被插值进 Foundry 端点主机名的问题;现在非纯资源名的值一律拒绝。这一条的性质与前面的「写可执行配置文件前提示」完全不同:那里防的是模型改你的配置,这里防的是配置值变成主机名的一部分。一个用于认证的普通环境变量,因为它参与构造了请求目标,就成了注入点——而且这类注入面在凭据体系里最难被意识到,因为它看起来只是「填了个资源名」。

14.6 设计启示

  1. 多云适配是企业级产品的必要条件。大企业不会为了用 Claude Code 而改变云战略。

  2. 统一的 API 抽象屏蔽底层差异。上层代码不需要知道底层用的是 Bedrock 还是 Vertex——ModelConfig 做了翻译。

  3. 凭证管理比看起来复杂得多。缓存、刷新、错误恢复、多平台——一个认证模块可能比想象中要重好几倍。