For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navigation principale

Configuration de la fédération d’identités de charge de travail pour Kubernetes

Utilisez Kubernetes comme fournisseur d’identités de charge de travail en échangeant un token de compte de service Kubernetes projeté contre un jeton d’accès OpenAI de courte durée.

Pour Codex, suivez cette page pour obtenir et examiner le token projeté. Ensuite, configurez l’identité de charge de travail de Codex pour indiquer à Codex le fichier de token monté. Le mappage de compte de service et les exemples de SDK de cette page s’appliquent à l’API OpenAI.

Configuration de Kubernetes

Ce guide suppose que la projection de tokens de compte de service Kubernetes est activée, ce qui est le cas par défaut dans les versions récentes de Kubernetes. La fédération d’identités de charge de travail OpenAI nécessite des tokens de compte de service projetés compatibles avec OIDC. Les anciens tokens de compte de service Kubernetes stockés dans des Secrets ne sont pas pris en charge.

Utilisez un ServiceAccount Kubernetes pour la charge de travail qui doit appeler l’API OpenAI. Si vous n’en avez pas encore, créez-en un :

kubectl create serviceaccount openai-wif --namespace default

Récupérez l’émetteur OIDC de votre cluster Kubernetes :

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

Même si vous importez le JWKS et qu’OpenAI n’effectue pas de découverte JWKS auprès de l’émetteur OIDC, cet émetteur doit correspondre à celui configuré dans le fournisseur d’identités de charge de travail.

Récupérez le JWKS du cluster et enregistrez le jeu de clés renvoyé. Vous en aurez besoin pour configurer le fournisseur d’identités de charge de travail :

kubectl get --raw /openid/v1/jwks

Configurez le token de compte de service projeté avec l’audience attendue par OpenAI et une durée de validité adaptée à votre charge de travail. OpenAI valide l’émetteur, la signature, l’audience et l’expiration du token. Dans cet exemple, le fichier de token est monté à l’emplacement /var/run/secrets/tokens/token, utilise l’audience https://api.openai.com/v1 et expire au bout de 3600 secondes. Vous pouvez utiliser une autre audience à condition que l’audience du token projeté corresponde à celle du fournisseur d’identités de charge de travail 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

Vérifiez le token

Avant de configurer la fédération d’identités de charge de travail, décodez localement un exemple de token de compte de service projeté et examinez ses revendications. Depuis un pod en cours d’exécution dans lequel le token projeté est monté, récupérez le token et exportez-le dans TOKEN :

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

Exécutez ensuite ce 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);

Cette commande décode la charge utile du JWT sans vérifier la signature du token. Utilisez un décodeur local pour les tokens de production et évitez de les coller dans des outils tiers.

Une fois décodé, un token de compte de service Kubernetes projeté ressemble à ceci :

{
  "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"
    }
  }
}

Utilisez la charge utile décodée pour comparer le token reçu aux valeurs d’émetteur, d’audience et de mappage configurées dans OpenAI. La plupart des problèmes de configuration sont visibles dans les revendications iss, aud et sub avant même d’échanger le token.

Configuration de la fédération d’identités de charge de travail

Créez un fournisseur d’identités de charge de travail dans OpenAI pour l’émetteur Kubernetes, puis ajoutez un mappage de compte de service qui correspond aux attributs du token projeté.

Configurez d’abord le fournisseur d’identités de charge de travail, puis créez le mappage de compte de service.

Configurez le fournisseur d’identités de charge de travail

  1. Créez le fournisseur d’identités de charge de travail. Renseignez le champ Nom avec une valeur unique, par exemple kubernetes-prod. Renseignez le champ Description, par exemple avec Production Kubernetes cluster, pour aider les administrateurs à identifier le cluster.

  2. Définissez l’émetteur et l’audience. Renseignez le champ URL de l’émetteur OIDC avec l’émetteur renvoyé par kubectl get --raw /.well-known/openid-configuration | jq -r .issuer. Cette valeur doit correspondre à la revendication iss du token projeté. Renseignez le champ Audience avec la même chaîne d’audience opaque que celle configurée sur le volume du token de compte de service projeté. Dans cet exemple, cette valeur est https://api.openai.com/v1.

  3. Importez le JWKS de Kubernetes. Activez Utiliser le JWKS importé pour vérifier les tokens, puis renseignez le champ JSON du JWKS avec la sortie de kubectl get --raw /openid/v1/jwks. OpenAI utilise ce jeu de clés publiques pour vérifier les tokens de compte de service Kubernetes projetés. Importez le jeu de clés complet, y compris le champ keys qui les contient.

    Remarque : Pour les clusters Kubernetes autohébergés, OpenAI prend uniquement en charge le mode JWKS local. Importez le JWKS renvoyé par votre cluster ; OpenAI n’effectue pas de découverte OIDC auprès de l’émetteur configuré. OpenAI compare néanmoins l’émetteur configuré au champ iss du token.

    Si votre cluster effectue une rotation des clés de signature des comptes de service, mettez à jour le JWKS importé dans la configuration du fournisseur d’identités de charge de travail. Les tokens signés avec des clés absentes du JWKS configuré sont rejetés. Si le JWKS contient plusieurs clés publiques actives, incluez le tableau keys complet.

  4. Ajoutez des transformations d’attributs uniquement si vous avez besoin d’attributs dérivés pour le mappage. Les revendications brutes du token, telles que sub, aud et iss, peuvent être utilisées directement dans les assertions de mappage. Si vous prévoyez d’établir la correspondance à partir d’attributs transformés plutôt que de revendications brutes du token, le tableau de bord applique automatiquement le préfixe openai. ; par exemple, saisissez workload_subject avec l’expression assertion.sub pour créer openai.workload_subject. Les revendications brutes du token qui commencent déjà par openai. sont ignorées pour les clés de mappage openai., sauf si une transformation correspondante est configurée.

