For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegación principal

Configuración de la federación de identidades de carga de trabajo para Kubernetes

Usa Kubernetes como proveedor de identidad de carga de trabajo al intercambiar un token proyectado de cuenta de servicio de Kubernetes por un token de acceso de OpenAI de corta duración.

Para Codex, usa esta página para obtener e inspeccionar el token proyectado. Luego, configura la identidad de carga de trabajo de Codex para que Codex use el archivo de token montado. La asignación de cuentas de servicio y los ejemplos del SDK de esta página se aplican a la API de OpenAI.

Configuración de Kubernetes

Esta guía supone que la proyección de tokens de cuentas de servicio de Kubernetes está habilitada, una función disponible de forma predeterminada en las versiones modernas de Kubernetes. La federación de identidades de carga de trabajo de OpenAI requiere tokens proyectados de cuentas de servicio compatibles con OIDC. No se admiten los tokens heredados de cuentas de servicio de Kubernetes almacenados en Secrets.

Usa una ServiceAccount de Kubernetes para la carga de trabajo que necesita llamar a la API de OpenAI. Si aún no tienes una, créala:

kubectl create serviceaccount openai-wif --namespace default

Obtén el emisor OIDC de tu clúster de Kubernetes:

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

Aunque cargues el JWKS y OpenAI no realice el descubrimiento de JWKS a través del emisor OIDC, este emisor debe coincidir con el configurado en el proveedor de identidad de carga de trabajo.

Obtén el JWKS del clúster y guarda el conjunto de claves devuelto. Lo necesitarás al configurar el proveedor de identidad de carga de trabajo:

kubectl get --raw /openid/v1/jwks

Configura el token proyectado de cuenta de servicio con la audiencia que espera OpenAI y un vencimiento adecuado para tu carga de trabajo. OpenAI valida el emisor, la firma, la audiencia y el vencimiento del token. En este ejemplo, el archivo de token se monta en /var/run/secrets/tokens/token, usa la audiencia https://api.openai.com/v1 y vence después de 3600 segundos. Puedes usar otra audiencia siempre que coincidan la audiencia del token proyectado y la del proveedor de identidad de carga de trabajo de OpenAI:

apiVersion: v1
kind: Pod
metadata:
  name: openai-wif-app
  namespace: default
spec:
  serviceAccountName: openai-wif
  containers:
    - name: app
      image: my-image
      volumeMounts:
        - name: ksa-token
          mountPath: /var/run/secrets/tokens
          readOnly: true
  volumes:
    - name: ksa-token
      projected:
        sources:
          - serviceAccountToken:
              path: token
              audience: "https://api.openai.com/v1"
              expirationSeconds: 3600

Verifica el token

Antes de configurar la federación de identidades de carga de trabajo, decodifica localmente un token proyectado de cuenta de servicio de muestra e inspecciona sus declaraciones. Desde un pod en ejecución que tenga montado el token proyectado, obtén el token y expórtalo como TOKEN:

TOKEN=$(kubectl exec -n default openai-wif-app -- cat /var/run/secrets/tokens/token)
export TOKEN

Luego, ejecuta este script:

const parts = process.env.TOKEN?.split(".") ?? [];
if (parts.length !== 3) {
  throw new Error("Expected a compact JWT with three segments");
}
if (!/^[A-Za-z0-9_-]+$/.test(parts[1]) || parts[1].length % 4 === 1) {
  throw new Error("JWT payload is not valid Base64URL");
}

const bytes = Buffer.from(parts[1], "base64url");
if (bytes.toString("base64url") !== parts[1]) {
  throw new Error("JWT payload is not valid Base64URL");
}
const decoded = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
const claims = JSON.parse(decoded);
if (claims === null || Array.isArray(claims) || typeof claims !== "object") {
  throw new Error("JWT payload is not a JSON object");
}
console.log(decoded);

Este comando decodifica el contenido del JWT sin verificar la firma del token. Usa un decodificador local para los tokens de producción y evita pegarlos en herramientas de terceros.

Un token proyectado de cuenta de servicio de Kubernetes decodificado tendrá un aspecto similar a este:

