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 charges de travail pour Idira

Utilisez Idira Secure Workload Access (SWA) pour appeler l’API OpenAI sans stocker de clé API OpenAI. SWA attribue un identifiant SPIFFE à votre charge de travail et émet un JWT-SVID, un jeton signé qui représente cette identité. Le SDK OpenAI échange ce jeton contre un jeton d’accès OpenAI de courte durée qui confère les autorisations du compte de service associé.

Ce guide explique comment configurer l’API OpenAI. Pour Codex, suivez les étapes de ce guide pour fournir le jeton à la charge de travail, puis suivez les instructions de la section Utilisation d’une identité de charge de travail avec Codex.

Avant de commencer

Vous devez disposer des éléments suivants :

  • Un déploiement SWA avec un domaine de confiance et une politique d’attestation qui attribue l’identifiant SPIFFE attendu à votre charge de travail.
  • Un accès, depuis la charge de travail, au socket de la Workload API de l’agent SWA.
  • Les autorisations nécessaires pour gérer les fournisseurs d’identités de charges de travail, les associations de comptes de service, les projets et les comptes de service dans votre organisation OpenAI.
  • Un SDK OpenAI qui prend en charge les informations d’identification des charges de travail.

Terminez la configuration de l’infrastructure SWA en suivant les prérequis indiqués dans le guide d’Idira sur l’intégration avec OpenAI.

Récupérez l’URL de l’émetteur et les clés de signature

Récupérez les valeurs de jwt.discovery_endpoints.oidc_discovery_url et de jwt.discovery_endpoints.jwks_uri pour votre domaine de confiance. Pour les trouver, suivez les instructions d’Idira pour la configuration OIDC.

OpenAI doit pouvoir accéder au document de découverte et au jeu de clés JWKS via HTTPS sans authentification. L’URL HTTPS figurant dans le champ iss du jeton indique l’émetteur. L’identifiant SPIFFE figurant dans sub identifie votre charge de travail.

Choisissez une audience réservée à l’accès à OpenAI, par exemple https://api.openai.com/v1. Utilisez la même valeur lorsque vous demandez le JWT-SVID et lorsque vous configurez le fournisseur dans OpenAI. L’audience indique le destinataire prévu du jeton. Elle ne définit pas le point de terminaison utilisé pour l’échange de jetons.

Par défaut, SWA signe les jetons avec RS512 et une clé RSA de 4 096 bits. Le vérificateur de JWT d’OpenAI accepte cette combinaison. Pour connaître les autres options de signature de SWA, consultez les exigences d’Idira relatives aux JWT.

Fournissez un JWT-SVID à jour à la charge de travail

Installez spiffe-helper dans l’environnement de la charge de travail pour demander un JWT-SVID à l’agent SWA et le renouveler. Enregistrez la configuration suivante dans helper.conf. L’utilitaire écrit le jeton dans /var/run/spiffe/openai.jwt, le chemin utilisé dans les exemples de code du SDK communs aux intégrations SPIFFE :

agent_address = "/tmp/swa-agent/public/api.sock"
cert_dir      = "/var/run/spiffe"
daemon_mode   = true

jwt_svids = [{
  jwt_audience       = "https://api.openai.com/v1"
  jwt_svid_file_name = "openai.jwt"
}]

Dans Kubernetes, exécutez l’utilitaire dans un conteneur sidecar du pod de la charge de travail. Partagez un volume emptyDir en mémoire monté sur /var/run/spiffe et montez le répertoire parent du socket SWA, /tmp/swa-agent/public, dans le conteneur de l’utilitaire. Sur une machine virtuelle, utilisez /run/swa-agent/api.sock comme valeur de agent_address et conservez le répertoire du jeton sur un système de fichiers en mémoire. Suivez les instructions de déploiement d’Idira pour l’accès au socket et l’attestation.

Avant de démarrer l’utilitaire, créez le répertoire du jeton et accordez à l’utilitaire le droit d’y écrire. Démarrez l’utilitaire avec cette configuration dans le conteneur sidecar ou dans le service de la machine virtuelle :

spiffe-helper -config helper.conf

