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

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 jeton projeté de compte de service Kubernetes contre un jeton d’accès OpenAI de courte durée.

Configuration de Kubernetes

Ce guide suppose que la projection des jetons de compte de service Kubernetes est activée. Cette fonctionnalité est disponible par défaut dans les versions récentes de Kubernetes. La fédération d’identités de charge de travail d’OpenAI exige des jetons projetés de compte de service compatibles avec OIDC. Elle ne prend pas en charge les anciens jetons de compte de service Kubernetes stockés dans des Secrets.

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’URL de 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 ne le recherche pas auprès de l’émetteur OIDC, l’URL de cet émetteur doit correspondre à celle configurée 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 jeton projeté de compte de service avec l’audience attendue par OpenAI et une durée de validité adaptée à votre charge de travail. OpenAI vérifie l’émetteur, la signature, l’audience et la date d’expiration du jeton. Dans cet exemple, le fichier du jeton est monté à l’emplacement /var/run/secrets/tokens/token. Le jeton a pour audience https://api.openai.com/v1 et expire au bout de 3 600 secondes. Vous pouvez choisir une autre audience à condition de configurer la même valeur pour le jeton projeté et pour le fournisseur d’identités de charge de travail dans 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érification du jeton

Avant de configurer la fédération d’identités de charge de travail, décodez localement un exemple de jeton projeté de compte de service et examinez ses revendications. Récupérez le jeton depuis un pod en cours d’exécution dans lequel le fichier du jeton projeté est monté, puis exportez-le dans la variable 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 jeton. Utilisez un décodeur local pour les jetons de production et évitez de les coller dans des outils tiers.

Voici à quoi ressemble un jeton projeté de compte de service Kubernetes une fois décodé :

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

À partir de la charge utile décodée, comparez les valeurs du jeton reçu avec l’émetteur, l’audience et les valeurs de mappage configurés dans OpenAI. Avant d’échanger le jeton, vous pouvez repérer la plupart des erreurs de configuration en examinant les revendications iss, aud et sub.

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

Dans OpenAI, créez un fournisseur d’identités de charge de travail pour l’émetteur Kubernetes, puis ajoutez un mappage de compte de service dont les critères correspondent aux attributs du jeton projeté.

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

Configuration du fournisseur d’identités de charge de travail

  1. Créez le fournisseur d’identités de charge de travail. Dans le champ Nom, saisissez une valeur unique, par exemple kubernetes-prod. Dans le champ Description, saisissez un texte qui aidera les administrateurs à identifier le cluster, par exemple Production Kubernetes cluster.

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

  3. Importez le JWKS de Kubernetes. Activez l’option Utiliser le JWKS importé pour vérifier les jetons, puis collez dans le champ JWKS au format JSON la sortie de kubectl get --raw /openid/v1/jwks. OpenAI utilise ce jeu de clés publiques pour vérifier les jetons projetés de compte de service Kubernetes. Importez le jeu de clés complet, y compris le champ keys qui les contient.

    Remarque : Pour les clusters Kubernetes auto-hé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 toutefois cet émetteur au champ iss du jeton.

    Si votre cluster renouvelle les 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. OpenAI rejette les jetons signés avec des clés absentes du JWKS configuré. Si le JWKS contient plusieurs clés publiques actives, incluez le tableau keys complet.

  4. Ajoutez des transformations d’attributs uniquement si le mappage nécessite des attributs dérivés. Vous pouvez utiliser directement les revendications brutes du jeton, telles que sub, aud et iss, dans les assertions de mappage. Si vous utilisez des attributs transformés comme critères de correspondance à la place des revendications brutes, le tableau de bord ajoute 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 jeton qui commencent déjà par openai. sont ignorées pour les clés de mappage préfixées par openai., sauf si vous configurez une transformation correspondante.

Configuration du mappage de compte de service

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

  2. Utilisez le sujet du compte de service Kubernetes comme critère de correspondance. Dans le champ Clé, saisissez sub. Dans le champ Valeur, saisissez system:serviceaccount:default:openai-wif. Pour les comptes de service Kubernetes, le sujet est au format system:serviceaccount:<namespace>:<service-account-name>.

  3. Choisissez le compte de service OpenAI cible. 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 pourra 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. Limitez les autorisations d’accès à l’API si nécessaire. Dans Autorisations, sélectionnez les autorisations appropriées, par exemple api.model.request et api.vector_store.read, pour restreindre davantage les droits accordés par les jetons d’accès émis via ce mappage. Laissez ce champ vide si vous ne souhaitez pas ajouter de restriction de portée propre à la fédération d’identités de charge de travail. Les droits associés au jeton restent ceux du compte de service défini dans le mappage.

Utilisation du jeton dans le code

Configurez le client du SDK OpenAI pour qu’il lise le jeton projeté Kubernetes et l’échange contre un jeton d’accès émis par OpenAI.

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

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

Authentification avec un jeton projeté de compte de service 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);

Bonnes pratiques pour Kubernetes

  • Utilisez un émetteur OIDC stable. Son URL doit correspondre à la revendication iss du jeton projeté de compte de service 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 jetons qu’OpenAI est susceptible d’accepter.
  • Réservez des comptes de service aux intégrations OpenAI. Évitez de réutiliser des comptes qui donnent également accès à des infrastructures ou à des applications sans rapport avec ces intégrations.
  • Tenez le JWKS importé à jour. En mode JWKS local, OpenAI valide les jetons d’identité de charge de travail à l’aide du JWKS configuré. 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 critères de correspondance fondés sur des revendications standard telles que sub et aud, ou sur des attributs transformés qui en dérivent directement.
  • Tenez compte des droits d’administration des espaces de noms dans votre modèle de sécurité. Si les administrateurs d’espaces de noms peuvent créer des comptes de service, délimitez la portée des mappages pour éviter toute élévation de privilèges involontaire.
  • Surveillez les changements d’émetteur et de clés de signature. Si vous renouvelez les clés de signature sans mettre à jour le JWKS du fournisseur d’identités de charge de travail, l’échange de jetons risque d’échouer.