Claude Platform Docs
AdministraciónProveedores de identidad

Usar WIF con AWS

Autentica cargas de trabajo de AWS en Lambda, EC2, ECS o EKS ante la Claude API con Workload Identity Federation y tokens de identidad emitidos por STS.

Las cargas de trabajo de AWS pueden autenticarse ante la Claude API sin claves de API estáticas intercambiando un token de identidad OIDC firmado por AWS. La ruta recomendada llama a la API GetWebIdentityToken de AWS STS, que funciona en cualquier lugar donde la carga de trabajo tenga credenciales de AWS: Lambda, EC2, ECS y EKS. Las cargas de trabajo de EKS pueden usar alternativamente la ruta de token proyectado de Kubernetes, que tiene menos pasos de configuración pero solo funciona dentro de un pod.

Esta guía muestra ambas rutas. Para los conceptos subyacentes (cuentas de servicio, emisores de federación y reglas de federación), consulta Workload Identity Federation.

Requisitos previos

  • Familiaridad con los conceptos de WIF: cuentas de servicio, emisores de federación y reglas de federación.
  • Una carga de trabajo de AWS (pod de EKS, tarea de ECS, función Lambda o instancia de EC2) con un rol de IAM asociado.
  • La CLI aws o un SDK de AWS disponible en la carga de trabajo.
  • Permiso para crear cuentas de servicio, emisores de federación y reglas de federación en la Claude Console para tu organización de Anthropic.

La API GetWebIdentityToken de AWS STS devuelve un token OIDC firmado por AWS que afirma la identidad de IAM del llamador. Dado que usa las credenciales de AWS ambientales de la carga de trabajo, la misma integración cubre Lambda, EC2, ECS y EKS.

Configurar AWS

  1. Habilita la federación de identidad web saliente para la cuenta

    Esta es una marca a nivel de cuenta, desactivada de forma predeterminada. En la consola de AWS, abre IAM, elige Account settings y habilita Outbound web identity federation. Para habilitarla programáticamente:

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

    Si esto no está habilitado, las llamadas a GetWebIdentityToken fallan con OutboundWebIdentityFederationDisabledException.

  2. Otorga al rol de IAM de la carga de trabajo permiso para llamar a la API

    Asocia esta política al rol de IAM con el que se ejecuta tu función Lambda, instancia de EC2 o tarea de ECS:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["sts:GetWebIdentityToken"],
          "Resource": "*"
        }
      ]
    }
  3. Encuentra la URL del emisor de STS de tu cuenta

    Después de habilitar la federación saliente, la página IAM > Account settings muestra un campo Get Token Issuer URL con un valor de la forma https://<uuid>.tokens.sts.global.api.aws. Esta URL es única para tu cuenta de AWS; cópiala para el siguiente paso. Para obtenerla programáticamente:

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

Configurar Anthropic

En la Claude Console, abre Settings → Workload identity, haz clic en Connect workload y selecciona el mosaico AWS. El asistente te guía a través del registro del emisor, la creación de una cuenta de servicio y la creación de una regla de federación.

El asistente crea estos recursos por ti. Usa los siguientes valores, ya sea que los ingreses en el asistente o los envíes a la Admin API:

Emisor de federación: Registra la URL del emisor de STS por cuenta que copiaste en el paso anterior. Expone un endpoint JWKS público, así que usa el modo de descubrimiento.

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

Regla de federación: Haz coincidir la audiencia que pasas a GetWebIdentityToken y el ARN del rol de IAM del rol llamador en el claim sub. El valor de sub es el ARN del rol de IAM de la carga de trabajo que llamó a la API, en la forma arn:aws:iam::<account>:role/<role-name>. El token también lleva un claim https://sts.amazonaws.com/ con aws_account, org_id, principal_id y cualquier request_tags que hayas pasado; puedes hacer coincidencias sobre ellos con el mapa claims de la regla o una condition CEL para un control más fino.

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