{
  "iss": "https://kubernetes.example.com",
  "aud": ["https://api.openai.com/v1"],
  "sub": "system:serviceaccount:default:openai-wif",
  "iat": 1716235422,
  "exp": 1716239022,
  "kubernetes.io": {
    "namespace": "default",
    "serviceaccount": {
      "name": "openai-wif",
      "uid": "11111111-2222-3333-4444-555555555555"
    }
  }
}

Usa el contenido decodificado para comparar el token que recibiste con los valores de emisor, audiencia y asignación configurados en OpenAI. La mayoría de los problemas de configuración se pueden detectar en las declaraciones iss, aud y sub antes de intercambiar el token.

Configuración de la federación de identidades de carga de trabajo

Crea un proveedor de identidad de carga de trabajo en OpenAI para el emisor de Kubernetes y luego agrega una asignación de cuenta de servicio que coincida con los atributos del token proyectado.

Primero configura el proveedor de identidad de carga de trabajo y luego crea la asignación de cuenta de servicio.

Configura el proveedor de identidad de carga de trabajo

  1. Crea el proveedor de identidad de carga de trabajo. Establece Nombre en un valor único, como kubernetes-prod. Usa una Descripción, como Production Kubernetes cluster, para ayudar a los administradores a identificar el clúster.

  2. Establece el emisor y la audiencia. Establece URL del emisor OIDC en el emisor devuelto por kubectl get --raw /.well-known/openid-configuration | jq -r .issuer. Este valor debe coincidir con la declaración iss del token proyectado. Establece Audiencia en la misma cadena opaca de audiencia configurada en el volumen del token proyectado de cuenta de servicio. En este ejemplo, ese valor es https://api.openai.com/v1.

  3. Carga el JWKS de Kubernetes. Habilita Usar el JWKS cargado para verificar tokens y luego establece JSON de JWKS en la salida de kubectl get --raw /openid/v1/jwks. OpenAI usa este conjunto de claves públicas para verificar los tokens proyectados de cuentas de servicio de Kubernetes. Carga el conjunto completo de claves, incluido el campo keys que las contiene.

    Nota: para los clústeres de Kubernetes autoalojados, OpenAI solo admite el modo JWKS local. Carga el JWKS devuelto por tu clúster; OpenAI no realiza el descubrimiento OIDC a través del emisor configurado. OpenAI sigue comparando el emisor configurado con el campo iss del token.

    Si tu clúster rota las claves de firma de las cuentas de servicio, actualiza el JWKS cargado en la configuración del proveedor de identidad de carga de trabajo. Los tokens firmados con claves que no estén presentes en el JWKS configurado se rechazan. Si el JWKS contiene varias claves públicas activas, incluye el arreglo keys completo.

  4. Agrega transformaciones de atributos solo si necesitas atributos derivados para la asignación. Las declaraciones originales del token, como sub, aud y iss, se pueden usar directamente en las aserciones de asignación. Si planeas buscar coincidencias con atributos transformados en lugar de las declaraciones originales del token, el panel aplica el prefijo openai. automáticamente; por ejemplo, ingresa workload_subject con la expresión assertion.sub para crear openai.workload_subject. Las declaraciones originales del token que ya comienzan con openai. se ignoran para las claves de asignación openai., a menos que se configure una transformación correspondiente.

Configura la asignación de cuenta de servicio

  1. Crea una asignación de cuenta de servicio. Establece Nombre en un valor único dentro del proveedor de identidad de carga de trabajo, como openai-mapping-kubernetes. Usa una Descripción, como Workload Identity Provider Mapping for Kubernetes Workloads, para explicar qué carga de trabajo puede usar la asignación.

  2. Configura la coincidencia con el sujeto de la cuenta de servicio de Kubernetes. Establece Clave en sub y Valor en system:serviceaccount:default:openai-wif. Para las cuentas de servicio de Kubernetes, el formato del sujeto es system:serviceaccount:<namespace>:<service-account-name>.

  3. Elige el destino en OpenAI. Establece Proyecto en el proyecto de OpenAI al que pertenece la cuenta de servicio de destino. Establece Cuenta de servicio en la cuenta de servicio de OpenAI que puede usar la carga de trabajo de Kubernetes, como kubernetes-prod-openai-wif. Marca Create a new service account in this project si deseas crear una cuenta de servicio nueva para esta asignación en lugar de reutilizar una existente.

  4. Restringe los permisos de la API si es necesario. Selecciona los Permisos adecuados, como api.model.request y api.vector_store.read, para restringir aún más los tokens de acceso emitidos a partir de esta asignación. Deja los permisos en blanco para evitar agregar una restricción de alcance específica de WIF; el token sigue autorizando el acceso como la cuenta de servicio asignada.

