Los clústeres de Kubernetes autogestionados (kubeadm, k3s, OpenShift y distribuciones on-premises) firman JSON Web Tokens (JWTs) de OIDC para cada pod mediante tokens proyectados de cuentas de servicio. El servidor de API del clúster actúa como el emisor de OIDC, y el claim sub de cada token sigue la forma 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 de esta página (token proyectado de cuenta de servicio, servidor de API del clúster como emisor de OIDC) es nativo de Kubernetes en sí, por lo que es la base de todas las distribuciones de Kubernetes. Si usas un servicio de Kubernetes gestionado, las guías de proveedores de nube explican dónde encontrar la URL del emisor gestionado 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 allí, 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 establecen 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 cubre en Configura 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 lleva sub: "system:serviceaccount:inference:inference-worker" y aud: ["https://api.anthropic.com"].
En la Claude Console, abre Settings → Workload identity, haz clic en Connect workload y selecciona el mosaico de Kubernetes. El asistente te guía para registrar el emisor, crear una cuenta de servicio y crear 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: 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 eso aplica a tu clúster, elige la fuente JWKS inline y pega las claves del clúster. Obtenlas desde dentro del clúster:
kubectl get --raw /openid/v1/jwksLuego configura el emisor con el contenido del arreglo keys devuelto (no el envoltorio {"keys": [...]} que lo rodea):
{
"name": "onprem-k8s",
"issuer_url": "https://kubernetes.default.svc.cluster.local",
"jwks": {
"type": "inline",
"keys": [{ "kty": "RSA", "kid": "...", "n": "...", "e": "AQAB" }]
}
}En modo inline, la issuer_url solo se compara con el claim iss del JWT; Anthropic nunca intenta acceder a ella. Si tu emisor es accesible públicamente, usa "jwks": {"type": "discovery"} en su lugar.
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 las actualizaciones del clúster), pero los intercambios de tokens fallan con un error de firma hasta que publiques el nuevo JWKS.
Regla de federación: Haz coincidir el claim sub de la cuenta de servicio y la audiencia que estableciste 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 Configura 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 en su lugar, el SDK lee el token desde el disco en cada intercambio y actualiza el token de acceso de Anthropic automáticamente.
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-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(next(block.text for block in message.content if block.type == "text"))Un intercambio exitoso devuelve un access_token que comienza con sk-ant-oat01- y un valor expires_in en segundos. Ante un 400 invalid_grant, consulta Solucionar 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 comparador 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 establece el mismo valor en la proyección serviceAccountToken del pod para que se rechacen los tokens de audiencia predeterminada.Was this page helpful?