Workloads AWS podem se autenticar na Claude API sem chaves de API estáticas trocando um token de identidade OIDC assinado pela AWS. O caminho recomendado chama a API GetWebIdentityToken do AWS STS, que funciona em qualquer lugar onde o workload tenha credenciais AWS: Lambda, EC2, ECS e EKS. Workloads EKS podem, alternativamente, usar o caminho de token projetado do Kubernetes, que tem menos etapas de configuração, mas só funciona dentro de um pod.
Este guia mostra ambos os caminhos. Para os conceitos subjacentes (service accounts, federation issuers e federation rules), consulte Workload Identity Federation.
aws ou um SDK da AWS disponível no workload.A API GetWebIdentityToken do AWS STS retorna um token OIDC assinado pela AWS que atesta a identidade IAM do chamador. Como ela usa as credenciais AWS do ambiente do workload, a mesma integração cobre Lambda, EC2, ECS e EKS.
Habilite a federação de identidade web de saída para a conta
Esta é uma flag no nível da conta, desativada por padrão. No console da AWS, abra IAM, escolha Account settings e habilite Outbound web identity federation. Para habilitá-la programaticamente:
python3 -c "import boto3; boto3.client('iam').enable_outbound_web_identity_federation()"Se isso não estiver habilitado, as chamadas para GetWebIdentityToken falham com OutboundWebIdentityFederationDisabledException.
Conceda à IAM role do workload permissão para chamar a API
Anexe esta política à IAM role com a qual sua função Lambda, instância EC2 ou task ECS é executada:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["sts:GetWebIdentityToken"],
"Resource": "*"
}
]
}Encontre a URL do issuer do STS da sua conta
Após habilitar a federação de saída, a página IAM > Account settings mostra um campo Get Token Issuer URL com um valor no formato https://<uuid>.tokens.sts.global.api.aws. Esta URL é exclusiva da sua conta AWS; copie-a para a próxima etapa. Para recuperá-la programaticamente:
python3 -c "import boto3; print(boto3.client('iam').get_outbound_web_identity_federation_info())"No Claude Console, abra Settings → Workload identity, clique em Connect workload e selecione o bloco AWS. O assistente orienta você no registro do issuer, na criação de uma service account e na criação de uma federation rule.
O assistente cria esses recursos para você. Use os seguintes valores, seja inserindo-os no assistente ou enviando-os para a Admin API:
Federation issuer: Registre a URL do issuer do STS por conta que você copiou na etapa anterior. Ela expõe um endpoint JWKS público, portanto use o modo de descoberta.
{
"name": "aws-sts",
"issuer_url": "https://<uuid>.tokens.sts.global.api.aws",
"jwks": { "type": "discovery" }
}Federation rule: Faça a correspondência da audience que você passa para GetWebIdentityToken e do ARN da IAM role do chamador na claim sub. O valor de sub é o ARN da IAM role do workload que chamou a API, no formato arn:aws:iam::<account>:role/<role-name>. O token também carrega uma claim https://sts.amazonaws.com/ com aws_account, org_id, principal_id e quaisquer request_tags que você tenha passado; você pode fazer correspondência com esses valores usando o mapa claims da regra ou uma condition em CEL para um controle mais refinado.
{
"name": "prod-inference",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "arn:aws:iam::123456789012:role/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 o workload permitir. Faça a correspondência com o ARN exato da role e só amplie o subject_prefix (por exemplo, para arn:aws:iam::123456789012:role/*) se várias IAM roles devem ser mapeadas para a mesma service account da Anthropic.
Chame GetWebIdentityToken com https://api.anthropic.com como audience e, em seguida, passe o resultado para as credenciais de federação do SDK. O provedor de token é um callable, portanto o SDK reinvoca o STS a cada atualização.
GetWebIdentityToken está disponível apenas em endpoints regionais do STS. Se você receber 'STS' object has no attribute 'get_web_identity_token' ou um erro semelhante, fixe seu cliente STS em uma região (por exemplo, boto3.client("sts", region_name="us-east-1")) e garanta que seu SDK da AWS seja recente o suficiente para incluir a API.
import os
import anthropic
import boto3
from anthropic import WorkloadIdentityCredentials
def get_sts_web_identity_token() -> str:
sts = boto3.client("sts", region_name="us-east-1")
resp = sts.get_web_identity_token(
Audience=["https://api.anthropic.com"],
SigningAlgorithm="RS256",
DurationSeconds=900,
)
return resp["WebIdentityToken"]
client = anthropic.Anthropic(
credentials=WorkloadIdentityCredentials(
identity_token_provider=get_sts_web_identity_token,
federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
),
)
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from AWS"}],
)
print(next(block.text for block in message.content if block.type == "text"))De dentro do workload, troque um token emitido pelo STS diretamente e inspecione a resposta:
JWT=$(aws sts get-web-identity-token \
--region us-east-1 \
--audience "https://api.anthropic.com" \
--signing-algorithm RS256 \
--duration-seconds 900 \
--query WebIdentityToken --output text)
curl -sS https://api.anthropic.com/v1/oauth/token \
-H "content-type: application/json" \
-d "{
\"grant_type\": \"urn:ietf:params:oauth:grant-type:jwt-bearer\",
\"assertion\": \"$JWT\",
\"federation_rule_id\": \"fdrl_...\",
\"organization_id\": \"00000000-0000-0000-0000-000000000000\",
\"service_account_id\": \"svac_...\",
\"workspace_id\": \"wrkspc_...\"
}" | jqUma 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 da AWS é uma incompatibilidade de iss (a URL do issuer do STS por conta deve corresponder exatamente ao issuer_url registrado).
Se o seu workload é executado em um pod EKS, você pode pular a chamada ao STS e ler um token de service account projetado pelo Kubernetes diretamente do disco. O Kubernetes projeta nativamente um token compatível com OIDC no pod, e o SDK pode lê-lo a partir de um caminho de arquivo, portanto nenhum callable de provedor de token é necessário. Este caminho tem duas etapas de configuração da AWS a menos do que o caminho do STS, mas só funciona dentro de um pod; o mecanismo subjacente é o mesmo da integração genérica com Kubernetes.
Este caminho requer adicionalmente um cluster EKS com um provedor OIDC do IAM habilitado e acesso via kubectl ao cluster.
Encontre a URL do issuer OIDC do seu cluster
Cada cluster EKS tem um issuer OIDC exclusivo. Recupere-o com a AWS CLI:
aws eks describe-cluster \
--name <cluster-name> \
--query "cluster.identity.oidc.issuer" \
--output textA saída se parece com https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB.... Você registrará esta URL como um federation issuer na próxima seção.
Crie a service account e projete um token com audience da Anthropic
O webhook de identidade de pod do EKS detecta a anotação eks.amazonaws.com/role-arn e projeta automaticamente um token com aud: sts.amazonaws.com, expondo seu caminho como AWS_WEB_IDENTITY_TOKEN_FILE. Esse token é para assunção de role da AWS. Para a troca com a Anthropic, projete um segundo token com audience: https://api.anthropic.com e monte-o em um caminho dedicado.
apiVersion: v1
kind: ServiceAccount
metadata:
name: inference-worker
namespace: inference
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/inference-workerapiVersion: 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: trueObserve o formato das claims do token
O token projetado é um JSON Web Token (JWT) assinado pelo issuer OIDC do seu cluster. Sua claim sub segue a convenção do Kubernetes system:serviceaccount:<namespace>:<service-account-name>:
{
"iss": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
"sub": "system:serviceaccount:inference:inference-worker",
"aud": ["https://api.anthropic.com"],
"kubernetes.io": {
"namespace": "inference",
"serviceaccount": { "name": "inference-worker", "uid": "..." }
},
"exp": 1775527120,
"iat": 1775523520
}A projeção serviceAccountToken define aud como https://api.anthropic.com. O token separado injetado pelo IRSA em AWS_WEB_IDENTITY_TOKEN_FILE carrega aud: sts.amazonaws.com e é para chamadas à API da AWS, não para esta troca.
No Claude Console, abra Settings → Workload identity, clique em Connect workload e selecione o bloco AWS. O assistente orienta você no registro do issuer, na criação de uma service account e na criação de uma federation rule.
O assistente cria esses recursos para você. Use os seguintes valores, seja inserindo-os no assistente ou enviando-os para a Admin API:
Federation issuer: Issuers do EKS expõem um endpoint JWKS público, portanto use o modo de descoberta. A URL do issuer deve corresponder exatamente à claim iss do token. Registre um issuer por cluster.
{
"name": "prod-eks-uswest2",
"issuer_url": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
"jwks": { "type": "discovery" }
}Federation rule: Faça a correspondência da claim sub do Kubernetes e da audience da Anthropic https://api.anthropic.com. (Projete um token de service account dedicado com essa audience; não reutilize o token padrão sts.amazonaws.com do IRSA.)
{
"name": "prod-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 o workload permitir. Afrouxe o subject_prefix para system:serviceaccount:inference:* (o * no final o torna uma correspondência de prefixo) somente se todas as service accounts no namespace devem ser mapeadas para a mesma service account da Anthropic.
Dentro do pod, o token projetado está em /var/run/secrets/anthropic.com/token (exposto como ANTHROPIC_IDENTITY_TOKEN_FILE na especificação do Pod). Passe esse arquivo para as credenciais de federação do SDK e o SDK cuida da troca e da atualização.
import os
import anthropic
from anthropic import IdentityTokenFile, WorkloadIdentityCredentials
client = anthropic.Anthropic(
credentials=WorkloadIdentityCredentials(
identity_token_provider=IdentityTokenFile(
os.environ["ANTHROPIC_IDENTITY_TOKEN_FILE"]
),
federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
),
)
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from EKS"}],
)
print(next(block.text for block in message.content if block.type == "text"))A especificação do Pod já define ANTHROPIC_IDENTITY_TOKEN_FILE, ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID e ANTHROPIC_WORKSPACE_ID, portanto você pode construir o cliente sem argumentos e o SDK lê as variáveis de ambiente de federação automaticamente.
De dentro do pod, troque o token projetado diretamente e inspecione a resposta:
JWT=$(cat "$ANTHROPIC_IDENTITY_TOKEN_FILE")
curl -sS https://api.anthropic.com/v1/oauth/token \
-H "content-type: application/json" \
-d "{
\"grant_type\": \"urn:ietf:params:oauth:grant-type:jwt-bearer\",
\"assertion\": \"$JWT\",
\"federation_rule_id\": \"$ANTHROPIC_FEDERATION_RULE_ID\",
\"organization_id\": \"$ANTHROPIC_ORGANIZATION_ID\",
\"service_account_id\": \"$ANTHROPIC_SERVICE_ACCOUNT_ID\",
\"workspace_id\": \"$ANTHROPIC_WORKSPACE_ID\"
}" | jqUma 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 EKS é o aud do token projetado não corresponder à regra (projete um token com audience: https://api.anthropic.com, não o padrão sts.amazonaws.com do IRSA).
Um subject_prefix de arn:aws:iam::123456789012:role/* corresponde a todas as IAM roles da conta. Qualquer principal que possa assumir qualquer role correspondente pode obter um token federado da Anthropic.
Restrinja o bloco match da regra ao escopo mais estreito que se adeque ao seu caso de uso:
subject_prefix: "arn:aws:iam::<account>:role/<role-name>" sem * no final para que outras roles na conta não correspondam.aws_account da claim https://sts.amazonaws.com/ do token com o mapa claims ou uma condition em CEL como uma verificação de defesa em profundidade contra um prefixo mal configurado.system:serviceaccount:<namespace>:<name> sem * após o prefixo system:serviceaccount:.Was this page helpful?