Uso del token en el código

Configura tu cliente del SDK de OpenAI para que lea el token proyectado de Kubernetes y lo intercambie por un token de acceso emitido por OpenAI.

Usa la ruta del token montado, como /var/run/secrets/tokens/token, como origen del token de sujeto para el proveedor de federación de identidades de carga de trabajo del SDK. El SDK intercambia ese token de Kubernetes por un token de acceso emitido por OpenAI y usa el token de OpenAI para autenticar las solicitudes a la API.

Los siguientes ejemplos inicializan un cliente de OpenAI con un proveedor personalizado de tokens de sujeto. El proveedor lee el token proyectado de cuenta de servicio de Kubernetes desde la ruta del archivo montado y lo usa como token de sujeto para la federación de identidades de carga de trabajo.

Autenticación con un token proyectado de cuenta de servicio de Kubernetes
import { readFile } from "node:fs/promises";
import OpenAI from "openai";

const tokenPath = "/var/run/secrets/tokens/token";
const identityProviderId = process.env.OPENAI_IDENTITY_PROVIDER_ID;
const serviceAccountId = process.env.OPENAI_SERVICE_ACCOUNT_ID;

if (!identityProviderId || !serviceAccountId) {
  throw new Error(
    "Set OPENAI_IDENTITY_PROVIDER_ID and OPENAI_SERVICE_ACCOUNT_ID"
  );
}

function mountedServiceAccountTokenProvider(path) {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const token = (await readFile(path, "utf8")).trim();
      if (!token) {
        throw new Error("The mounted service account token file is empty.");
      }
      return token;
    },
  };
}

const client = new OpenAI({
  workloadIdentity: {
    identityProviderId,
    serviceAccountId,
    provider: mountedServiceAccountTokenProvider(tokenPath),
  },
});

const response = await client.responses.create({
  model: "gpt-5.6-terra",
  input: "Say hello from Kubernetes workload identity federation.",
});

console.log(response.output_text);

Prácticas recomendadas de Kubernetes

  • Usa un emisor OIDC estable. La URL del emisor debe coincidir con la declaración iss del token proyectado de cuenta de servicio y debería mantenerse estable durante las actualizaciones del clúster y las operaciones de mantenimiento.
  • Protege cuidadosamente las claves de firma. Cualquier persona con acceso a las claves de firma de las cuentas de servicio del clúster puede emitir tokens que OpenAI podría aceptar.
  • Usa cuentas de servicio dedicadas para las integraciones con OpenAI. Evita reutilizar cuentas de servicio que también se usen para acceder a infraestructura o aplicaciones no relacionadas.
  • Mantén actualizado el JWKS cargado. OpenAI usa el JWKS configurado para validar los tokens de identidad de carga de trabajo en el modo JWKS local, así que actualiza el proveedor de identidad de carga de trabajo antes de rotar a nuevas claves de firma.
  • Minimiza la complejidad de las declaraciones personalizadas. Da preferencia a las coincidencias con declaraciones estándar, como sub y aud, o con atributos transformados derivados directamente de esas declaraciones.
  • Considera la titularidad de los espacios de nombres como parte de tu modelo de seguridad. Si los administradores de los espacios de nombres pueden crear cuentas de servicio, asegúrate de que las asignaciones tengan un alcance adecuado para evitar una escalada de privilegios no intencional.
  • Monitorea los cambios de emisor y de claves de firma. Rotar las claves de firma sin actualizar el JWKS del proveedor de identidad de carga de trabajo puede provocar fallas en el intercambio de tokens.