Configurez le mappage de compte de service

  1. Créez un mappage de compte de service. Renseignez le champ Nom avec une valeur unique au sein du fournisseur d’identités de charge de travail, par exemple openai-mapping-kubernetes. Renseignez le champ Description, par exemple avec Workload Identity Provider Mapping for Kubernetes Workloads, pour expliquer quelle charge de travail peut utiliser le mappage.

  2. Définissez la correspondance avec le sujet du compte de service Kubernetes. Renseignez le champ Clé avec sub et le champ Valeur avec system:serviceaccount:default:openai-wif. Pour les comptes de service Kubernetes, le format du sujet est system:serviceaccount:<namespace>:<service-account-name>.

  3. Choisissez la cible OpenAI. Dans le champ Projet , sélectionnez le projet OpenAI auquel appartient le compte de service cible. Dans le champ Compte de service , sélectionnez le compte de service OpenAI que la charge de travail Kubernetes peut utiliser, par exemple kubernetes-prod-openai-wif. Cochez Create a new service account in this project si vous souhaitez créer un compte de service pour ce mappage plutôt que réutiliser un compte existant.

  4. Restreignez les autorisations de l’API si nécessaire. Sélectionnez les Autorisations appropriées, telles que api.model.request et api.vector_store.read, pour restreindre davantage les droits des jetons d’accès émis à partir de ce mappage. Laissez les autorisations vides pour ne pas ajouter de restriction de portée propre à la WIF ; le token continue d’accorder les droits du compte de service associé par le mappage.

Utilisation du token dans le code

Configurez votre client du SDK OpenAI pour lire le token Kubernetes projeté et l’échanger contre un jeton d’accès émis par OpenAI.

Utilisez le chemin du token monté, par exemple /var/run/secrets/tokens/token, comme source du token de sujet pour le fournisseur de fédération d’identités de charge de travail du SDK. Le SDK échange ce token Kubernetes contre un jeton d’accès émis par OpenAI et utilise le token OpenAI pour authentifier les requêtes API.

Les exemples suivants initialisent un client OpenAI avec un fournisseur personnalisé de tokens de sujet. Ce fournisseur lit le token de compte de service Kubernetes projeté depuis le chemin du fichier monté et l’utilise comme token de sujet pour la fédération d’identités de charge de travail.

Authentifiez-vous à l’aide d’un token de compte de service Kubernetes projeté
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);

Bonnes pratiques pour Kubernetes

  • Utilisez un émetteur OIDC stable. L’URL de l’émetteur doit correspondre à la revendication iss du token de compte de service projeté et devrait rester stable lors des mises à niveau du cluster et des opérations de maintenance.
  • Protégez soigneusement les clés de signature. Toute personne ayant accès aux clés de signature des comptes de service du cluster peut émettre des tokens susceptibles d’être acceptés par OpenAI.
  • Utilisez des comptes de service dédiés aux intégrations OpenAI. Évitez de réutiliser des comptes de service qui servent également à accéder à des infrastructures ou à des applications sans rapport avec ces intégrations.
  • Maintenez le JWKS importé à jour. En mode JWKS local, OpenAI utilise le JWKS configuré pour valider les tokens d’identité de charge de travail. Mettez donc à jour le fournisseur d’identités de charge de travail avant de passer à de nouvelles clés de signature.
  • Limitez la complexité des revendications personnalisées. Privilégiez les correspondances sur des revendications standard telles que sub et aud, ou sur des attributs transformés dérivés directement de ces revendications.
  • Intégrez la propriété des espaces de noms à votre modèle de sécurité. Si les administrateurs d’espaces de noms peuvent créer des comptes de service, veillez à définir une portée appropriée pour les mappages afin d’éviter toute élévation de privilèges involontaire.
  • Surveillez les changements d’émetteur et de clés de signature. Une rotation des clés de signature sans mise à jour du JWKS du fournisseur d’identités de charge de travail peut entraîner des échecs d’échange de tokens.