自管理的 Kubernetes 集群(kubeadm、k3s、OpenShift 以及本地部署的发行版)通过 projected service account tokens(投影服务账户令牌)为每个 Pod 签发 OIDC "JSON Web Token"(JSON Web 令牌),即 JWT。集群的 API 服务器充当 OIDC 颁发者,每个令牌的 sub 声明遵循 system:serviceaccount:<namespace>:<service-account> 的格式。您可以通过读取集群的发现文档来查找其颁发者 URL:
kubectl get --raw /.well-known/openid-configuration | jq -r .issuer本页介绍的机制(投影服务账户令牌、集群 API 服务器作为 OIDC 颁发者)是 Kubernetes 本身的原生功能,因此它是所有 Kubernetes 发行版的基础。如果您在托管的 Kubernetes 服务上运行,云提供商指南会详细说明在何处找到提供商托管的颁发者 URL:AWS (EKS)、Google Cloud (GKE) 或 Azure (AKS)。如果您的集群运行 SPIRE,则 SPIRE OIDC Discovery Provider 是颁发者,而非集群 API 服务器;请参阅 SPIFFE。对于任何其他发行版或未在此列出的托管提供商,请遵循本指南并使用您的集群报告的颁发者 URL。
--service-account-issuer 标志的 Kubernetes 集群。大多数发行版默认设置此项;kubeadm 集群通常使用 https://kubernetes.default.svc.cluster.local。如果您无法直接访问 API 服务器配置,您的平台团队可以确认该值。inline 模式注册(在配置 Anthropic 中介绍)。将服务账户令牌投影到您的 Pod 中,并设置联合规则所期望的受众(audience)和生命周期。serviceAccountToken 投影会将新的 JWT 写入挂载路径,并在 expirationSeconds 到期之前轮换它。
apiVersion: v1
kind: Pod
metadata:
name: inference-worker
namespace: inference
spec:
serviceAccountName: inference-worker
volumes:
- name: anthropic-token
projected:
sources:
- serviceAccountToken:
audience: https://api.anthropic.com
expirationSeconds: 3600
path: token
containers:
- name: app
image: your-registry/inference-worker:latest
env:
- name: ANTHROPIC_IDENTITY_TOKEN_FILE
value: /var/run/secrets/anthropic.com/token
- name: ANTHROPIC_FEDERATION_RULE_ID
value: fdrl_...
- name: ANTHROPIC_ORGANIZATION_ID
value: 00000000-0000-0000-0000-000000000000
- name: ANTHROPIC_SERVICE_ACCOUNT_ID
value: svac_...
- name: ANTHROPIC_WORKSPACE_ID # required when the rule covers multiple workspaces
value: wrkspc_...
volumeMounts:
- name: anthropic-token
mountPath: /var/run/secrets/anthropic.com
readOnly: true为此 Pod 颁发的令牌包含 sub: "system:serviceaccount:inference:inference-worker" 和 aud: ["https://api.anthropic.com"]。
按照设置演练在 Claude Console 中注册联合颁发者、创建 Anthropic 服务账户并创建联合规则。请使用以下 Kubernetes 特定的值。
联合颁发者: 许多自管理集群使用的颁发者 URL(例如 https://kubernetes.default.svc.cluster.local)无法从公共互联网访问。如果您的集群属于这种情况,请选择 inline JWKS 源并粘贴集群的密钥。从集群内部获取它们:
kubectl get --raw /openid/v1/jwks然后使用返回的 keys 数组的内容(而非外层的 {"keys": [...]} 包装)配置颁发者:
{
"name": "onprem-k8s",
"issuer_url": "https://kubernetes.default.svc.cluster.local",
"jwks_source": "inline",
"jwks_keys": [{ "kty": "RSA", "kid": "...", "n": "...", "e": "AQAB" }]
}在 inline 模式下,issuer_url 仅用于与 JWT 的 iss 声明进行比较;Anthropic 绝不会尝试访问它。如果您的颁发者可公开访问,请改用 "jwks_source": "discovery" 并省略 jwks_keys。
使用 inline 密钥时,当集群轮换其服务账户签名密钥时,您需要负责更新颁发者。轮换很少发生(通常仅在集群升级期间),但在您推送新的 JWKS 之前,令牌交换会因签名错误而失败。
联合规则: 匹配服务账户的 sub 声明以及您在投影令牌上设置的受众。
{
"name": "onprem-inference",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "system:serviceaccount:inference:inference-worker",
"audience": "https://api.anthropic.com"
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}请尽可能根据工作负载的情况进行精确匹配。仅当命名空间中的每个服务账户都应映射到同一个 Anthropic 服务账户时,才将 subject_prefix 放宽为 system:serviceaccount:inference:*(末尾的 * 使其成为前缀匹配)。将规则的 fdrl_... ID 添加到 Pod 的 ANTHROPIC_FEDERATION_RULE_ID 环境变量中。
配置 Kubernetes 中的 Pod 规范将 ANTHROPIC_IDENTITY_TOKEN_FILE 设置为投影挂载路径,同时设置了 ANTHROPIC_FEDERATION_RULE_ID、ANTHROPIC_ORGANIZATION_ID、ANTHROPIC_SERVICE_ACCOUNT_ID 和 ANTHROPIC_WORKSPACE_ID。配置好这些后,SDK 会在每次交换时从磁盘读取令牌,并自动刷新 Anthropic 访问令牌。
import anthropic
# 读取 ANTHROPIC_IDENTITY_TOKEN_FILE、ANTHROPIC_FEDERATION_RULE_ID、
# ANTHROPIC_ORGANIZATION_ID、ANTHROPIC_SERVICE_ACCOUNT_ID 和 ANTHROPIC_WORKSPACE_ID
# (从 Pod 的环境变量中读取)。
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.content[0].text)成功的交换会返回一个以 sk-ant-oat01- 开头的 access_token 以及一个以秒为单位的 expires_in 值。如果遇到 400 invalid_grant,请参阅排查交换失败问题;Kubernetes 端最常见的原因是 JWKS 密钥不匹配(对于 inline 模式,请使用 kubectl get --raw /openid/v1/jwks 重新获取并更新颁发者)。
subject_prefix 为 system:serviceaccount:* 会匹配集群中的每个服务账户,因此任何 Pod 都可以获取联合的 Anthropic 令牌。如果没有 audience 匹配器,该规则还会匹配集群的默认受众令牌,而每个 Pod 都已投影了此类令牌。
将规则的 match 块锁定到适合您用例的最窄范围:
system:serviceaccount:<namespace>:<name> 值,不带末尾的 *。audience,并在 Pod 的 serviceAccountToken 投影上设置相同的值,以便拒绝默认受众令牌。Was this page helpful?