Sé tan específico como la carga de trabajo lo permita. Haz coincidir el ARN exacto del rol, y solo amplía subject_prefix (por ejemplo, a arn:aws:iam::123456789012:role/*) si varios roles de IAM deben asignarse a la misma cuenta de servicio de Anthropic.

Obtener y usar el token

Llama a GetWebIdentityToken con https://api.anthropic.com como audiencia, luego pasa el resultado a las credenciales de federación del SDK. El proveedor de tokens es un callable, por lo que el SDK vuelve a invocar a STS en cada actualización.

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

Verificar la configuración

Desde dentro de la carga de trabajo, intercambia directamente un token emitido por STS e inspecciona la respuesta:

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 intercambio exitoso devuelve un access_token que comienza con sk-ant-oat01- y un valor expires_in en segundos. Si el intercambio falla con la respuesta opaca 401 authentication_error (mensaje Authentication failed), revisa la página de historial de autenticación para ver el motivo de denegación y consulta Solucionar problemas de un intercambio fallido; la causa más común del lado de AWS es una discrepancia en iss (la URL del emisor de STS por cuenta debe coincidir exactamente con la issuer_url registrada).

Usar tokens de cuenta de servicio proyectados de EKS

Si tu carga de trabajo se ejecuta en un pod de EKS, puedes omitir la llamada a STS y leer un token de cuenta de servicio proyectado por Kubernetes directamente desde el disco. Kubernetes proyecta de forma nativa un token compatible con OIDC en el pod, y el SDK puede leerlo desde una ruta de archivo, por lo que no se requiere un callable proveedor de tokens. Esta ruta tiene dos pasos de configuración de AWS menos que la ruta de STS, pero solo funciona dentro de un pod; el mecanismo subyacente es el mismo que el de la integración genérica de Kubernetes.

Esta ruta requiere además un clúster de EKS con un proveedor OIDC de IAM habilitado y acceso kubectl al clúster.

Configurar tu clúster de EKS

  1. Encuentra la URL del emisor OIDC de tu clúster

    Cada clúster de EKS tiene un emisor OIDC único. Obtenlo con la CLI de AWS:

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

    La salida se ve como https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB.... Registrarás esta URL como emisor de federación en la siguiente sección.

  2. Crea la cuenta de servicio y proyecta un token con audiencia de Anthropic

    El webhook de identidad de pod de EKS detecta la anotación eks.amazonaws.com/role-arn y proyecta automáticamente un token con aud: sts.amazonaws.com, exponiendo su ruta como AWS_WEB_IDENTITY_TOKEN_FILE. Ese token es para la asunción de roles de AWS. Para el intercambio con Anthropic, proyecta un segundo token con audience: https://api.anthropic.com y móntalo en una ruta dedicada.

    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. Observa la forma de los claims del token

    El token proyectado es un "JSON Web Token" (token web JSON), o JWT, firmado por el emisor OIDC de tu clúster. Su claim sub sigue la convención de 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 proyección serviceAccountToken establece aud en https://api.anthropic.com. El token separado inyectado por IRSA en AWS_WEB_IDENTITY_TOKEN_FILE lleva aud: sts.amazonaws.com y es para llamadas a la API de AWS, no para este intercambio.

Configurar Anthropic

En la Claude Console, abre Settings → Workload identity, haz clic en Connect workload y selecciona el mosaico AWS. El asistente te guía a través del registro del emisor, la creación de una cuenta de servicio y la creación de una regla de federación.

El asistente crea estos recursos por ti. Usa los siguientes valores, ya sea que los ingreses en el asistente o los envíes a la Admin API:

Emisor de federación: Los emisores de EKS exponen un endpoint JWKS público, así que usa el modo de descubrimiento. La URL del emisor debe coincidir exactamente con el claim iss del token. Registra un emisor por clúster.

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

Regla de federación: Haz coincidir el claim sub de Kubernetes y la audiencia de Anthropic https://api.anthropic.com. (Proyecta un token de cuenta de servicio dedicado con esa audiencia; no reutilices el token predeterminado de IRSA 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
}

Sé tan específico como la carga de trabajo lo permita. Relaja subject_prefix a system:serviceaccount:inference:* (el * final lo convierte en una coincidencia de prefijo) solo si todas las cuentas de servicio del namespace deben asignarse a la misma cuenta de servicio de Anthropic.

Obtener y usar el token

Dentro del pod, el token proyectado está en /var/run/secrets/anthropic.com/token (expuesto como ANTHROPIC_IDENTITY_TOKEN_FILE en la especificación del Pod). Pasa ese archivo a las credenciales de federación del SDK y el SDK se encarga del intercambio y la actualización.

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

Verificar la configuración

Desde dentro del pod, intercambia directamente el token proyectado e inspecciona la respuesta:

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 intercambio exitoso devuelve un access_token que comienza con sk-ant-oat01- y un valor expires_in en segundos. Si el intercambio falla con la respuesta opaca 401 authentication_error (mensaje Authentication failed), revisa la página de historial de autenticación para ver el motivo de denegación y consulta Solucionar problemas de un intercambio fallido; la causa más común del lado de EKS es que el aud del token proyectado no coincida con la regla (proyecta un token con audience: https://api.anthropic.com, no el predeterminado de IRSA sts.amazonaws.com).

Delimitar el alcance de tu regla

Restringe el bloque match de la regla al alcance más estrecho que se ajuste a tu caso de uso:

  • Fija el ARN completo del rol: Usa subject_prefix: "arn:aws:iam::<account>:role/<role-name>" sin * final para que otros roles de la cuenta no coincidan.
  • Fija el ID de la cuenta: Haz coincidir el campo aws_account del claim https://sts.amazonaws.com/ del token con el mapa claims o una condition CEL como verificación de defensa en profundidad contra un prefijo mal configurado.
  • Fija el namespace y la cuenta de servicio en EKS: Usa el valor exacto system:serviceaccount:<namespace>:<name> sin * después del prefijo system:serviceaccount:.
  • Usa una regla separada por entorno: Crea reglas distintas para las cargas de trabajo de producción, staging y desarrollo en lugar de ampliar un solo prefijo para cubrirlas todas.

Próximos pasos

  • Revisa la referencia de WIF para la referencia completa de precedencia de credenciales, configuración de perfiles y coincidencia de reglas.
  • Para clústeres de Kubernetes autogestionados que no están en EKS, consulta Usar WIF con Kubernetes.

Was this page helpful?