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

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

GitHub peut émettre un JWT OIDC signé pour une tâche de workflow qui dispose de l’autorisation id-token: write et demande un jeton d’identité. Avant d’émettre un jeton d’accès OpenAI, OpenAI vérifie l’émetteur, l’audience et la signature du jeton, ainsi que les attributs utilisés pour la mise en correspondance.

Configuration de GitHub Actions

Accordez au workflow ou à la tâche l’autorisation de demander un jeton OIDC à GitHub :

permissions:
  id-token: write
  contents: read

L’autorisation id-token: write permet à la tâche de demander un JWT OIDC. Elle ne donne aucun accès en écriture au contenu du dépôt. L’autorisation contents: read est nécessaire pour actions/checkout.

Demandez le jeton en indiquant exactement l’audience configurée pour votre fournisseur d’identités de charge de travail dans OpenAI. Les actions JavaScript personnalisées peuvent appeler core.getIDToken("your-wif-audience"). Les étapes shell peuvent appeler directement l’URL de demande de jeton OIDC de GitHub. Si la valeur de l’audience contient des caractères réservés dans les URL, comme dans https://api.openai.com/v1, appliquez-lui un encodage URL avant de l’ajouter à l’URL de la 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

Voici les principales revendications OIDC de GitHub :

  • iss : l’émetteur du jeton. Pour GitHub Actions, il s’agit de https://token.actions.githubusercontent.com.
  • aud : l’audience demandée par le workflow. Configurez OpenAI pour exiger la valeur exacte que vous demandez, par exemple your-wif-audience ou https://api.openai.com/v1.
  • sub : la chaîne qui identifie le sujet principal. 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 dans lequel le workflow s’exécute, par exemple my-org/my-repo.
  • repository_owner : l’organisation ou l’utilisateur propriétaire du dépôt, par exemple my-org.
  • ref : la référence Git qui a déclenché le workflow, par exemple refs/heads/main ou refs/tags/v1.0.0.
  • workflow : la revendication qui indique le nom du workflow. Utilisez la valeur effectivement émise par GitHub, par exemple deploy si c’est celle qui figure dans le jeton de votre tâche.
  • workflow_ref : le chemin du fichier du workflow et sa référence Git, par exemple my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main.
  • environment : le nom de l’environnement GitHub, par exemple production, lorsque la tâche utilise un environnement.
  • run_id, run_number, run_attempt et job_workflow_ref : des identifiants d’exécution et de tâche utiles pour les audits ou pour définir des règles de confiance plus avancées.

Pour consulter la liste complète des revendications et les formats du sujet, reportez-vous à la référence OpenID Connect de GitHub.

Vérification du jeton

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

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. Pour les jetons de production, utilisez un décodeur local et évitez de les coller dans des outils tiers. Ne consignez jamais dans les journaux le jeton OIDC brut de GitHub ni le jeton d’accès OpenAI obtenu en échange.

Une fois décodé, un jeton OIDC de GitHub Actions 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"
}

À partir de la charge utile décodée, comparez l’émetteur, l’audience et les attributs du jeton reçu aux valeurs configurées dans OpenAI. Avant même d’échanger le jeton, vous pouvez repérer la plupart des problèmes de configuration en examinant les revendications iss, aud, repository, ref et workflow_ref.

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 GitHub Actions, puis ajoutez une règle d’association à un compte de service qui vérifie les revendications des workflows GitHub auxquels vous faites confiance.

Configurez d’abord le fournisseur d’identités de charge de travail, puis créez la règle d’association au 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 github-actions-prod. Renseignez le champ Description, par exemple avec Production GitHub Actions workflows, pour aider les administrateurs à identifier le fournisseur.

  2. Définissez l’émetteur et l’audience. Dans le champ URL de l’émetteur OIDC, saisissez https://token.actions.githubusercontent.com. Dans le champ Audience, saisissez la valeur exacte demandée par votre workflow, par exemple 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 jetons désactivée. OpenAI utilise les métadonnées de découverte OIDC et le JWKS de GitHub pour vérifier le jeton signé par GitHub.

  4. Ajoutez des transformations d’attributs uniquement si votre règle d’association nécessite des attributs dérivés. Vous pouvez utiliser directement les revendications GitHub brutes, comme repository, ref et workflow, dans les assertions de la règle. Si vous créez des attributs dérivés, le tableau de bord ajoute automatiquement le préfixe openai.. Par exemple, saisissez github_repository avec l’expression assertion.repository pour créer openai.github_repository. Si une revendication brute du jeton commence déjà par openai., OpenAI l’ignore pour les clés de la règle préfixées par openai., sauf si vous avez configuré une transformation correspondante.

