Français

Exécuter Codex Security dans GitLab CI/CD

Exécutez Codex Security dans GitLab CI/CD pour analyser les modifications enregistrées dans des commits et les branches protégées, publier les résultats dans GitLab Security et, si vous le souhaitez, proposer des correctifs vérifiés dans des demandes de fusion à l’état de brouillon.

Le workflow sépare les identifiants d’analyse de l’accès en écriture au dépôt. Les modifications générées doivent toujours faire l’objet d’une révision humaine avant leur fusion.

Commencez par des rapports d’analyse uniquement. N’activez la correction qu’après avoir vérifié le runner, les résultats et les limites d’utilisation des identifiants pour votre projet.

Avant de commencer

Vous avez besoin des éléments suivants :

  • Un projet GitLab doté d’un runner de confiance prenant en charge l’espace de noms utilisateur du bac à sable Codex.
  • Le rôle Maintainer ou Owner dans le projet GitLab afin de pouvoir configurer les variables CI/CD du projet et les ressources protégées.
  • Une clé API OpenAI avec accès à Codex Security. Les organisations utilisant des clés Platform API peuvent demander l’accès Trusted Access pour Cyber. Les personnes utilisant l’authentification ChatGPT peuvent suivre le processus personnel de Trusted Access. Certains comptes ou dépôts nécessitent cet accès pour les analyses de l’intégralité du dépôt.
  • GitLab Ultimate 19.2 ou version ultérieure pour l’ingestion de fichiers SARIF 2.1.0.
  • L’historique Git complet afin que les tâches des demandes de fusion puissent calculer la base de fusion.

L’image du pipeline installe Node.js 26, Python 3, Git, rg et la version épinglée de Codex Security CLI. La correction automatisée nécessite également un test de régression existant et un runner capable d’exécuter des commandes contrôlées par le dépôt sans identifiants protégés.

Commencer avec un pipeline d’analyse uniquement

Créez une variable GitLab CI/CD protégée, masquée et cachée nommée CODEX_SECURITY_API_KEY. Utilisez une clé API OpenAI Platform avec accès à Codex Security et définissez sa portée d’environnement sur codex-security/openai. Consultez les variables CI/CD à portée d’environnement.

Ajoutez d’abord ce pipeline minimal à un projet de test. Il analyse les modifications enregistrées dans des commits dans les demandes de fusion protégées admissibles, publie le fichier SARIF depuis une tâche de rapport réussie et rétablit le résultat de l’analyse dans un contrôle distinct :

stages:
  - security_scan
  - security_gate

.codex-security-merge-request:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID && $CI_MERGE_REQUEST_SOURCE_BRANCH_PROTECTED == "true" && $CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED == "true"'

codex-security:
  extends: .codex-security-merge-request
  stage: security_scan
  image: node:26-bookworm-slim
  environment:
    name: codex-security/openai
    action: access
  variables:
    GIT_DEPTH: "0"
  before_script:
    - npm install --prefix /tmp/codex-security-cli --ignore-scripts --no-audit --no-fund @openai/codex-security@0.1.20
  script:
    - |
      set -eu
      test -n "${CODEX_SECURITY_API_KEY:-}"

      CODEX_SECURITY_BIN="/tmp/codex-security-cli/node_modules/.bin/codex-security"
      RESULTS_DIR="/tmp/codex-security-results-$CI_JOB_ID"
      ARTIFACT_DIR="codex-security-artifacts"
      BASE_REVISION="$(git merge-base \
        "$CI_MERGE_REQUEST_DIFF_BASE_SHA" "$CI_COMMIT_SHA")"
      install -d -m 700 "$RESULTS_DIR" "$ARTIFACT_DIR/results"

      codex_security_api_key="$CODEX_SECURITY_API_KEY"
      unset CODEX_SECURITY_API_KEY
      set +e
      OPENAI_API_KEY="$codex_security_api_key" \
        "$CODEX_SECURITY_BIN" scan . \
          --diff "$BASE_REVISION" \
          --head "$CI_COMMIT_SHA" \
          --auth api-key \
          --output-dir "$RESULTS_DIR" \
          --json
      scan_exit="$?"
      set -e
      unset codex_security_api_key

      case "$scan_exit" in
        0|1|2) ;;
        *) exit "$scan_exit" ;;
      esac

      "$CODEX_SECURITY_BIN" export "$RESULTS_DIR" \
        --export-format sarif \
        --source-root "$CI_PROJECT_DIR" \
        --output "$ARTIFACT_DIR/results.sarif"
      test -s "$ARTIFACT_DIR/results.sarif"
      cp -R "$RESULTS_DIR"/. "$ARTIFACT_DIR/results/"
      printf '%s\n' "$scan_exit" > "$ARTIFACT_DIR/scan-exit-code.txt"
      exit 0
  artifacts:
    when: always
    access: maintainer
    expire_in: 7 days
    paths:
      - codex-security-artifacts/
    reports:
      sarif: codex-security-artifacts/results.sarif

