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 GitHub Actions

Utilisez GitHub Actions comme fournisseur d’identités de charge de travail en échangeant un token OIDC émis par GitHub contre un jeton d’accès OpenAI à courte durée de vie. Les workflows peuvent ainsi s’authentifier auprès de l’API OpenAI sans stocker de clé API à longue durée de vie dans les secrets GitHub.

Pour Codex, suivez cette page pour obtenir et inspecter le token GitHub. Ensuite, configurez l’identité de charge de travail de Codex pour écrire ce token dans un fichier et indiquer ce fichier à Codex. Le mappage de compte de service et les exemples de SDK de cette page concernent l’API OpenAI.

GitHub peut émettre un JWT OIDC signé pour un job de workflow qui dispose de l’autorisation id-token: write et demande un token d’identité. OpenAI valide l’émetteur, l’audience et la signature du token, ainsi que les attributs de mappage, avant d’émettre un jeton d’accès OpenAI.

Configuration de GitHub Actions

Accordez au workflow ou au job l’autorisation de demander un token OIDC GitHub :

permissions:
  id-token: write
  contents: read

L’autorisation id-token: write permet au job de demander un JWT OIDC. Elle n’accorde pas d’accès en écriture au contenu du dépôt. L’autorisation contents: read est nécessaire pour actions/checkout.

Demandez le token avec exactement l’audience configurée dans votre fournisseur d’identités de charge de travail OpenAI. Les actions JavaScript personnalisées peuvent appeler core.getIDToken("your-wif-audience") ; les étapes shell peuvent appeler directement l’URL de requête OIDC de GitHub. Les valeurs d’audience contenant des caractères réservés dans les URL, comme https://api.openai.com/v1, doivent être encodées pour les URL avant d’être ajoutées à l’URL de requête :

AUDIENCE="https://api.openai.com/v1"
ENCODED_AUDIENCE=$(jq -rn --arg audience "$AUDIENCE" '$audience | @uri')

TOKEN=$(curl -sSf -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
  "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${ENCODED_AUDIENCE}" | jq -r .value)
export TOKEN

Les principales revendications OIDC de GitHub comprennent :

  • iss : l’émetteur du token. Pour GitHub Actions, il s’agit de https://token.actions.githubusercontent.com.
  • aud : la valeur d’audience demandée par le workflow. Configurez OpenAI pour exiger exactement la valeur que vous demandez, comme your-wif-audience ou https://api.openai.com/v1.
  • sub : la chaîne principale du sujet. GitHub la construit à partir des métadonnées du workflow, comme le dépôt, la branche, le tag, la pull request ou l’environnement.
  • repository : le dépôt qui exécute le workflow, comme my-org/my-repo.
  • repository_owner : l’organisation ou l’utilisateur propriétaire du dépôt, comme my-org.
  • ref : la référence Git qui a déclenché le workflow, comme refs/heads/main ou refs/tags/v1.0.0.
  • workflow : la revendication du workflow. Utilisez la valeur réellement émise par GitHub, par exemple deploy si c’est la valeur de cette revendication dans votre job.
  • workflow_ref : le chemin du fichier de workflow et sa référence, comme my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main.
  • environment : le nom de l’environnement GitHub, comme production, lorsque le job utilise un environnement.
  • run_id, run_number, run_attempt et job_workflow_ref : des identifiants d’exécution et de job qui peuvent faciliter les audits ou la définition de règles de confiance plus avancées.

Pour connaître la liste complète des revendications et les formats du sujet, consultez la référence OpenID Connect de GitHub.

Vérifiez le token

Avant de configurer la fédération d’identités de charge de travail, exportez le token OIDC GitHub dans TOKEN, puis exécutez ce script sur le runner du workflow pour inspecter ses revendications :

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. Ne consignez jamais dans les journaux le token OIDC GitHub brut ni le jeton d’accès OpenAI obtenu en échange.

Un token OIDC GitHub Actions décodé ressemble à ceci :

