I workload AWS possono autenticarsi all'API di Claude senza chiavi API statiche scambiando un token di identità OIDC firmato da AWS. Il percorso consigliato chiama l'API AWS STS GetWebIdentityToken, che funziona ovunque il workload disponga di credenziali AWS: Lambda, EC2, ECS ed EKS. I workload EKS possono in alternativa usare il percorso del token proiettato di Kubernetes, che richiede meno passaggi di configurazione ma funziona solo all'interno di un pod.
Questa guida mostra entrambi i percorsi. Per i concetti sottostanti (service account, federation issuer e federation rule), consulta Workload Identity Federation.
aws o un SDK AWS disponibile nel workload.L'API AWS STS GetWebIdentityToken restituisce un token OIDC firmato da AWS che attesta l'identità IAM del chiamante. Poiché utilizza le credenziali AWS ambientali del workload, la stessa integrazione copre Lambda, EC2, ECS ed EKS.
Abilita la federazione di identità web in uscita per l'account
Questo è un flag a livello di account, disattivato per impostazione predefinita. Nella console AWS, apri IAM, scegli Account settings e abilita Outbound web identity federation. Per abilitarlo a livello di programmazione:
python3 -c "import boto3; boto3.client('iam').enable_outbound_web_identity_federation()"Se non è abilitato, le chiamate a GetWebIdentityToken falliscono con OutboundWebIdentityFederationDisabledException.
Concedi al ruolo IAM del workload l'autorizzazione a chiamare l'API
Associa questa policy al ruolo IAM con cui viene eseguita la tua funzione Lambda, istanza EC2 o task ECS:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["sts:GetWebIdentityToken"],
"Resource": "*"
}
]
}Trova l'URL dell'issuer STS del tuo account
Dopo aver abilitato la federazione in uscita, la pagina IAM > Account settings mostra un campo Get Token Issuer URL con un valore nella forma https://<uuid>.tokens.sts.global.api.aws. Questo URL è univoco per il tuo account AWS; copialo per il passaggio successivo. Per recuperarlo a livello di programmazione:
python3 -c "import boto3; print(boto3.client('iam').get_outbound_web_identity_federation_info())"Segui la procedura di configurazione per registrare un federation issuer, creare un service account Anthropic e creare una federation rule nella Claude Console. Usa questi valori specifici per STS.
Federation issuer: Registra l'URL dell'issuer STS specifico dell'account che hai copiato nel passaggio precedente. Espone un endpoint JWKS pubblico, quindi usa la modalità discovery.
{
"name": "aws-sts",
"issuer_url": "https://<uuid>.tokens.sts.global.api.aws",
"jwks_source": "discovery"
}Federation rule: Fai corrispondere l'audience che passi a GetWebIdentityToken e l'ARN del ruolo IAM del ruolo chiamante nel claim sub. Il valore sub è l'ARN del ruolo IAM del workload che ha chiamato l'API, nella forma arn:aws:iam::<account>:role/<role-name>. Il token contiene anche un claim https://sts.amazonaws.com/ con aws_account, org_id, principal_id e qualsiasi request_tags che hai passato; puoi fare corrispondenza su questi con la mappa claims della regola o una condition CEL per un controllo più granulare.
{
"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
}Sii il più specifico possibile in base al workload. Fai corrispondere l'ARN esatto del ruolo e allarga subject_prefix (ad esempio, a arn:aws:iam::123456789012:role/*) solo se più ruoli IAM devono essere mappati allo stesso service account Anthropic.
Chiama GetWebIdentityToken con https://api.anthropic.com come audience, quindi passa il risultato alle credenziali di federazione dell'SDK. Il token provider è un callable, quindi l'SDK richiama nuovamente STS a ogni refresh.
GetWebIdentityToken è disponibile solo sugli endpoint STS regionali. Se ricevi 'STS' object has no attribute 'get_web_identity_token' o un errore simile, fissa il tuo client STS a una regione (ad esempio, boto3.client("sts", region_name="us-east-1")) e assicurati che il tuo SDK AWS sia abbastanza recente da includere l'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-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from AWS"}],
)
print(message.content[0].text)Dall'interno del workload, scambia direttamente un token emesso da STS e ispeziona la risposta:
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_...\"
}" | jqUno scambio riuscito restituisce un access_token che inizia con sk-ant-oat01- e un valore expires_in in secondi. In caso di 400 invalid_grant, consulta Risolvere i problemi di uno scambio fallito; la causa più comune lato AWS è una mancata corrispondenza di iss (l'URL dell'issuer STS specifico dell'account deve corrispondere esattamente all'issuer_url registrato).
Se il tuo workload viene eseguito in un pod EKS, puoi saltare la chiamata STS e leggere un token di service account proiettato da Kubernetes direttamente dal disco. Kubernetes proietta nativamente un token compatibile con OIDC nel pod, e l'SDK può leggerlo da un percorso di file, quindi non è richiesto alcun callable token-provider. Questo percorso ha due passaggi di configurazione AWS in meno rispetto al percorso STS ma funziona solo all'interno di un pod; il meccanismo sottostante è lo stesso dell'integrazione generica di Kubernetes.
Questo percorso richiede inoltre un cluster EKS con un provider OIDC IAM abilitato e accesso kubectl al cluster.
Trova l'URL dell'issuer OIDC del tuo cluster
Ogni cluster EKS ha un issuer OIDC univoco. Recuperalo con la CLI AWS:
aws eks describe-cluster \
--name <cluster-name> \
--query "cluster.identity.oidc.issuer" \
--output textL'output è simile a https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB.... Registrerai questo URL come federation issuer nella sezione successiva.
Crea il service account e proietta un token con audience Anthropic
Il webhook di identità del pod EKS rileva l'annotazione eks.amazonaws.com/role-arn e proietta automaticamente un token con aud: sts.amazonaws.com, esponendo il suo percorso come AWS_WEB_IDENTITY_TOKEN_FILE. Quel token serve per l'assunzione del ruolo AWS. Per lo scambio con Anthropic, proietta un secondo token con audience: https://api.anthropic.com e montalo in un percorso dedicato.
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: trueNota la struttura dei claim del token
Il token proiettato è un "JSON Web Token" (token web JSON), o JWT, firmato dall'issuer OIDC del tuo cluster. Il suo claim sub segue la convenzione 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
}La proiezione serviceAccountToken imposta aud su https://api.anthropic.com. Il token separato iniettato da IRSA in AWS_WEB_IDENTITY_TOKEN_FILE contiene aud: sts.amazonaws.com ed è destinato alle chiamate API AWS, non a questo scambio.
Segui la procedura di configurazione per registrare un federation issuer, creare un service account Anthropic e creare una federation rule nella Claude Console. Usa questi valori specifici per EKS.
Federation issuer: Gli issuer EKS espongono un endpoint JWKS pubblico, quindi usa la modalità discovery. L'URL dell'issuer deve corrispondere esattamente al claim iss del token. Registra un issuer per cluster.
{
"name": "prod-eks-uswest2",
"issuer_url": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
"jwks_source": "discovery"
}Federation rule: Fai corrispondere il claim sub di Kubernetes e l'audience Anthropic https://api.anthropic.com. (Proietta un token di service account dedicato con quell'audience; non riutilizzare il token IRSA predefinito sts.amazonaws.com.)
{
"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
}Sii il più specifico possibile in base al workload. Allenta subject_prefix a system:serviceaccount:inference:* (il * finale lo rende una corrispondenza di prefisso) solo se ogni service account nel namespace deve essere mappato allo stesso service account Anthropic.
All'interno del pod, il token proiettato si trova in /var/run/secrets/anthropic.com/token (esposto come ANTHROPIC_IDENTITY_TOKEN_FILE nella specifica del Pod). Passa quel file alle credenziali di federazione dell'SDK e l'SDK gestisce lo scambio e il refresh.
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-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from EKS"}],
)
print(message.content[0].text)La specifica del Pod imposta già ANTHROPIC_IDENTITY_TOKEN_FILE, ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID e ANTHROPIC_WORKSPACE_ID, quindi puoi costruire il client senza argomenti e l'SDK legge automaticamente le variabili d'ambiente di federazione.
Dall'interno del pod, scambia direttamente il token proiettato e ispeziona la risposta:
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\"
}" | jqUno scambio riuscito restituisce un access_token che inizia con sk-ant-oat01- e un valore expires_in in secondi. In caso di 400 invalid_grant, consulta Risolvere i problemi di uno scambio fallito; la causa più comune lato EKS è che l'aud del token proiettato non corrisponde alla regola (proietta un token con audience: https://api.anthropic.com, non il valore predefinito IRSA sts.amazonaws.com).
Un subject_prefix di arn:aws:iam::123456789012:role/* corrisponde a ogni ruolo IAM nell'account. Qualsiasi principal che può assumere un qualsiasi ruolo corrispondente può ottenere un token Anthropic federato.
Blocca il blocco match della regola all'ambito più ristretto adatto al tuo caso d'uso:
subject_prefix: "arn:aws:iam::<account>:role/<role-name>" senza * finale in modo che gli altri ruoli nell'account non corrispondano.aws_account del claim https://sts.amazonaws.com/ del token tramite la mappa claims o una condition CEL come controllo di difesa in profondità contro un prefisso configurato in modo errato.system:serviceaccount:<namespace>:<name> senza * dopo il prefisso system:serviceaccount:.Was this page helpful?