Réservez l’accès au fichier du jeton et au socket de l’agent aux processus qui en ont besoin. Laissez l’utilitaire s’exécuter pour qu’il remplace le jeton avant son expiration.

Si votre langage dispose d’un client pour la Workload API de SPIFFE, vous pouvez aussi récupérer un nouveau JWT-SVID directement dans le fournisseur de jetons de sujet. Consultez l’option d’accès direct à la Workload API dans le guide d’intégration d’Idira.

Inspectez le jeton

Depuis la charge de travail, chargez le jeton dans l’environnement du décodeur local :

export TOKEN="$(cat /var/run/spiffe/openai.jwt)"
const parts = process.env.TOKEN?.split(".") ?? [];
if (parts.length !== 3) {
  throw new Error("Expected a compact JWT with three segments");
}

const decode = (segment) => {
  if (!/^[A-Za-z0-9_-]+$/.test(segment) || segment.length % 4 === 1) {
    throw new Error("JWT segment is not valid Base64URL");
  }
  const bytes = Buffer.from(segment, "base64url");
  if (bytes.toString("base64url") !== segment) {
    throw new Error("JWT segment is not valid Base64URL");
  }
  const decoded = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
  const value = JSON.parse(decoded);
  if (value === null || Array.isArray(value) || typeof value !== "object") {
    throw new Error("JWT segment is not a JSON object");
  }
  return decoded;
};

console.log("Header:");
console.log(decode(parts[0]));
console.log("\nPayload:");
console.log(decode(parts[1]));

Vérifiez les champs suivants avant de créer le fournisseur dans OpenAI :

Champ Valeur attendue
Champ d’en-tête alg L’algorithme de signature configuré, par exemple RS512.
Champ d’en-tête kid L’identifiant d’une clé de signature figurant dans le JWKS public du domaine de confiance.
iss L’URL HTTPS de l’émetteur du domaine de confiance.
sub L’identifiant SPIFFE attribué à cette charge de travail.
aud Contient l’audience choisie pour l’accès à OpenAI.
iat et exp Les horodatages d’émission et d’expiration du jeton. Utilisez un jeton qui n’a pas encore expiré.

Le décodeur lit les champs du jeton sans en vérifier la signature. N’enregistrez pas le jeton dans les journaux et ne le collez pas dans un décodeur en ligne. Supprimez la variable d’environnement TOKEN après l’inspection.

Configurez la fédération d’identités de charges de travail dans OpenAI

Créez le fournisseur d’identités de charges de travail

Ouvrez Paramètres de l’organisation > Sécurité > Fournisseur d’identités de charges de travail et créez un fournisseur avec les paramètres suivants :

Paramètre Valeur
Nom Un nom unique, par exemple idira-prod.
Description L’application et l’environnement qui utilisent ce fournisseur.
URL de l’émetteur OIDC La valeur du champ iss du JWT-SVID.
Audience L’audience demandée par l’utilitaire, par exemple https://api.openai.com/v1.
Utiliser un JWKS importé pour vérifier les jetons Laissez cette option désactivée pour utiliser la découverte OIDC.
Transformations d’attributs Laissez ce champ vide si vous associez le compte de service directement à partir de sub.

Lors de l’échange de jetons, l’API OpenAI ignore les barres obliques finales lorsqu’elle compare les URL des émetteurs. Par exemple, https://issuer.example.com et https://issuer.example.com/ sont équivalentes. Tous les autres caractères doivent correspondre, y compris dans le schéma et le chemin de l’URL. Les valeurs d’audience doivent correspondre exactement. Copiez l’URL de l’émetteur telle qu’elle figure dans le jeton pour que votre configuration reste cohérente.

Si OpenAI ne peut pas accéder au document de découverte ou au JWKS, suivez les instructions communes de configuration des fournisseurs pour importer un JWKS public. Mettez à jour les clés importées lorsque SWA renouvelle ses clés de signature.

