Los clústeres de Kubernetes autogestionados (kubeadm, k3s, OpenShift y distribuciones on-premises) firman "JSON Web Tokens" (tokens web JSON), o JWTs, de OIDC para cada pod mediante tokens de cuenta de servicio proyectados. El servidor de API del clúster actúa como el emisor OIDC, y el claim sub de cada token sigue el formato system:serviceaccount:<namespace>:<service-account>. Puedes encontrar la URL del emisor de tu clúster leyendo su documento de descubrimiento:
kubectl get --raw /.well-known/openid-configuration | jq -r .issuerEl mecanismo descrito en esta página (token de cuenta de servicio proyectado, servidor de API del clúster como emisor OIDC) es nativo de Kubernetes, por lo que subyace a todas las distribuciones de Kubernetes. Si usas un servicio de Kubernetes gestionado, las guías de los proveedores de nube explican dónde encontrar la URL del emisor gestionada por el proveedor: AWS (EKS), Google Cloud (GKE) o Azure (AKS). Si tu clúster ejecuta SPIRE, el SPIRE OIDC Discovery Provider es el emisor en lugar del servidor de API del clúster; consulta SPIFFE. Para cualquier otra distribución o un proveedor gestionado que no aparezca en esa lista, sigue esta guía y usa la URL del emisor que reporte tu clúster.
--service-account-issuer configurado en el servidor de API. La mayoría de las distribuciones lo configuran de forma predeterminada; los clústeres de kubeadm suelen usar https://kubernetes.default.svc.cluster.local. Tu equipo de plataforma puede confirmar el valor si no tienes acceso directo a la configuración del servidor de API.inline (se explica en Configurar Anthropic).Proyecta un token de cuenta de servicio en tu pod con la audiencia y el tiempo de vida que espera tu regla de federación. La proyección serviceAccountToken escribe un JWT nuevo en la ruta de montaje y lo rota antes de que transcurra expirationSeconds.
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: trueEl token emitido para este pod contiene sub: "system:serviceaccount:inference:inference-worker" y aud: ["https://api.anthropic.com"].
Sigue la guía de configuración para registrar un emisor de federación, crear una cuenta de servicio de Anthropic y crear una regla de federación en Claude Console. Usa estos valores específicos de Kubernetes.
Emisor de federación: Muchos clústeres autogestionados usan una URL de emisor como https://kubernetes.default.svc.cluster.local que no es accesible desde la internet pública. Si ese es el caso de tu clúster, elige la fuente de JWKS inline y pega las claves del clúster. Obténlas desde dentro del clúster:
kubectl get --raw /openid/v1/jwksLuego configura el emisor con el contenido del array keys devuelto (no el envoltorio {"keys": [...]} que lo rodea):
{
"name": "onprem-k8s",
"issuer_url": "https://kubernetes.default.svc.cluster.local",
"jwks_source": "inline",
"jwks_keys": [{ "kty": "RSA", "kid": "...", "n": "...", "e": "AQAB" }]
}En modo inline, el issuer_url solo se compara con el claim iss del JWT; Anthropic nunca intenta acceder a él. Si tu emisor es accesible públicamente, usa "jwks_source": "discovery" en su lugar y omite jwks_keys.
Con claves inline, eres responsable de actualizar el emisor cuando el clúster rote su clave de firma de cuentas de servicio. La rotación es poco frecuente (normalmente solo durante actualizaciones del clúster), pero los intercambios de tokens fallan con un error de firma hasta que subas el nuevo JWKS.
Regla de federación: Haz coincidir el claim sub de la cuenta de servicio y la audiencia que configuraste en el token proyectado.
{
"name": "onprem-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 lo permita la carga de trabajo. 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. Agrega el ID fdrl_... de la regla a la variable de entorno ANTHROPIC_FEDERATION_RULE_ID de tu pod.
La especificación del pod en Configurar Kubernetes establece ANTHROPIC_IDENTITY_TOKEN_FILE en la ruta de montaje proyectada, junto con ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID y ANTHROPIC_WORKSPACE_ID. Con eso configurado, el SDK lee el token del disco en cada intercambio y actualiza automáticamente el token de acceso de Anthropic.
Un intercambio exitoso devuelve un access_token que comienza con sk-ant-oat01- y un valor expires_in en segundos. Si recibes 400 invalid_grant, consulta Solucionar problemas de un intercambio fallido; la causa más común del lado de Kubernetes es una discrepancia de claves JWKS (para el modo inline, vuelve a obtenerlas con kubectl get --raw /openid/v1/jwks y actualiza el emisor).
Un subject_prefix de system:serviceaccount:* coincide con todas las cuentas de servicio del clúster, por lo que cualquier pod puede obtener un token federado de Anthropic. Sin un matcher de audience, la regla también coincide con los tokens de audiencia predeterminada del clúster, que todos los pods ya tienen proyectados.
Restringe el bloque match de la regla al alcance más estrecho que se ajuste a tu caso de uso:
system:serviceaccount:<namespace>:<name> sin * al final.audience en la regla y configura el mismo valor en la proyección serviceAccountToken del pod para que se rechacen los tokens de audiencia predeterminada.Was this page helpful?
import anthropic
# Lee ANTHROPIC_IDENTITY_TOKEN_FILE, ANTHROPIC_FEDERATION_RULE_ID,
# ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID y ANTHROPIC_WORKSPACE_ID
# del entorno del pod.
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.content[0].text)