Claude Platform Docs
AdministrationFournisseurs d'identité

Utiliser WIF avec AWS

Authentifiez les charges de travail AWS sur Lambda, EC2, ECS ou EKS auprès de l'API Claude avec Workload Identity Federation et des jetons d'identité émis par STS.

Les charges de travail AWS peuvent s'authentifier auprès de l'API Claude sans clés API statiques en échangeant un jeton d'identité OIDC signé par AWS. La méthode recommandée appelle l'API AWS STS GetWebIdentityToken, qui fonctionne partout où la charge de travail dispose d'identifiants AWS : Lambda, EC2, ECS et EKS. Les charges de travail EKS peuvent également utiliser la méthode du jeton projeté Kubernetes, qui comporte moins d'étapes de configuration mais ne fonctionne qu'à l'intérieur d'un pod.

Ce guide présente les deux méthodes. Pour les concepts sous-jacents (comptes de service, émetteurs de fédération et règles de fédération), consultez Workload Identity Federation.

Prérequis

  • Une familiarité avec les concepts WIF : comptes de service, émetteurs de fédération et règles de fédération.
  • Une charge de travail AWS (pod EKS, tâche ECS, fonction Lambda ou instance EC2) avec un rôle IAM attaché.
  • La CLI aws ou un SDK AWS disponible dans la charge de travail.
  • L'autorisation de créer des comptes de service, des émetteurs de fédération et des règles de fédération dans la Claude Console pour votre organisation Anthropic.

L'API AWS STS GetWebIdentityToken renvoie un jeton OIDC signé par AWS qui atteste l'identité IAM de l'appelant. Comme elle utilise les identifiants AWS ambiants de la charge de travail, la même intégration couvre Lambda, EC2, ECS et EKS.

Configurer AWS

  1. Activer la fédération d'identité web sortante pour le compte

    Il s'agit d'un indicateur au niveau du compte, désactivé par défaut. Dans la console AWS, ouvrez IAM, choisissez Account settings et activez Outbound web identity federation. Pour l'activer par programmation :

    python3 -c "import boto3; boto3.client('iam').enable_outbound_web_identity_federation()"

    Si cette option n'est pas activée, les appels à GetWebIdentityToken échouent avec OutboundWebIdentityFederationDisabledException.

  2. Accorder au rôle IAM de la charge de travail l'autorisation d'appeler l'API

    Attachez cette politique au rôle IAM sous lequel s'exécute votre fonction Lambda, votre instance EC2 ou votre tâche ECS :

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["sts:GetWebIdentityToken"],
          "Resource": "*"
        }
      ]
    }
  3. Trouver l'URL de l'émetteur STS de votre compte

    Après avoir activé la fédération sortante, la page IAM > Account settings affiche un champ Get Token Issuer URL dont la valeur a la forme https://<uuid>.tokens.sts.global.api.aws. Cette URL est propre à votre compte AWS ; copiez-la pour l'étape suivante. Pour la récupérer par programmation :

    python3 -c "import boto3; print(boto3.client('iam').get_outbound_web_identity_federation_info())"

Configurer Anthropic

Dans la Claude Console, ouvrez Settings → Workload identity, cliquez sur Connect workload et sélectionnez la tuile AWS. L'assistant vous guide dans l'enregistrement de l'émetteur, la création d'un compte de service et la création d'une règle de fédération.

L'assistant crée ces ressources pour vous. Utilisez les valeurs suivantes, que vous les saisissiez dans l'assistant ou que vous les envoyiez à l'Admin API :

Émetteur de fédération : enregistrez l'URL de l'émetteur STS propre au compte que vous avez copiée à l'étape précédente. Elle expose un point de terminaison JWKS public, utilisez donc le mode découverte.

{
  "name": "aws-sts",
  "issuer_url": "https://<uuid>.tokens.sts.global.api.aws",
  "jwks": { "type": "discovery" }
}