codex-security-gate:
  extends: .codex-security-merge-request
  stage: security_gate
  image: alpine:3.20
  needs:
    - job: codex-security
      artifacts: true
  script:
    - exit "$(cat codex-security-artifacts/scan-exit-code.txt)"

Examinez chaque modification de .gitlab-ci.yml avant d’exécuter une tâche utilisant des secrets. L’exemple minimal omet volontairement les analyses complètes et les corrections.

Adopter le pipeline de production

  1. Téléchargez le pipeline GitLab complet et enregistrez-le sous .gitlab-ci.yml à la racine du dépôt. Si votre dépôt possède déjà un pipeline, fusionnez les phases, modèles cachés et tâches de l’exemple dans le fichier existant.
  2. Conservez les phases existantes de compilation, de test et de déploiement. Si le projet utilise workflow: rules, vérifiez qu’il autorise les événements de pipeline que vous souhaitez analyser.

L’exemple ajoute les phases security_scan, security_remediation, security_publish et security_gate. Pour produire uniquement des rapports d’analyse, seule la variable CODEX_SECURITY_API_KEY est nécessaire.

Par défaut, la tâche d’analyse s’exécute uniquement pour les demandes de fusion du même projet entre des branches protégées. Définissez CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH=true pour analyser les envois vers la branche par défaut protégée et les pipelines manuels. Définissez CODEX_SECURITY_SCHEDULED_DEEP_SCAN=true et configurez des budgets explicites de temps et de coût pour activer les analyses approfondies planifiées sur la branche par défaut protégée.

Un pipeline de demande de fusion ne peut accéder aux variables et runners protégés que lorsque :

Les pipelines de forks et les demandes de fusion non protégées ne reçoivent pas les identifiants d’analyse. Examinez chaque modification de .gitlab-ci.yml avant d’exécuter une tâche utilisant des secrets. Masquer et cacher une variable ne rend pas sûr du code CI non fiable.

Exécuter une analyse et examiner les résultats

Créez une demande de fusion protégée admissible ou exécutez le pipeline sur la branche par défaut protégée. Commencez par un petit diff avant de lancer une analyse payante de l’intégralité du dépôt.

Ouvrez la tâche codex-security et vérifiez que ses artefacts comprennent :

  • scan-manifest.json
  • findings.json
  • coverage.json
  • results.sarif
  • scan-exit-code.txt

Ouvrez ensuite l’onglet Security du pipeline, examinez les avertissements d’ingestion et vérifiez les identifiants des résultats, les niveaux de gravité et les emplacements dans le code source. Les analyses de la branche par défaut créent également des enregistrements de vulnérabilités dans le projet. Les résultats des demandes de fusion apparaissent dans l’onglet Security du pipeline ou dans le widget de sécurité de la demande de fusion, mais ne créent pas d’enregistrements de vulnérabilités à l’échelle du projet.

Restreignez l’accès aux artefacts, car les résultats d’analyse peuvent contenir des extraits de code source vulnérables, des preuves et des détails de correction.