Configuration de l’association au compte de service

  1. Créez une règle d’association à un compte de service. Dans le champ Nom, saisissez une valeur unique pour ce fournisseur d’identités de charge de travail, par exemple github-actions-main-deploy. Renseignez le champ Description, par exemple avec Production deploy workflow on main, pour préciser quel workflow peut utiliser cette règle.

  2. Ajoutez des assertions qui vérifient la valeur exacte des revendications. Ajoutez une ligne avec les champs Clé et Valeur pour chaque revendication GitHub à vérifier. OpenAI n’émet un jeton d’accès que si chaque ligne configurée correspond à la valeur de la revendication dans le jeton GitHub. 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"

    Pour les règles qui accordent des privilèges élevés, privilégiez workflow_ref par rapport à workflow. Les administrateurs cherchent généralement à n’autoriser qu’un fichier de workflow dont le chemin et la référence Git sont précis. Un workflow peut changer de nom et plusieurs fichiers de workflow peuvent déclarer le même nom.

    Dans l’interface de configuration de la règle, saisissez une paire clé-valeur par ligne. Par exemple, saisissez Clé repository et Valeur my-org/my-repo, puis Clé ref et Valeur refs/heads/main, puis Clé workflow_ref et Valeur my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main. Si la tâche utilise un environnement GitHub, ajoutez aussi Clé environment et Valeur production.

    Attention : Évitez les règles trop larges. Par exemple, ne vous fiez à la seule assertion repository_owner == "my-org" que si tous les dépôts de ce propriétaire doivent pouvoir obtenir des jetons d’accès OpenAI.

  3. Choisissez la cible dans 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 le workflow GitHub peut utiliser, par exemple github-actions-prod-deploy.

  4. Restreignez les autorisations d’accès à 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 associés aux jetons d’accès émis selon cette règle. 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. Le jeton donne alors accès à l’API avec les autorisations du compte de service associé.

Utilisation du jeton dans un workflow

Configurez votre client du SDK OpenAI pour qu’il demande un jeton OIDC à GitHub et l’échange 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 qui utilise le SDK. Pour demander le jeton OIDC à GitHub, le SDK utilise les variables d’environnement ACTIONS_ID_TOKEN_REQUEST_URL et ACTIONS_ID_TOKEN_REQUEST_TOKEN que GitHub met à la disposition de la tâche. Il utilise ensuite le jeton d’accès OpenAI obtenu en échange pour authentifier les requêtes à l’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

Enregistrez OPENAI_WIF_AUDIENCE, OPENAI_IDENTITY_PROVIDER_ID et OPENAI_SERVICE_ACCOUNT_ID comme variables GitHub Actions. Elles identifient le fournisseur et le compte de service, mais ne permettent pas à leur détenteur de s’authentifier.

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

Authentification avec un jeton OIDC de 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

  • Protégez les environnements de déploiement en production. Exigez des approbations ou imposez des restrictions de branche avant d’autoriser les workflows à accéder aux ressources OpenAI de production.
  • Limitez chaque règle d’association à un dépôt. Dans la mesure du possible, vérifiez des revendications propres au dépôt pour éviter d’autoriser l’accès depuis tous les dépôts d’une organisation.
  • Limitez les règles d’association à une branche ou à un workflow. Envisagez de vérifier des revendications comme repository, ref, environment ou workflow_ref pour limiter l’émission de jetons.
  • Utilisez des comptes de service OpenAI distincts pour la CI/CD et les charges de travail de production. Les pipelines de build nécessitent souvent des autorisations différentes de celles des applications déployées.
  • Évitez d’accorder un accès aux pull requests provenant de forks non fiables. Ces pull requests peuvent exécuter du code contrôlé par un attaquant et ne doivent pas recevoir d’identifiants de production.
  • Utilisez des jetons de courte durée pour les échanges. Les jetons OIDC de GitHub sont conçus pour une authentification temporaire. Échangez-les uniquement lorsque vous en avez besoin.
  • Auditez les changements de propriétaire des dépôts. Les transferts de dépôts, les changements de nom et les modifications d’autorisations peuvent remettre en cause les hypothèses de sécurité sur lesquelles reposent les règles d’association existantes.
  • Privilégiez la vérification exacte des revendications. Vérifiez les valeurs de revendications comme repository, ref et environment plutôt que de vous fier à une relation de confiance qui s’étend à toute l’organisation.