Associez l’identifiant SPIFFE à un compte de service

  1. Dans le fournisseur, créez une association de compte de service et donnez-lui un nom, par exemple idira-production-workload.
  2. Dans Clé, saisissez sub. Dans Valeur, saisissez l’identifiant SPIFFE exact figurant dans le jeton de la charge de travail, par exemple spiffe://prod.example.com/k8s-nodegroup/ns/my-namespace/sa/my-service-account.
  3. Sélectionnez le Projet et le Compte de service que la charge de travail peut utiliser.
  4. Sélectionnez les Autorisations nécessaires à la charge de travail, par exemple api.model.request pour les requêtes adressées aux modèles. Ces autorisations peuvent restreindre les droits d’accès du compte de service, mais elles ne peuvent pas les étendre. Si vous laissez ce champ vide, la fédération d’identités de charges de travail n’ajoute aucune restriction.

Utilisez un compte de service distinct pour chaque application et chaque environnement. Privilégiez un identifiant SPIFFE exact. N’ajoutez un caractère générique à la fin d’un préfixe que si toutes les identités commençant par ce préfixe doivent bénéficier des mêmes droits d’accès. Évitez les associations qui se chevauchent. Pour en savoir plus, consultez la section Associations entre identifiants SPIFFE et comptes de service.

Utilisez le jeton dans votre code

Dans l’environnement de la charge de travail, définissez les identifiants de votre fournisseur OpenAI et du compte de service sélectionné :

export OPENAI_IDENTITY_PROVIDER_ID="<workload identity provider ID>"
export OPENAI_SERVICE_ACCOUNT_ID="<service account ID>"

Les exemples suivants, communs aux intégrations SPIFFE, lisent le jeton dans /var/run/spiffe/openai.jwt. Le fournisseur de jetons de sujet renvoie le jeton en cours chaque fois que le SDK doit effectuer un échange pour obtenir ou renouveler un jeton d’accès OpenAI. SWA et l’utilitaire renouvellent le JWT-SVID externe. Le SDK OpenAI gère le jeton d’accès OpenAI.

Authentification avec un JWT-SVID SPIFFE émis par Idira
import { readFile } from "node:fs/promises";
import OpenAI from "openai";

const tokenPath = "/var/run/spiffe/openai.jwt";
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 spiffeJwtSvidProvider(path) {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const token = (await readFile(path, "utf8")).trim();
      if (!token) {
        throw new Error("The SPIFFE JWT-SVID file is empty.");
      }
      return token;
    },
  };
}

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

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

console.log(response.output_text);

Vérifiez le fonctionnement et résolvez les problèmes

Exécutez l’exemple depuis la charge de travail attestée, en veillant à ce que la variable OPENAI_API_KEY ne soit pas définie. Si la requête aboutit, l’exemple affiche la réponse du modèle. Vérifiez que les requêtes continuent d’aboutir après le remplacement du JWT-SVID par l’utilitaire et le renouvellement du jeton d’accès OpenAI par le SDK.

Symptôme Vérifications à effectuer
L’utilitaire ne reçoit aucune identité Vérifiez que la charge de travail répond aux critères de la politique d’attestation SWA et qu’elle peut accéder au socket de l’agent. Effectuez ces vérifications dans le contexte de la charge de travail.
Le fichier du jeton est absent ou vide, ou le jeton qu’il contient a expiré Vérifiez que l’utilitaire est en cours d’exécution, que le volume partagé et le chemin du fichier correspondent à la configuration et que la charge de travail peut lire le fichier. Maintenez les horloges des hôtes synchronisées.
La vérification du jeton échoue Vérifiez iss, aud, kid et la date d’expiration du jeton. Vérifiez aussi que le document de découverte et le JWKS sont accessibles. Appliquez la règle de comparaison des URL des émetteurs décrite plus haut.
Aucune association de compte de service ne correspond Vérifiez l’identifiant du fournisseur, l’identifiant du compte de service, l’activation de l’association et la valeur exacte de sub.
Plusieurs associations correspondent Rendez les critères des associations qui se chevauchent plus précis ou désactivez certaines de ces associations pour qu’une seule association active corresponde.
L’échange aboutit, mais l’API rejette la requête Vérifiez le projet du compte de service associé, ses autorisations et les politiques d’accès à l’API qui s’appliquent.

Pour diagnostiquer les problèmes de déploiement de SWA, consultez les instructions de dépannage de l’intégration d’Idira.