AWS-Workloads können sich ohne statische API-Keys bei der Claude API authentifizieren, indem sie ein von AWS signiertes OIDC-Identitätstoken austauschen. Der empfohlene Weg ruft die AWS STS GetWebIdentityToken API auf, die überall dort funktioniert, wo der Workload über AWS-Anmeldeinformationen verfügt: Lambda, EC2, ECS und EKS. EKS-Workloads können alternativ den Kubernetes-Pfad mit projizierten Token verwenden, der weniger Konfigurationsschritte hat, aber nur innerhalb eines Pods funktioniert.
Dieser Leitfaden zeigt beide Wege. Für die zugrunde liegenden Konzepte (Service Accounts, Federation Issuers und Federation Rules) siehe Workload Identity Federation.
aws CLI oder ein AWS SDK, das im Workload verfügbar ist.Die AWS STS GetWebIdentityToken API gibt ein von AWS signiertes OIDC-Token zurück, das die IAM-Identität des Aufrufers bestätigt. Da sie die vorhandenen AWS-Anmeldeinformationen des Workloads verwendet, deckt dieselbe Integration Lambda, EC2, ECS und EKS ab.
Ausgehende Web Identity Federation für das Konto aktivieren
Dies ist ein Flag auf Kontoebene, das standardmäßig deaktiviert ist. Öffne in der AWS-Konsole IAM, wähle Account settings und aktiviere Outbound web identity federation. Um es programmatisch zu aktivieren:
python3 -c "import boto3; boto3.client('iam').enable_outbound_web_identity_federation()"Wenn dies nicht aktiviert ist, schlagen Aufrufe von GetWebIdentityToken mit OutboundWebIdentityFederationDisabledException fehl.
Der IAM-Rolle des Workloads die Berechtigung zum Aufrufen der API erteilen
Hänge diese Richtlinie an die IAM-Rolle an, unter der deine Lambda-Funktion, EC2-Instanz oder dein ECS-Task ausgeführt wird:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["sts:GetWebIdentityToken"],
"Resource": "*"
}
]
}Die STS-Issuer-URL deines Kontos finden
Nach dem Aktivieren der ausgehenden Federation zeigt die Seite IAM > Account settings ein Feld Get Token Issuer URL mit einem Wert der Form https://<uuid>.tokens.sts.global.api.aws. Diese URL ist für dein AWS-Konto eindeutig; kopiere sie für den nächsten Schritt. Um sie programmatisch abzurufen:
python3 -c "import boto3; print(boto3.client('iam').get_outbound_web_identity_federation_info())"Öffne in der Claude Console Settings → Workload identity, klicke auf Connect workload und wähle die Kachel AWS. Der Assistent führt dich durch die Registrierung des Issuers, die Erstellung eines Service Accounts und die Erstellung einer Federation Rule.
Der Assistent erstellt diese Ressourcen für dich. Verwende die folgenden Werte, unabhängig davon, ob du sie im Assistenten eingibst oder an die Admin API sendest:
Federation Issuer: Registriere die kontospezifische STS-Issuer-URL, die du im vorherigen Schritt kopiert hast. Sie stellt einen öffentlichen JWKS-Endpunkt bereit, verwende also den Discovery-Modus.
{
"name": "aws-sts",
"issuer_url": "https://<uuid>.tokens.sts.global.api.aws",
"jwks": { "type": "discovery" }
}Federation Rule: Gleiche die Audience ab, die du an GetWebIdentityToken übergibst, sowie den IAM-Rollen-ARN der aufrufenden Rolle im sub-Claim. Der sub-Wert ist der IAM-Rollen-ARN des Workloads, der die API aufgerufen hat, in der Form arn:aws:iam::<account>:role/<role-name>. Das Token enthält außerdem einen https://sts.amazonaws.com/-Claim mit aws_account, org_id, principal_id und allen request_tags, die du übergeben hast; du kannst diese mit der claims-Map der Regel oder einer CEL-condition für eine feinere Kontrolle abgleichen.
{
"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
}Sei so spezifisch, wie es der Workload zulässt. Gleiche den exakten Rollen-ARN ab und erweitere subject_prefix nur dann (zum Beispiel auf arn:aws:iam::123456789012:role/*), wenn mehrere IAM-Rollen demselben Anthropic Service Account zugeordnet werden sollen.
Rufe GetWebIdentityToken mit https://api.anthropic.com als Audience auf und übergib dann das Ergebnis an die Federation-Anmeldeinformationen des SDK. Der Token-Provider ist ein Callable, sodass das SDK STS bei jeder Aktualisierung erneut aufruft.
GetWebIdentityToken ist nur auf regionalen STS-Endpunkten verfügbar. Wenn du 'STS' object has no attribute 'get_web_identity_token' oder einen ähnlichen Fehler erhältst, lege deinen STS-Client auf eine Region fest (zum Beispiel boto3.client("sts", region_name="us-east-1")) und stelle sicher, dass dein AWS SDK aktuell genug ist, um die API zu enthalten.
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"))Tausche aus dem Workload heraus ein von STS ausgestelltes Token direkt aus und prüfe die Antwort:
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_...\"
}" | jqEin erfolgreicher Austausch gibt ein access_token zurück, das mit sk-ant-oat01- beginnt, sowie einen expires_in-Wert in Sekunden. Bei 400 invalid_grant siehe Fehlerbehebung bei einem fehlgeschlagenen Austausch; die häufigste Ursache auf AWS-Seite ist eine iss-Nichtübereinstimmung (die kontospezifische STS-Issuer-URL muss exakt mit der registrierten issuer_url übereinstimmen).
Wenn dein Workload in einem EKS-Pod läuft, kannst du den STS-Aufruf überspringen und ein von Kubernetes projiziertes Service-Account-Token direkt von der Festplatte lesen. Kubernetes projiziert nativ ein OIDC-kompatibles Token in den Pod, und das SDK kann es aus einem Dateipfad lesen, sodass kein Token-Provider-Callable erforderlich ist. Dieser Weg hat zwei AWS-Konfigurationsschritte weniger als der STS-Weg, funktioniert aber nur innerhalb eines Pods; der zugrunde liegende Mechanismus ist derselbe wie bei der generischen Kubernetes-Integration.
Dieser Weg erfordert zusätzlich einen EKS-Cluster mit einem aktivierten IAM-OIDC-Provider und kubectl-Zugriff auf den Cluster.
Die OIDC-Issuer-URL deines Clusters finden
Jeder EKS-Cluster hat einen eindeutigen OIDC-Issuer. Rufe ihn mit der AWS CLI ab:
aws eks describe-cluster \
--name <cluster-name> \
--query "cluster.identity.oidc.issuer" \
--output textDie Ausgabe sieht aus wie https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB.... Du registrierst diese URL im nächsten Abschnitt als Federation Issuer.
Den Service Account erstellen und ein Token mit Anthropic-Audience projizieren
Der EKS-Pod-Identity-Webhook erkennt die Annotation eks.amazonaws.com/role-arn und projiziert automatisch ein Token mit aud: sts.amazonaws.com, dessen Pfad als AWS_WEB_IDENTITY_TOKEN_FILE verfügbar gemacht wird. Dieses Token ist für die AWS-Rollenübernahme. Für den Anthropic-Austausch projiziere ein zweites Token mit audience: https://api.anthropic.com und mounte es an einem dedizierten Pfad.
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: trueDie Claim-Struktur des Tokens beachten
Das projizierte Token ist ein JSON Web Token (JWT), das vom OIDC-Issuer deines Clusters signiert ist. Sein sub-Claim folgt der Kubernetes-Konvention 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
}Die serviceAccountToken-Projektion setzt aud auf https://api.anthropic.com. Das separate, von IRSA injizierte Token unter AWS_WEB_IDENTITY_TOKEN_FILE trägt aud: sts.amazonaws.com und ist für AWS-API-Aufrufe gedacht, nicht für diesen Austausch.
Öffne in der Claude Console Settings → Workload identity, klicke auf Connect workload und wähle die Kachel AWS. Der Assistent führt dich durch die Registrierung des Issuers, die Erstellung eines Service Accounts und die Erstellung einer Federation Rule.
Der Assistent erstellt diese Ressourcen für dich. Verwende die folgenden Werte, unabhängig davon, ob du sie im Assistenten eingibst oder an die Admin API sendest:
Federation Issuer: EKS-Issuer stellen einen öffentlichen JWKS-Endpunkt bereit, verwende also den Discovery-Modus. Die Issuer-URL muss exakt mit dem iss-Claim des Tokens übereinstimmen. Registriere einen Issuer pro Cluster.
{
"name": "prod-eks-uswest2",
"issuer_url": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
"jwks": { "type": "discovery" }
}Federation Rule: Gleiche den Kubernetes-sub-Claim und die Anthropic-Audience https://api.anthropic.com ab. (Projiziere ein dediziertes Service-Account-Token mit dieser Audience; verwende nicht das IRSA-Standard-Token mit sts.amazonaws.com wieder.)
{
"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
}Sei so spezifisch, wie es der Workload zulässt. Lockere subject_prefix nur dann auf system:serviceaccount:inference:* (das abschließende * macht daraus einen Präfix-Abgleich), wenn jeder Service Account im Namespace demselben Anthropic Service Account zugeordnet werden soll.
Innerhalb des Pods befindet sich das projizierte Token unter /var/run/secrets/anthropic.com/token (als ANTHROPIC_IDENTITY_TOKEN_FILE in der Pod-Spezifikation verfügbar gemacht). Übergib diese Datei an die Federation-Anmeldeinformationen des SDK, und das SDK übernimmt den Austausch und die Aktualisierung.
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"))Die Pod-Spezifikation setzt bereits ANTHROPIC_IDENTITY_TOKEN_FILE, ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID, sodass du den Client ohne Argumente erstellen kannst und das SDK die Federation-Umgebungsvariablen automatisch liest.
Tausche aus dem Pod heraus das projizierte Token direkt aus und prüfe die Antwort:
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\"
}" | jqEin erfolgreicher Austausch gibt ein access_token zurück, das mit sk-ant-oat01- beginnt, sowie einen expires_in-Wert in Sekunden. Bei 400 invalid_grant siehe Fehlerbehebung bei einem fehlgeschlagenen Austausch; die häufigste Ursache auf EKS-Seite ist, dass das aud des projizierten Tokens nicht mit der Regel übereinstimmt (projiziere ein Token mit audience: https://api.anthropic.com, nicht mit dem IRSA-Standard sts.amazonaws.com).
Ein subject_prefix von arn:aws:iam::123456789012:role/* passt auf jede IAM-Rolle im Konto. Jeder Principal, der eine passende Rolle übernehmen kann, kann ein föderiertes Anthropic-Token erhalten.
Beschränke den match-Block der Regel auf den engsten Geltungsbereich, der zu deinem Anwendungsfall passt:
subject_prefix: "arn:aws:iam::<account>:role/<role-name>" ohne abschließendes *, damit andere Rollen im Konto nicht übereinstimmen.aws_account des https://sts.amazonaws.com/-Claims des Tokens mit der claims-Map oder einer CEL-condition ab, als Defense-in-Depth-Prüfung gegen ein falsch konfiguriertes Präfix.system:serviceaccount:<namespace>:<name> ohne * nach dem Präfix system:serviceaccount:.Was this page helpful?