Choisir un profil d’analyse

Le pipeline sélectionne un profil en fonction du déclencheur :

Déclencheur Cible Mode Effort
Demande de fusion protégée dans le même projet Diff des commits standard low
Envoi facultatif vers la branche par défaut protégée ou lancement manuel Dépôt complet standard high
Planification facultative sur la branche par défaut protégée Dépôt complet deep xhigh

Les analyses de demandes de fusion concentrent les retours sur les modifications enregistrées dans les commits. Les analyses de la branche par défaut examinent le dépôt intégré. Les analyses approfondies planifiées offrent une couverture périodique plus large. Une analyse de diff terminée s’applique uniquement à cette modification et ne démontre pas que l’intégralité du dépôt est exempte de problèmes.

Le workflow installe le CLI hors du dépôt et l’exécute à l’aide de son chemin absolu. La vérification préalable en mode dry-run utilise la clé API limitée au processus, mais ne lance pas d’analyse payante et ne vérifie ni l’authentification à l’API, ni l’accès à Codex Security, ni le quota, ni la disponibilité du modèle.

Le workflow écrit l’état et les résultats de l’analyse hors du worktree et limite OPENAI_API_KEY au processus d’analyse. Le CLI reçoit un environnement restreint et explicite au lieu d’hériter de toutes les variables GitLab. Pour les analyses de diff, le workflow calcule la base de fusion et lie l’analyse aux révisions de base et de tête examinées.

L’exemple épingle @openai/codex-security sur 0.1.20. Testez à nouveau l’authentification, les artefacts, l’ingestion SARIF et le contrôle des politiques avant de modifier cette version.

Séparer les rapports de l’application des politiques

GitLab ingère le fichier SARIF depuis une tâche de rapport réussie. Le pipeline publie d’abord le rapport, puis rétablit le code de sortie de l’analyse dans une tâche codex-security-gate distincte.

La tâche de rapport accepte les résultats associés aux codes de sortie 0 et 1. Elle accepte le code de sortie 2 uniquement lorsque le manifeste d’analyse prouve que celle-ci est terminée, que la couverture est explicitement partial et qu’un rapport SARIF non vide existe. Les autres erreurs d’exécution, de configuration ou d’exportation restent bloquantes.

Le contrôle final préserve les codes de sortie suivants de l’analyseur :

Sortie Signification
0 L’analyse s’est terminée avec une couverture complète et a satisfait à sa politique.
1 L’analyse s’est terminée et a détecté un problème égal ou supérieur au seuil configuré.
2 La couverture de l’analyse était incomplète, ou une erreur d’entrée ou d’exécution s’est produite.

L’exemple autorise temporairement la sortie 2 pendant que vous étalonnez la couverture partielle. Supprimez cette autorisation lorsque la couverture incomplète doit bloquer le pipeline.

La correction et la publication s’exécutent avant le contrôle final de la politique. Un résultat admissible peut produire une demande de fusion vérifiée à l’état de brouillon même si le contrôle fait ensuite échouer le pipeline.

Activer la correction vérifiée

La correction automatisée est facultative et ne s’exécute que pour les pipelines de la branche par défaut protégée. Le processus de correction Codex et les commandes de vérification contrôlées par le dépôt ne reçoivent ni le jeton d’accès au projet GitLab ni les identifiants injectés par le runner.

Le contrat de sécurité comporte trois volets : les commandes contrôlées par le dépôt ne reçoivent jamais d’identifiants OpenAI ou GitLab, seule la tâche de publication reçoit un accès en écriture au dépôt, et chaque demande de fusion associée à une modification générée reste à l’état de brouillon jusqu’à ce qu’une personne l’examine et la fusionne.

