Claude Platform Docs
AdministraciónProveedores de identidad

Usar WIF con Kubernetes

Autentícate en la Claude API desde clústeres de Kubernetes autogestionados usando tokens de cuenta de servicio proyectados.

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 la forma system:serviceaccount:<namespace>:<service-account>. Puedes encontrar la URL del emisor de tu clúster leyendo su documento de descubrimiento:

cURL
kubectl get --raw /.well-known/openid-configuration | jq -r .issuer

Requisitos previos

  • Familiaridad con los conceptos de WIF: cuentas de servicio, emisores de federación y reglas de federación.
  • Un clúster de Kubernetes con el flag --service-account-issuer configurado en el servidor de API. La mayoría de las distribuciones lo establecen por defecto; los clústeres kubeadm normalmente usan 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.
  • Una de las siguientes opciones para que Anthropic pueda validar las firmas de los tokens:
    • El endpoint JWKS del emisor es accesible desde internet pública por HTTPS en el puerto 443, o
    • Puedes obtener el JWKS desde dentro del clúster y registrarlo en modo inline (cubierto en Configurar Anthropic).
  • 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.

Configurar Kubernetes

Proyecta un token de cuenta de servicio en tu pod con la audiencia y la duración 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 transcurran los expirationSeconds.

Pod
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

El token emitido para este pod lleva sub: "system:serviceaccount:inference:inference-worker" y aud: ["https://api.anthropic.com"].

Configurar Anthropic

En la Claude Console, abre Settings → Workload identity, haz clic en Connect workload y selecciona el mosaico 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 internet pública. Si ese es el caso de tu clúster, elige la fuente JWKS inline y pega las claves del clúster. Obtenlas desde dentro del clúster:

cURL
kubectl get --raw /openid/v1/jwks

Luego 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.

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 por prefijo) solo si todas las cuentas de servicio del namespace deben 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 tu pod.

Obtener y usar el token

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 esto configurado, el SDK lee el token desde el disco en cada intercambio y renueva 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
# desde el 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"))

Verificar la configuración

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 del rechazo y 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).

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 namespace y el nombre de la cuenta de servicio: Usa el valor completo system:serviceaccount:<namespace>:<name> sin * final.
  • Establece siempre una audiencia: Exige audience en la regla y establece el mismo valor en la proyección serviceAccountToken del pod para que los tokens de audiencia predeterminada sean rechazados.
  • Usa una regla separada por namespace: Crea una regla y una cuenta de servicio de Anthropic distintas para cada namespace en lugar de ampliar una sola regla.
  • Limita los emisores con JWKS inline a un solo clúster: Cuando varios clústeres comparten una URL de emisor, registra el JWKS de cada clúster como su propio emisor de federación y vincula las reglas únicamente a ese emisor.

Próximos pasos

Was this page helpful?