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
awso 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.
Usar tokens de identidad web de STS (recomendado)
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
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
GetWebIdentityTokenfallan conOutboundWebIdentityFederationDisabledException.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": "*" } ] }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:
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_...\"
}" | jqUn 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
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:
CLIaws eks describe-cluster \ --name <cluster-name> \ --query "cluster.identity.oidc.issuer" \ --output textLa 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.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-arny proyecta automáticamente un token conaud: sts.amazonaws.com, exponiendo su ruta comoAWS_WEB_IDENTITY_TOKEN_FILE. Ese token es para la asunción de roles de AWS. Para el intercambio con Anthropic, proyecta un segundo token conaudience: https://api.anthropic.comy 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-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: trueObserva 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
subsigue la convención de Kubernetessystem: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
serviceAccountTokenestableceaudenhttps://api.anthropic.com. El token separado inyectado por IRSA enAWS_WEB_IDENTITY_TOKEN_FILEllevaaud: sts.amazonaws.comy 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:
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\"
}" | jqUn 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_accountdel claimhttps://sts.amazonaws.com/del token con el mapaclaimso unaconditionCEL 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 prefijosystem: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?