Règle de fédération : faites correspondre l'audience que vous transmettez à GetWebIdentityToken et l'ARN du rôle IAM appelant dans la revendication sub. La valeur sub est l'ARN du rôle IAM de la charge de travail qui a appelé l'API, sous la forme arn:aws:iam::<account>:role/<role-name>. Le jeton contient également une revendication https://sts.amazonaws.com/ avec aws_account, org_id, principal_id et tous les request_tags que vous avez transmis ; vous pouvez établir une correspondance sur ceux-ci avec la table claims de la règle ou une condition CEL pour un contrôle plus fin.

{
  "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
}

Soyez aussi précis que la charge de travail le permet. Faites correspondre l'ARN exact du rôle et n'élargissez subject_prefix (par exemple, à arn:aws:iam::123456789012:role/*) que si plusieurs rôles IAM doivent correspondre au même compte de service Anthropic.

Obtenir et utiliser le jeton

Appelez GetWebIdentityToken avec https://api.anthropic.com comme audience, puis transmettez le résultat aux identifiants de fédération du SDK. Le fournisseur de jeton est un objet appelable, de sorte que le SDK réinvoque STS à chaque actualisation.

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"))

Vérifier la configuration

Depuis l'intérieur de la charge de travail, échangez directement un jeton émis par STS et examinez la réponse :

cURL
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_...\"
  }" | jq

Un échange réussi renvoie un access_token commençant par sk-ant-oat01- et une valeur expires_in en secondes. Si l'échange échoue avec la réponse opaque 401 authentication_error (message Authentication failed), consultez la page d'historique d'authentification pour connaître le motif du refus et reportez-vous à Dépanner un échange en échec ; la cause la plus fréquente côté AWS est une non-correspondance de iss (l'URL de l'émetteur STS propre au compte doit correspondre exactement à l'issuer_url enregistrée).

Utiliser les jetons de compte de service projetés EKS

Si votre charge de travail s'exécute dans un pod EKS, vous pouvez ignorer l'appel STS et lire directement depuis le disque un jeton de compte de service projeté par Kubernetes. Kubernetes projette nativement un jeton compatible OIDC dans le pod, et le SDK peut le lire à partir d'un chemin de fichier, de sorte qu'aucun fournisseur de jeton appelable n'est nécessaire. Cette méthode comporte deux étapes de configuration AWS de moins que la méthode STS mais ne fonctionne qu'à l'intérieur d'un pod ; le mécanisme sous-jacent est le même que celui de l'intégration Kubernetes générique.

Cette méthode nécessite en outre un cluster EKS avec un fournisseur OIDC IAM activé et un accès kubectl au cluster.

Configurer votre cluster EKS

  1. Trouver l'URL de l'émetteur OIDC de votre cluster

    Chaque cluster EKS possède un émetteur OIDC unique. Récupérez-le avec la CLI AWS :

    CLI
    aws eks describe-cluster \
      --name <cluster-name> \
      --query "cluster.identity.oidc.issuer" \
      --output text

    La sortie ressemble à https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB.... Vous enregistrerez cette URL comme émetteur de fédération dans la section suivante.

  2. Créer le compte de service et projeter un jeton avec l'audience Anthropic

    Le webhook d'identité de pod EKS détecte l'annotation eks.amazonaws.com/role-arn et projette automatiquement un jeton avec aud: sts.amazonaws.com, en exposant son chemin sous AWS_WEB_IDENTITY_TOKEN_FILE. Ce jeton sert à l'endossement de rôle AWS. Pour l'échange Anthropic, projetez un second jeton avec audience: https://api.anthropic.com et montez-le à un chemin dédié.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: inference-worker
      namespace: inference
      annotations:
        eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/inference-worker
    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
  3. Noter la forme des revendications du jeton

    Le jeton projeté est un « JSON Web Token » (jeton web JSON), ou JWT, signé par l'émetteur OIDC de votre cluster. Sa revendication sub suit la convention 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 projection serviceAccountToken définit aud sur https://api.anthropic.com. Le jeton distinct injecté par IRSA à l'emplacement AWS_WEB_IDENTITY_TOKEN_FILE porte aud: sts.amazonaws.com et sert aux appels d'API AWS, pas à cet échange.

Configurer Anthropic

Dans la Claude Console, ouvrez Settings → Workload identity, cliquez sur Connect workload et sélectionnez la tuile AWS. L'assistant vous guide dans l'enregistrement de l'émetteur, la création d'un compte de service et la création d'une règle de fédération.

L'assistant crée ces ressources pour vous. Utilisez les valeurs suivantes, que vous les saisissiez dans l'assistant ou que vous les envoyiez à l'Admin API :

Émetteur de fédération : les émetteurs EKS exposent un point de terminaison JWKS public, utilisez donc le mode découverte. L'URL de l'émetteur doit correspondre exactement à la revendication iss du jeton. Enregistrez un émetteur par cluster.

{
  "name": "prod-eks-uswest2",
  "issuer_url": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
  "jwks": { "type": "discovery" }
}

Règle de fédération : faites correspondre la revendication sub Kubernetes et l'audience Anthropic https://api.anthropic.com. (Projetez un jeton de compte de service dédié avec cette audience ; ne réutilisez pas le jeton IRSA par défaut 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
}

Soyez aussi précis que la charge de travail le permet. N'assouplissez subject_prefix en system:serviceaccount:inference:* (le * final en fait une correspondance par préfixe) que si chaque compte de service de l'espace de noms doit correspondre au même compte de service Anthropic.

Obtenir et utiliser le jeton

À l'intérieur du pod, le jeton projeté se trouve à /var/run/secrets/anthropic.com/token (exposé sous ANTHROPIC_IDENTITY_TOKEN_FILE dans la spécification du Pod). Transmettez ce fichier aux identifiants de fédération du SDK et le SDK gère l'échange et l'actualisation.

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"))

Vérifier la configuration

Depuis l'intérieur du pod, échangez directement le jeton projeté et examinez la réponse :

cURL
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\"
  }" | jq

Un échange réussi renvoie un access_token commençant par sk-ant-oat01- et une valeur expires_in en secondes. Si l'échange échoue avec la réponse opaque 401 authentication_error (message Authentication failed), consultez la page d'historique d'authentification pour connaître le motif du refus et reportez-vous à Dépanner un échange en échec ; la cause la plus fréquente côté EKS est que l'aud du jeton projeté ne correspond pas à la règle (projetez un jeton avec audience: https://api.anthropic.com, et non la valeur IRSA par défaut sts.amazonaws.com).

Délimiter votre règle

Verrouillez le bloc match de la règle sur la portée la plus étroite qui convient à votre cas d'utilisation :

  • Fixer l'ARN complet du rôle : utilisez subject_prefix: "arn:aws:iam::<account>:role/<role-name>" sans * final afin que les autres rôles du compte ne correspondent pas.
  • Fixer l'ID du compte : faites correspondre le champ aws_account de la revendication https://sts.amazonaws.com/ du jeton avec la table claims ou une condition CEL comme vérification de défense en profondeur contre un préfixe mal configuré.
  • Fixer l'espace de noms et le compte de service sur EKS : utilisez la valeur exacte system:serviceaccount:<namespace>:<name> sans * après le préfixe system:serviceaccount:.
  • Utiliser une règle distincte par environnement : créez des règles distinctes pour les charges de travail de production, de préproduction et de développement plutôt que d'élargir un seul préfixe pour toutes les couvrir.

Étapes suivantes

  • Consultez la référence WIF pour la référence complète sur l'ordre de priorité des identifiants, la configuration des profils et la correspondance des règles.
  • Pour les clusters Kubernetes autogérés qui ne sont pas sur EKS, consultez Utiliser WIF avec Kubernetes.

Was this page helpful?