SPIFFE es el estándar de la CNCF para emitir identidad a cargas de trabajo. SPIRE es su implementación de referencia de código abierto, y varios productos comerciales también emiten identidades conformes a SPIFFE. Anthropic federa con cualquier implementación de SPIFFE que emita JWT-SVIDs compatibles con OIDC. Para una lista actualizada de implementaciones, consulta Commercial software that implements SPIFFE en el sitio del proyecto SPIFFE.
La federación funciona ya sea a través de un documento de descubrimiento OIDC en una URL HTTPS pública (modo discovery, sujeto a las restricciones de URL) o registrando el JWKS directamente (modo inline).
La especificación JWT-SVID define sub como el SPIFFE ID de la carga de trabajo, y la Workload API de SPIFFE requiere que el llamador proporcione aud en el momento de la obtención, por lo que esos claims son los mismos en todas las implementaciones. Anthropic requiere adicionalmente iss e iat, ninguno de los cuales es obligatorio según la especificación JWT-SVID, así que configura tu implementación para que complete ambos (en SPIRE, iss es la configuración del servidor jwt_issuer e iat se establece automáticamente). Con eso en su lugar, las secciones Configura Anthropic, Adquiere y usa el token y Delimita tu regla de esta guía aplican a cualquier implementación de SPIFFE.
SPIFFE asigna a cada carga de trabajo una URI de identidad estable de la forma spiffe://<trust-domain>/<path>, y SPIRE emite esa identidad como un JWT-SVID bajo demanda a través de la Workload API. Un JWT-SVID es un JWT firmado ordinario cuyo claim sub es el SPIFFE ID de la carga de trabajo y cuyo claim aud es proporcionado por la carga de trabajo en el momento de la obtención.
El puente desde un dominio de confianza de SPIRE hacia OIDC estándar es el SPIRE OIDC Discovery Provider, un asistente independiente que publica /.well-known/openid-configuration y un endpoint JWKS para las claves de firma JWT del dominio de confianza. Con el proveedor de descubrimiento en ejecución, un JWT-SVID se valida como cualquier otro token OIDC: registra la URL de descubrimiento como un emisor de federación, escribe una regla de federación que coincida con el SPIFFE ID de la carga de trabajo, y haz que la carga de trabajo presente su JWT-SVID al endpoint de intercambio de tokens de Anthropic.
Los ejemplos de esta página usan SPIRE y aplican en cualquier lugar donde se ejecute SPIRE Agent: pods de Kubernetes, máquinas virtuales y hosts bare-metal.
Si tu clúster de Kubernetes no ejecuta SPIRE y quieres autenticarte con los tokens de cuenta de servicio proyectados nativos del clúster en su lugar, consulta Usa WIF con Kubernetes.
inline.iss en los JWT-SVIDs al valor que registrarás como el issuer_url del emisor de federación. Para el modo discovery, esta es la URL pública del endpoint de descubrimiento (en SPIRE, la configuración del servidor jwt_issuer).El valor de audiencia a solicitar al obtener un JWT-SVID es siempre https://api.anthropic.com. Usa este valor en el jwt_audience de spiffe-helper, en la llamada FetchJWTSVID de la Workload API y en el matcher audience de la regla de federación.
Las instrucciones de esta sección son específicas de SPIRE. Si usas un emisor SPIFFE diferente, configura su endpoint de descubrimiento OIDC y la obtención de JWT-SVID según su propia documentación, luego continúa en Configura Anthropic.
Si ya ejecutas SPIRE con el OIDC Discovery Provider, federar con Anthropic requiere tres cosas del lado de SPIRE: un jwt_issuer que coincida con la URL de descubrimiento, una entrada de registro para la carga de trabajo que llamará a la API de Claude, y una forma de que esa carga de trabajo obtenga un JWT-SVID con la audiencia de Anthropic. Las siguientes subsecciones recorren cada una. Los fragmentos de configuración muestran solo los ajustes relevantes para la federación con Anthropic, no configuraciones completas de despliegue de SPIRE.
¿Configurando SPIRE por primera vez? Despliega SPIRE Server y Agent siguiendo el inicio rápido de SPIRE, luego agrega el OIDC Discovery Provider como un servicio separado junto a SPIRE Server. La federación en modo discovery depende de que el proveedor esté desplegado y sea públicamente accesible. El proveedor no es parte de una instalación predeterminada de SPIRE.
Anthropic valida un JWT-SVID comparando su claim iss con un emisor de federación registrado y obteniendo el JWKS del documento de descubrimiento de ese emisor. Dos configuraciones de SPIRE deben coincidir en la misma URL: el jwt_issuer de SPIRE Server (que se convierte en el claim iss de cada JWT-SVID emitido) y la lista domains del OIDC Discovery Provider (que determina el host desde el cual se sirven el documento de descubrimiento y el JWKS). Esa URL compartida es la que registras con Anthropic.
El dominio de confianza y la URL del emisor son independientes. El dominio de confianza (spiffe://prod.example.com) delimita el claim sub. La URL del emisor (https://oidc-discovery.prod.example.com) es donde Anthropic obtiene las claves de firma. No necesitan compartir un nombre de host.
Confirma que jwt_issuer esté establecido en la configuración de SPIRE Server y apunte a la URL pública del proveedor de descubrimiento. El siguiente ejemplo también muestra un tiempo de vida predeterminado de JWT-SVID. El valor predeterminado integrado de SPIRE es de 5 minutos, lo cual es lo suficientemente corto como para requerir rotación continua (consulta Ejecuta spiffe-helper). El endpoint de intercambio de tokens de Anthropic rechaza cualquier token de identidad cuyo tiempo de vida exceda el máximo configurado del emisor de federación, que es de 1 hora de forma predeterminada (consulta Reglas de validación). Esta verificación aplica a toda implementación de SPIFFE, no solo a SPIRE, así que mantén default_jwt_svid_ttl (o cualquier anulación por entrada) en o por debajo de ese máximo.
server {
trust_domain = "prod.example.com"
jwt_issuer = "https://oidc-discovery.prod.example.com"
default_jwt_svid_ttl = "5m"
# ...
}En la configuración del OIDC Discovery Provider, el mismo nombre de host debe aparecer bajo domains, y el proveedor debe poder alcanzar el socket de la API de SPIRE Server. El proveedor sirve el documento de descubrimiento y el JWKS sobre HTTPS. Termina TLS con su soporte ACME integrado, o colócalo detrás de un balanceador de carga que lo haga.
domains = ["oidc-discovery.prod.example.com"]
server_api {
address = "unix:///run/spire/sockets/private/api.sock"
}
acme {
email = "[email protected]"
tos_accepted = true
}El ejemplo usa server_api, que conecta el proveedor de descubrimiento al socket de la API privilegiada de SPIRE Server. El proveedor también acepta un bloque workload_api (con socket_path y trust_domain) que obtiene el bundle a través de la Workload API de un SPIRE Agent en su lugar. Úsalo cuando el proveedor de descubrimiento no deba tener acceso a la Server API o se ejecute en un nodo que no puede alcanzar el Server.
Cada carga de trabajo que llama a la API de Claude necesita una entrada de registro de SPIRE que mapee sus selectores de tiempo de ejecución a un SPIFFE ID. Si la carga de trabajo ya está registrada, anota su SPIFFE ID, que usarás en el subject_prefix de la regla de federación. Si no, regístrala. Para un pod de Kubernetes, los selectores son típicamente el namespace y la cuenta de servicio de Kubernetes:
# Reemplaza NODE_UID con el UID del nodo:
# kubectl get node <node-name> -o jsonpath='{.metadata.uid}'
spire-server entry create \
-spiffeID spiffe://prod.example.com/ns/inference/sa/worker \
-parentID spiffe://prod.example.com/spire/agent/k8s_psat/prod-cluster/NODE_UID \
-selector k8s:ns:inference \
-selector k8s:sa:workerEl parentID mostrado es el ID de agente autogenerado de un solo nodo. Para un registro a nivel de clúster, asigna como padre de la entrada un alias de nodo para que coincida con cargas de trabajo en todos los nodos, como lo hace el inicio rápido de SPIRE para Kubernetes.
Las cargas de trabajo fuera de Kubernetes usan selectores a nivel de host como unix:uid:1000 (unix:path también está disponible pero requiere discover_workload_path = true en la configuración del atestador de cargas de trabajo unix del agente). Los clústeres que ejecutan spire-controller-manager pueden declarar entradas con el recurso personalizado ClusterSPIFFEID en lugar de llamar a spire-server entry create directamente.
spiffe-helper es una utilidad sidecar que se conecta al socket del SPIRE Agent, obtiene un JWT-SVID para una audiencia dada, lo escribe en un archivo y lo vuelve a obtener antes de que expire. El helper se ejecuta en modo daemon de forma predeterminada. El siguiente ejemplo establece daemon_mode = true explícitamente.
agent_address = "/run/spire/sockets/agent.sock"
# The JWT-SVID file is written under cert_dir
cert_dir = "/var/run/secrets/anthropic.com"
daemon_mode = true
jwt_svids = [{
jwt_audience = "https://api.anthropic.com"
jwt_svid_file_name = "token"
}]En Kubernetes, ejecuta spiffe-helper como un contenedor sidecar que comparta un volumen emptyDir respaldado en memoria (medium: Memory) con tu contenedor de aplicación para que el SVID portador nunca llegue al disco del nodo. Monta el socket del SPIRE Agent desde el host en el sidecar, monta el volumen compartido en /var/run/secrets/anthropic.com en ambos contenedores, y establece ANTHROPIC_IDENTITY_TOKEN_FILE=/var/run/secrets/anthropic.com/token en el contenedor de la aplicación. En VMs y bare metal, ejecuta spiffe-helper como un servicio del sistema junto a la carga de trabajo y apunta ambos a un directorio compartido.
En la Claude Console, abre Settings → Workload identity, haz clic en Connect workload y selecciona Custom OIDC. 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 pública del OIDC Discovery Provider en modo discovery. Anthropic obtiene /.well-known/openid-configuration desde esta URL y sigue el jwks_uri devuelto para recuperar las claves de firma del dominio de confianza.
{
"name": "spire-prod",
"issuer_url": "https://oidc-discovery.prod.example.com",
"jwks": { "type": "discovery" }
}Si el proveedor de descubrimiento no es accesible desde la internet pública, obtén el JWKS tú mismo (curl https://oidc-discovery.prod.example.com/keys) y registra el emisor con "jwks": {"type": "inline", "keys": [...]} usando el contenido del arreglo keys devuelto. En modo inline, el issuer_url solo se compara con el claim iss del JWT-SVID. Anthropic nunca intenta alcanzarlo.
SPIRE rota las claves de firma JWT con frecuencia, de forma predeterminada con la misma cadencia que la CA (ca_ttl, 24 horas). Si registras el emisor con un JWKS inline en lugar de una URL de descubrimiento, debes actualizar el JWKS cada vez que SPIRE rote: agrega la nueva clave antes de que las cargas de trabajo comiencen a presentarla, y elimina las claves reemplazadas una vez que los tokens firmados con ellas hayan expirado. Las claves obsoletas que queden en un JWKS inline permanecen confiables indefinidamente.
Para automatizar las actualizaciones del JWKS sin exponer un endpoint de descubrimiento público, configura un plugin BundlePublisher de SPIRE Server (aws_s3, gcp_cloudstorage o k8s_configmap) con format = "jwks" para enviar las claves de firma JWT a almacenamiento externo en cada rotación, luego actualiza las claves inline del emisor a través de la Admin API.
Regla de federación: Haz coincidir el sub del JWT-SVID (el SPIFFE ID) y el aud que configuraste para que spiffe-helper solicite. Los SPIFFE IDs son cadenas URI y subject_prefix los compara como texto opaco, por lo que tanto un valor exacto como una coincidencia de prefijo con * al final funcionan con ellos. Para patrones más complejos, usa una condition de CEL.
{
"name": "spire-inference-worker",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "spiffe://prod.example.com/ns/inference/sa/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
}token_lifetime_seconds es el tiempo de vida del token de acceso de Anthropic que devuelve el intercambio, no del JWT-SVID. El SDK actualiza el token de acceso automáticamente.
Sé tan específico como la carga de trabajo lo permita. Relaja subject_prefix a spiffe://prod.example.com/ns/inference/* solo si cada carga de trabajo registrada bajo esa ruta debe mapearse a la misma cuenta de servicio de Anthropic. Agrega el ID fdrl_... de la regla a la variable de entorno ANTHROPIC_FEDERATION_RULE_ID de la carga de trabajo.
Los SDKs de Anthropic pueden leer el JWT-SVID desde el archivo que spiffe-helper mantiene o llamar a la Workload API de SPIFFE directamente a través de un callable proveedor de tokens. La ruta del archivo es la integración más simple y funciona en todos los lenguajes del SDK. La ruta del callable elimina el sidecar pero requiere un cliente de la Workload API de SPIFFE en el lenguaje de tu aplicación.
Con spiffe-helper escribiendo un JWT-SVID fresco en /var/run/secrets/anthropic.com/token, establece ANTHROPIC_IDENTITY_TOKEN_FILE a esa ruta junto con ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID y ANTHROPIC_WORKSPACE_ID. El SDK lee el archivo en cada intercambio de tokens, por lo que siempre toma el SVID rotado más recientemente, y actualiza el token de acceso de Anthropic automáticamente antes de que expire. Consulta Variables de entorno para saber de dónde proviene cada valor.
import anthropic
# Lee el JWT-SVID que spiffe-helper escribe en
# ANTHROPIC_IDENTITY_TOKEN_FILE, además de ANTHROPIC_FEDERATION_RULE_ID,
# ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID y ANTHROPIC_WORKSPACE_ID.
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(next(block.text for block in message.content if block.type == "text"))Antes de integrar el SDK, obtén un JWT-SVID directamente desde SPIRE Agent y confirma que los claims coincidan con lo que tu regla de federación espera. Si usas una implementación de SPIFFE diferente, obtén un JWT-SVID con su CLI o cliente de la Workload API y decodifica el payload de la misma manera.
La Workload API atesta el proceso que la llama. Para una entrada de registro de Kubernetes, ejecuta este comando dentro de un pod que satisfaga los selectores de la entrada y tenga el socket del agente montado (por ejemplo, usando kubectl exec). En VMs y bare metal, ejecútalo como el usuario o proceso que coincida con los selectores unix: de la entrada. Ejecutarlo desde una shell de host no atestada devuelve no identity issued, que es la falla más común en el paso de verificación.
spire-agent api fetch jwt \
-audience https://api.anthropic.com \
-socketPath /run/spire/sockets/agent.sock \
-output json \
| jq -r '.[0].svids[0].svid' \
| jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson'El flag -output json devuelve la respuesta del SVID y la respuesta del bundle como un arreglo JSON de dos elementos, por lo que jq -r '.[0].svids[0].svid' extrae el token sin adornos. En versiones más antiguas de SPIRE sin -output, el comando imprime un bloque etiquetado en su lugar. En ese caso, pasa la salida predeterminada a través de awk '/^[[:space:]]*eyJ/{print $1; exit}' para extraer la línea del token. Verifica que iss sea la URL del OIDC Discovery Provider que registraste, que sub sea el SPIFFE ID de la carga de trabajo y que aud contenga https://api.anthropic.com. Luego ejecuta el ejemplo de cURL de Adquiere y usa el token. Un intercambio exitoso devuelve un access_token que comienza con sk-ant-oat01-. Ante un 400 invalid_grant, consulta Soluciona un intercambio fallido. La causa más común del lado de SPIRE es una discrepancia entre el jwt_issuer de SPIRE Server y la URL registrada como emisor de federación.
Las convenciones de rutas de SPIFFE ID son definidas por el operador, por lo que el matcher subject_prefix de la regla de federación debe reflejar el esquema de rutas que usan tus entradas de registro. Los esquemas comunes incluyen spiffe://<trust-domain>/ns/<namespace>/sa/<service-account> (el predeterminado emitido por el recurso ClusterSPIFFEID en spire-controller-manager) y spiffe://<trust-domain>/host/<hostname>/<service> para cargas de trabajo en VMs y bare-metal.
Un subject_prefix de spiffe://prod.example.com/* coincide con todas las cargas de trabajo del dominio de confianza. Sin un matcher audience, la regla también acepta JWT-SVIDs emitidos para cualquier audiencia, incluidos los que la carga de trabajo solicitó para relying parties no relacionadas.
Restringe el bloque match de la regla al alcance más estrecho que se ajuste a tu caso de uso:
subject_prefix al SPIFFE ID completo sin * al final.audience en la regla y configura spiffe-helper (o la llamada a la Workload API) con el mismo valor para que los SVIDs emitidos para otras relying parties sean rechazados.spiffe://prod.example.com/ns/inference/* para otorgar acceso a todas las cargas de trabajo registradas bajo un namespace, y crea una regla y una cuenta de servicio de Anthropic separadas por namespace en lugar de ampliar una sola regla.Federa identidades de aplicaciones de servicio de Okta a la API de Claude con Workload Identity Federation.
Autentica cargas de trabajo en la API de Claude con tokens de identidad de corta duración de tu propio proveedor de identidad en lugar de claves de API estáticas de larga duración.
Variables de entorno, reglas de validación, configuración de perfiles y referencia de errores para Workload Identity Federation.
Autentícate en la API de Claude desde clústeres de Kubernetes autogestionados usando tokens de cuenta de servicio proyectados.
Was this page helpful?