Clusters Kubernetes autogerenciados (kubeadm, k3s, OpenShift e distribuições on-premises) assinam JSON Web Tokens (JWTs) OIDC para cada pod por meio de tokens de service account projetados. O API server do cluster atua como o emissor OIDC, e a claim sub de cada token segue a forma system:serviceaccount:<namespace>:<service-account>. Você pode encontrar a URL do emissor do seu cluster lendo seu documento de descoberta:
kubectl get --raw /.well-known/openid-configuration | jq -r .issuerO mecanismo desta página (token de service account projetado, API server do cluster como o emissor OIDC) é nativo do próprio Kubernetes, portanto está na base de toda distribuição Kubernetes. Se você executa em um serviço Kubernetes gerenciado, os guias dos provedores de nuvem mostram onde encontrar a URL do emissor gerenciado pelo provedor: AWS (EKS), Google Cloud (GKE) ou Azure (AKS). Se o seu cluster executa SPIRE, o SPIRE OIDC Discovery Provider é o emissor em vez do API server do cluster; consulte SPIFFE. Para qualquer outra distribuição ou um provedor gerenciado não listado lá, siga este guia e use a URL do emissor que seu cluster reporta.
--service-account-issuer configurada no API server. A maioria das distribuições define isso por padrão; clusters kubeadm normalmente usam https://kubernetes.default.svc.cluster.local. Sua equipe de plataforma pode confirmar o valor se você não tiver acesso direto à configuração do API server.inline (abordado em Configure a Anthropic).Projete um token de service account no seu pod com a audiência e o tempo de vida que sua regra de federação espera. A projeção serviceAccountToken grava um JWT novo no caminho de montagem e o rotaciona antes que expirationSeconds expire.
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: trueO token emitido para este pod carrega sub: "system:serviceaccount:inference:inference-worker" e aud: ["https://api.anthropic.com"].
No Claude Console, abra Settings → Workload identity, clique em Connect workload e selecione o bloco Kubernetes. O assistente orienta você no registro do emissor, na criação de um service account e na criação de uma regra de federação.
O assistente cria esses recursos para você. Use os seguintes valores, seja inserindo-os no assistente ou enviando-os para a Admin API:
Emissor de federação: Muitos clusters autogerenciados usam uma URL de emissor como https://kubernetes.default.svc.cluster.local que não é acessível a partir da internet pública. Se isso se aplica ao seu cluster, escolha a fonte JWKS inline e cole as chaves do cluster. Busque-as de dentro do cluster:
kubectl get --raw /openid/v1/jwksEm seguida, configure o emissor com o conteúdo do array keys retornado (não o invólucro {"keys": [...]} ao redor):
{
"name": "onprem-k8s",
"issuer_url": "https://kubernetes.default.svc.cluster.local",
"jwks": {
"type": "inline",
"keys": [{ "kty": "RSA", "kid": "...", "n": "...", "e": "AQAB" }]
}
}No modo inline, a issuer_url é apenas comparada com a claim iss do JWT; a Anthropic nunca tenta acessá-la. Se o seu emissor for acessível publicamente, use "jwks": {"type": "discovery"} em vez disso.
Com chaves inline, você é responsável por atualizar o emissor quando o cluster rotacionar sua chave de assinatura de service account. A rotação é rara (normalmente apenas durante upgrades do cluster), mas as trocas de token falham com um erro de assinatura até que você envie o novo JWKS.
Regra de federação: Faça a correspondência com a claim sub do service account e a audiência que você definiu no token projetado.
{
"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
}Seja tão específico quanto a carga de trabalho permitir. Afrouxe subject_prefix para system:serviceaccount:inference:* (o * no final o torna uma correspondência de prefixo) apenas se todo service account no namespace deve ser mapeado para o mesmo service account da Anthropic. Adicione o ID fdrl_... da regra à variável de ambiente ANTHROPIC_FEDERATION_RULE_ID do seu pod.
A especificação do pod em Configure o Kubernetes define ANTHROPIC_IDENTITY_TOKEN_FILE para o caminho de montagem projetado, junto com ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID e ANTHROPIC_WORKSPACE_ID. Com isso configurado, o SDK lê o token do disco a cada troca e atualiza o token de acesso da Anthropic automaticamente.
import anthropic
# Lê ANTHROPIC_IDENTITY_TOKEN_FILE, ANTHROPIC_FEDERATION_RULE_ID,
# ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID e ANTHROPIC_WORKSPACE_ID
# do ambiente do pod.
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(next(block.text for block in message.content if block.type == "text"))Uma troca bem-sucedida retorna um access_token começando com sk-ant-oat01- e um valor expires_in em segundos. Em caso de 400 invalid_grant, consulte Solucionar problemas de uma troca com falha; a causa mais comum do lado do Kubernetes é uma incompatibilidade de chave JWKS (para o modo inline, busque novamente com kubectl get --raw /openid/v1/jwks e atualize o emissor).
Um subject_prefix de system:serviceaccount:* corresponde a todo service account no cluster, de modo que qualquer pod pode obter um token federado da Anthropic. Sem um correspondente de audience, a regra também corresponde aos tokens de audiência padrão do cluster, que todo pod já tem projetados.
Restrinja o bloco match da regra ao escopo mais estreito que atenda ao seu caso de uso:
system:serviceaccount:<namespace>:<name> sem * no final.audience na regra e defina o mesmo valor na projeção serviceAccountToken do pod para que tokens de audiência padrão sejam rejeitados.Was this page helpful?