{
  "iss": "https://token.actions.githubusercontent.com",
  "aud": "https://api.openai.com/v1",
  "sub": "repo:my-org/my-repo:environment:production",
  "repository": "my-org/my-repo",
  "repository_owner": "my-org",
  "ref": "refs/heads/main",
  "workflow": "deploy",
  "workflow_ref": "my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main",
  "environment": "production",
  "run_id": "1234567890",
  "run_attempt": "1"
}

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, repository, ref et workflow_ref avant l’échange du 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 GitHub Actions, puis ajoutez un mappage de compte de service correspondant aux revendications de workflow GitHub auxquelles vous faites confiance.

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. Définissez Nom sur une valeur unique, comme github-actions-prod. Renseignez Description, par exemple avec Production GitHub Actions workflows, pour aider les administrateurs à identifier le fournisseur.

  2. Définissez l’émetteur et l’audience. Définissez URL de l’émetteur OIDC sur https://token.actions.githubusercontent.com. Définissez Audience sur exactement l’audience demandée par votre workflow, comme your-wif-audience ou https://api.openai.com/v1.

  3. Utilisez la découverte OIDC de GitHub. Laissez l’option Utiliser le JWKS importé pour vérifier les tokens désactivée. OpenAI utilise les métadonnées de découverte OIDC et le JWKS de GitHub pour vérifier le token signé par GitHub.

  4. N’ajoutez des transformations d’attributs que si vous avez besoin d’attributs de mappage dérivés. Les revendications GitHub brutes comme repository, ref et workflow peuvent être utilisées directement dans les assertions de mappage. Si vous créez des attributs dérivés, le tableau de bord applique automatiquement le préfixe openai. ; par exemple, saisissez github_repository avec l’expression assertion.repository pour créer openai.github_repository. 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. Définissez Nom sur une valeur unique au sein du fournisseur d’identités de charge de travail, comme github-actions-main-deploy. Renseignez Description, par exemple avec Production deploy workflow on main, pour expliquer quel workflow peut utiliser ce mappage.

  2. Ajoutez des assertions de correspondance exacte des revendications. Ajoutez une ligne Clé et Valeur pour chaque revendication GitHub à vérifier. OpenAI exige que chaque ligne configurée corresponde avant d’émettre un jeton d’accès. Pour un workflow de déploiement en production, utilisez des assertions comme celles-ci :

    iss == "https://token.actions.githubusercontent.com"
    aud == "https://api.openai.com/v1"
    repository == "my-org/my-repo"
    ref == "refs/heads/main"
    workflow_ref == "my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main"

    Privilégiez workflow_ref plutôt que workflow pour les mappages accordant des privilèges élevés, car les administrateurs souhaitent généralement faire confiance à un chemin de fichier de workflow et à une référence précis. Les workflows peuvent être renommés et plusieurs fichiers de workflow peuvent partager le même nom.

    Dans l’interface de mappage, saisissez ces éléments sous forme de lignes clé/valeur, par exemple Clé repository avec Valeur my-org/my-repo, Clé ref avec Valeur refs/heads/main, et Clé workflow_ref avec Valeur my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main. Si le job utilise un environnement GitHub, ajoutez également Clé environment avec Valeur production.

    Attention : évitez les mappages trop larges, par exemple ceux qui ne vérifient que repository_owner == "my-org", sauf si tous les dépôts de l’espace de noms de ce propriétaire doivent pouvoir obtenir des jetons d’accès OpenAI.

  3. Choisissez la cible OpenAI. Dans Projet , sélectionnez le projet OpenAI auquel appartient le compte de service cible. Dans Compte de service , sélectionnez le compte de service OpenAI que le workflow GitHub peut utiliser, comme github-actions-prod-deploy.

  4. Restreignez les autorisations de l’API si nécessaire. Sélectionnez les Autorisations appropriées, comme api.model.request et api.vector_store.read, pour limiter 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 à WIF ; le token continue d’accorder les droits du compte de service associé.

Utilisation du token dans un workflow

Configurez votre client du SDK OpenAI pour demander un token OIDC GitHub et l’échanger contre un jeton d’accès émis par OpenAI.

Le workflow doit accorder l’autorisation id-token: write et transmettre les paramètres de fédération d’identités de charge de travail au code utilisant le SDK. Le SDK demande le token OIDC GitHub à l’aide des variables d’environnement ACTIONS_ID_TOKEN_REQUEST_URL et ACTIONS_ID_TOKEN_REQUEST_TOKEN que GitHub met à la disposition du job, puis utilise le jeton d’accès OpenAI obtenu en échange pour authentifier les requêtes API.

Par exemple, exécutez le code de votre application depuis un workflow comme celui-ci :