Le workflow :

  1. Exige une couverture d’analyse complète et un résultat de gravité high ou critical.
  2. Vérifie que le test de régression configuré échoue avant l’application du correctif.
  3. Génère un correctif ciblé et refuse les modifications apportées aux fichiers CI, d’identifiants, binaires ou à d’autres fichiers protégés.
  4. Exécute le test de régression sans identifiants OpenAI, GitLab, de registre, de déploiement ou de tâche.
  5. Utilise verify-fix pour renvoyer fixed, still_vulnerable ou inconclusive. La tâche ne publie un correctif que lorsque verify-fix renvoie fixed et que le processus de vérification laisse le correctif inchangé.

Définissez ces variables protégées pour activer la correction :

  • Définissez CODEX_SECURITY_ENABLE_REMEDIATION sur true.
  • Définissez CODEX_SECURITY_VERIFICATION_COMMAND sur un test de régression existant qui se termine avec 1 avant le correctif et 0 après celui-ci.
  • Vous pouvez définir CODEX_SECURITY_SETUP_COMMAND sur une commande non interactive de configuration des dépendances.

Choisissez un test de régression qui vérifie l’invariant de sécurité sous-jacent, et non une implémentation particulière. Examinez avec la même attention les modifications générées dans les tests et le code source.

Avancé : isolation des commandes du dépôt

Les commandes validate, patch et verify-fix reçoivent une valeur CODEX_API_KEY limitée au processus. Les commandes de configuration et de test contrôlées par le dépôt s’exécutent sous un utilisateur non privilégié distinct, dans une copie accessible en écriture des fichiers source suivis. La copie exclut volontairement les métadonnées Git, le contenu des sous-modules et les artefacts téléchargés. Les commandes de configuration et de test qui nécessitent .git ou des sous-modules doivent s’exécuter dans une tâche distincte conçue sans identifiants.

Seules les étapes Codex appartenant à l’utilisateur root peuvent accéder au checkout canonique ou au répertoire adjacent des variables de fichier de GitLab. L’environnement propre de la copie ne contient que PATH, HOME, LANG, CI et CI_PROJECT_DIR. Si une commande nécessite une autre valeur non secrète, ajoutez-la à la liste d’autorisation après avoir examiné la commande. Si votre runner ne peut pas changer d’utilisateur, déplacez la vérification vers une tâche distincte sans identifiants avant d’activer la correction.

Publier une demande de fusion brouillon

Créez un jeton d’accès au projet GitLab avec le rôle Developer et les portées api et write_repository. Stockez-le sous la forme d’une variable GITLAB_REMEDIATION_TOKEN protégée, masquée et cachée, limitée à l’environnement codex-security/publish.

Définissez CODEX_SECURITY_CREATE_MR=true pour activer la publication. Définissez également la variable non secrète CODEX_SECURITY_MR_TEST_COMMAND sur le test de régression de sécurité propre au projet que chaque branche de correction générée doit réussir. Laissez cette variable non protégée afin que la demande de fusion générée et non protégée puisse lire la commande. Le workflow de publication :

  • Reçoit le jeton d’écriture dans le dépôt, mais aucun identifiant OpenAI.
  • Crée une branche codex-security/fix-<finding-hash>.
  • Ouvre une demande de fusion à l’état de brouillon et réutilise un brouillon ouvert existant au lieu d’en créer un doublon.
  • Exécute le test de régression de la branche de correction non protégée sous un utilisateur non privilégié, dans une copie composée uniquement des fichiers suivis et dépourvue d’identifiants protégés.
  • Ne fusionne jamais automatiquement la modification générée.

Ne remplacez pas le jeton d’accès au projet par CI_JOB_TOKEN. Il ne peut pas effectuer l’opération requise de création d’une demande de fusion. Examinez le correctif proposé, les preuves de vérification et le résultat avant d’effectuer la fusion.

Configurer les variables facultatives

Configurez uniquement les variables nécessaires aux fonctionnalités que vous activez :