name: deploy

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Run OpenAI SDK code
        env:
          OPENAI_WIF_AUDIENCE: ${{ vars.OPENAI_WIF_AUDIENCE }}
          OPENAI_IDENTITY_PROVIDER_ID: ${{ vars.OPENAI_IDENTITY_PROVIDER_ID }}
          OPENAI_SERVICE_ACCOUNT_ID: ${{ vars.OPENAI_SERVICE_ACCOUNT_ID }}
        run: node ./scripts/call-openai.js

Stockez OPENAI_WIF_AUDIENCE, OPENAI_IDENTITY_PROVIDER_ID et OPENAI_SERVICE_ACCOUNT_ID en tant que variables GitHub Actions. Ces valeurs identifient le fournisseur et le compte de service, mais ne constituent pas des identifiants d’authentification au porteur.

Les exemples suivants initialisent un client OpenAI avec un fournisseur personnalisé de tokens de sujet. Ce fournisseur demande un token OIDC GitHub pour l’audience configurée et l’utilise comme token de sujet pour la fédération d’identités de charge de travail.

Authentification à partir d’un token OIDC GitHub Actions
import OpenAI from "openai";

const identityProviderId = process.env.OPENAI_IDENTITY_PROVIDER_ID;
const serviceAccountId = process.env.OPENAI_SERVICE_ACCOUNT_ID;
const audience = process.env.OPENAI_WIF_AUDIENCE;
const requestURL = process.env.ACTIONS_ID_TOKEN_REQUEST_URL;
const requestToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;

if (
  !identityProviderId ||
  !serviceAccountId ||
  !audience ||
  !requestURL ||
  !requestToken
) {
  throw new Error(
    "Set OPENAI_IDENTITY_PROVIDER_ID, OPENAI_SERVICE_ACCOUNT_ID, OPENAI_WIF_AUDIENCE, and run inside GitHub Actions with id-token: write"
  );
}

function githubActionsOIDCTokenProvider(requestURL, requestToken, audience) {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const url = new URL(requestURL);
      url.searchParams.set("audience", audience);

      const response = await fetch(url, {
        headers: { Authorization: `bearer ${requestToken}` },
      });

      if (!response.ok) {
        throw new Error(
          `Failed to request GitHub OIDC token: ${response.status} ${response.statusText}`
        );
      }

      const body = await response.json();
      if (!body.value) {
        throw new Error("GitHub OIDC token response did not include a value.");
      }

      return body.value;
    },
  };
}

const client = new OpenAI({
  workloadIdentity: {
    identityProviderId,
    serviceAccountId,
    provider: githubActionsOIDCTokenProvider(
      requestURL,
      requestToken,
      audience
    ),
  },
});

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

console.log(response.output_text);

Bonnes pratiques pour GitHub Actions

  • Utilisez les protections d’environnement pour les déploiements en production. Exigez des approbations ou des restrictions de branche avant que les workflows puissent accéder aux ressources OpenAI de production.
  • Restreignez les mappages par dépôt. Vérifiez autant que possible des revendications propres au dépôt plutôt que d’autoriser l’accès depuis tous les dépôts d’une organisation.
  • Restreignez les mappages par branche ou par workflow. Envisagez de vérifier des revendications comme repository, ref, environment ou workflow_ref pour limiter l’émission de tokens.
  • Utilisez des comptes de service OpenAI distincts pour les charges de travail de CI/CD et de production. Les pipelines de build nécessitent souvent des autorisations différentes de celles des applications déployées.
  • Évitez d’accorder l’accès aux pull requests provenant de dépôts forkés non fiables. Les pull requests provenant de dépôts forkés peuvent exécuter du code contrôlé par un attaquant et ne doivent pas recevoir d’identifiants d’authentification de production.
  • Privilégiez les échanges à courte durée de vie. Les tokens OIDC GitHub sont destinés à une authentification éphémère et ne doivent être échangés qu’en cas de besoin.
  • Auditez les changements de propriétaire des dépôts. Les transferts, les changements de nom et les modifications d’autorisations des dépôts peuvent remettre en cause les hypothèses de sécurité sur lesquelles reposent les mappages existants.
  • Privilégiez la correspondance exacte des revendications. Vérifiez des revendications comme repository, ref et environment plutôt que de vous appuyer sur des relations de confiance à l’échelle de l’organisation.