Variable Quand elle est nécessaire Valeur par défaut ou fonction
CODEX_SECURITY_API_KEY Chaque analyse Protégée, masquée et cachée ; portée limitée à codex-security/openai
CODEX_SECURITY_VERSION Mise à niveau du CLI Épinglée sur 0.1.20 ; testez à nouveau avant toute modification
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH Analyses complètes de la branche par défaut Activation explicite ; désactivée par défaut
CODEX_SECURITY_SCHEDULED_DEEP_SCAN Analyses approfondies planifiées Activation explicite ; désactivée par défaut
CODEX_SECURITY_DEEP_MAX_TIME_HOURS Analyses approfondies planifiées Budget de temps obligatoire supérieur à 0 et inférieur à 8
CODEX_SECURITY_DEEP_MAX_COST Analyses approfondies planifiées Garde-fou obligatoire du coût estimé en USD supérieur à 0
CODEX_SECURITY_ENABLE_REMEDIATION Génération de correctifs Activation protégée ; désactivée par défaut
CODEX_SECURITY_VERIFICATION_COMMAND Génération de correctifs Test de régression protégé
CODEX_SECURITY_SETUP_COMMAND Configuration facultative de la correction Installation protégée des dépendances
CODEX_SECURITY_REMEDIATION_EFFORT Réglage facultatif de la correction high
CODEX_SECURITY_MAX_CHANGED_FILES Limite facultative de taille des correctifs 8 ; plage autorisée de 1 à 20
CODEX_SECURITY_CREATE_MR Création de demandes de fusion à l’état de brouillon Activation protégée ; désactivée par défaut
GITLAB_REMEDIATION_TOKEN Création de demandes de fusion à l’état de brouillon Jeton de projet Developer limité à codex-security/publish
CODEX_SECURITY_GITLAB_INTERNAL_URL Publication auto-hébergée facultative Origine GitLab accessible depuis le runner
CODEX_SECURITY_MR_TEST_COMMAND Publication de demandes de fusion à l’état de brouillon Test de régression obligatoire, non secret et propre au projet
CODEX_SECURITY_MR_SETUP_COMMAND Configuration facultative de la branche de correction Configuration non secrète des dépendances

GitLab fournit les variables CI_*. Le pipeline gère CODEX_SECURITY_BIN, CODEX_SECURITY_EFFORT, CODEX_SECURITY_MODE, CODEX_SECURITY_STATE_DIR et CODEX_SECURITY_TARGET ; ne les configurez pas en tant que variables de projet. Pour les analyses de diff, le CLI déduit l’identité canonique de la cible à partir des révisions de base et de tête normalisées.

Ajuster l’application des politiques et les coûts

Utilisez des analyses de diff ciblées pour les retours sur les demandes de fusion, des analyses standard du dépôt pour la branche par défaut et des analyses approfondies planifiées pour une couverture plus large. Les deux profils couvrant l’intégralité du dépôt sont désactivés par défaut. Une analyse approfondie planifiée nécessite également CODEX_SECURITY_DEEP_MAX_TIME_HOURS et CODEX_SECURITY_DEEP_MAX_COST ; maintenez le budget de temps du CLI sous le délai maximal de huit heures de la tâche. Mesurez des exécutions représentatives avant de définir un budget. Considérez --max-cost comme un garde-fou du coût estimé, et non comme un plafond de facturation strict.

Commencez par des analyses produisant uniquement des rapports. Ajoutez --fail-on-severity une fois que votre équipe a examiné des résultats représentatifs, la couverture, le coût et la durée d’exécution. Consultez Exécuter Codex Security en CI pour en savoir plus sur les politiques de gravité et les codes de sortie.

Lorsqu’une tâche échoue :

  • L’absence d’artefacts d’analyse indique un problème de configuration ou de runner.
  • Si les artefacts existent, mais que la couverture est partielle, examinez coverage.json.
  • L’absence de résultats GitLab nécessite de vérifier si la tâche de rapport SARIF a réussi et si GitLab a accepté le rapport.
  • Si la correction est ignorée, vérifiez la branche protégée, la couverture complète, la gravité du résultat, la commande de vérification et les variables d’activation.
  • En cas d’erreur de publication, vérifiez le rôle, les portées et la restriction d’environnement du jeton de projet.

Pour chaque commande, option et artefact, consultez la référence de Codex Security CLI.