Exécutez Codex Security dans GitLab CI/CD pour analyser les modifications enregistrées dans les commits et les branches protégées, publier les problèmes détectés dans GitLab Security et, si vous le souhaitez, proposer des correctifs vérifiés dans des demandes de fusion en brouillon.
Le workflow sépare les identifiants utilisés pour l’analyse des droits d’écriture sur le dépôt. Une personne doit examiner chaque modification générée avant sa fusion.
Commencez par analyser le code et publier les résultats. N’activez la correction automatique qu’après avoir vérifié le runner, les problèmes détectés et les processus qui ont accès aux identifiants de votre projet.
Avant de commencer
Vous avez besoin des éléments suivants :
- Un projet GitLab avec un runner de confiance qui prend en charge l’espace de noms utilisateur du bac à sable Codex.
- Le rôle Maintainer ou Owner dans le projet GitLab pour configurer les variables CI/CD du projet et les ressources protégées.
- Une clé API OpenAI donnant accès à Codex Security. Les organisations qui utilisent des clés API de la plateforme OpenAI peuvent demander un accès via Trusted Access for Cyber. Les personnes qui s’authentifient avec ChatGPT peuvent suivre la procédure Trusted Access pour les particuliers. Pour certains comptes ou dépôts, cet accès est nécessaire pour analyser l’ensemble du dépôt.
- GitLab Ultimate 19.2 ou version ultérieure pour importer les rapports SARIF 2.1.0.
- L’historique Git complet pour que les jobs des demandes de fusion puissent déterminer la base de fusion.
L’image du pipeline installe Node.js 26, Python 3, Git, rg et la version spécifiée de la CLI Codex Security. Pour corriger automatiquement les problèmes détectés, vous avez également besoin d’un test de régression existant et d’un runner capable d’exécuter les commandes définies dans le dépôt sans identifiants protégés.
Commencez par un pipeline d’analyse seule
Créez une variable CI/CD GitLab masquée, cachée et protégée nommée CODEX_SECURITY_API_KEY. Utilisez une clé API de la plateforme OpenAI donnant accès à Codex Security et limitez sa portée à l’environnement codex-security/openai. Consultez la documentation sur les variables CI/CD limitées à un environnement.
Ajoutez d’abord ce pipeline à un projet de test. Il analyse les modifications enregistrées dans les commits des demandes de fusion protégées admissibles. Si le job de publication du rapport réussit, GitLab importe le rapport SARIF. Un job de contrôle distinct reprend ensuite le code de sortie de l’analyse :
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:
- apt-get update -qq
- apt-get install -y -qq --no-install-recommends ca-certificates git python3 ripgrep
- npm install --prefix /tmp/codex-security-cli --ignore-scripts --no-audit --no-fund @openai/codex-security@0.8.1
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" \
--fail-on-severity high \
--json
scan_exit="$?"
set -e
unset codex_security_api_key
case "$scan_exit" in
0|1) ;;
*) 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 un job qui a accès à des secrets. Cet exemple ne prévoit ni analyse complète ni correction automatique.
Adoptez le pipeline de production
- Téléchargez le pipeline GitLab complet et enregistrez-le sous le nom
.gitlab-ci.ymlà la racine du dépôt. Si votre dépôt dispose déjà d’un pipeline, intégrez les étapes, les modèles cachés et les jobs de l’exemple au fichier existant. - Conservez les étapes existantes de compilation, de test et de déploiement. Si le projet utilise
workflow: rules, vérifiez que ces règles autorisent les événements qui doivent déclencher une analyse.
L’exemple ajoute les étapes security_scan, security_remediation, security_publish et security_gate. Pour analyser le code et publier les résultats, seule la variable CODEX_SECURITY_API_KEY est nécessaire.
Par défaut, le job d’analyse s’exécute uniquement pour les demandes de fusion entre branches protégées d’un même projet. Définissez CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH=true pour lancer une analyse lors d’un push sur la branche par défaut protégée ou de l’exécution manuelle d’un pipeline sur cette branche. Définissez CODEX_SECURITY_SCHEDULED_DEEP_SCAN=true et fixez explicitement des budgets de durée 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 aux runners protégés que si toutes les conditions suivantes sont réunies :
- Vous protégez les branches source et cible dans le même projet.
- Le projet autorise les pipelines de demande de fusion à accéder aux variables et aux runners protégés.
- La personne qui lance le pipeline peut pousser ou fusionner des modifications dans la branche cible.
Les pipelines des forks et les demandes de fusion non protégées ne reçoivent pas la clé d’analyse. Examinez chaque modification de .gitlab-ci.yml avant d’exécuter un job qui a accès à des secrets. Même si une variable est masquée et cachée, le code CI provenant d’une source non fiable reste dangereux.
Lancez une analyse et examinez les problèmes détectés
Créez une demande de fusion protégée qui remplit les conditions requises ou exécutez le pipeline sur la branche par défaut protégée. Commencez par analyser un petit diff avant de lancer une analyse payante de l’ensemble du dépôt.
Ouvrez le job codex-security et vérifiez que ses artefacts contiennent les fichiers suivants :
results/scan-manifest.jsonresults/findings.jsonresults/report.mdresults.sarifscan-exit-code.txt
Ouvrez ensuite l’onglet Sécurité du pipeline, examinez les avertissements d’importation et vérifiez les identifiants des problèmes détectés, leur niveau de gravité et leur emplacement dans le code source. Les analyses de la branche par défaut créent aussi des fiches de vulnérabilité pour le projet. Les problèmes détectés dans une demande de fusion apparaissent dans l’onglet Sécurité du pipeline ou dans le widget de sécurité de la demande de fusion, sans créer de fiche de vulnérabilité à l’échelle du projet.
Limitez l’accès aux artefacts, car les résultats d’analyse peuvent contenir des extraits de code source vulnérable, des éléments de preuve et des précisions sur les correctifs.
Choisissez un profil d’analyse
Le pipeline sélectionne un profil en fonction de l’événement déclencheur :
| Déclencheur | Cible | Mode | Effort |
|---|---|---|---|
| Demande de fusion entre branches protégées du même projet | Diff entre commits | standard |
low |
| Push ou lancement manuel sur la branche par défaut protégée, après activation | Dépôt entier | standard |
high |
| Exécution planifiée sur la branche par défaut protégée, après activation | Dépôt entier | deep |
xhigh |
Pour une demande de fusion, l’analyse porte sur les modifications enregistrées dans les commits. Sur la branche par défaut, elle porte sur le dépôt tel qu’il se présente après intégration des modifications. Les analyses approfondies planifiées offrent une couverture plus large à intervalles réguliers. Une analyse de diff achevée ne porte que sur les modifications examinées et ne permet pas de conclure que le dépôt entier est exempt de problèmes.
Le workflow installe la CLI en dehors du dépôt et l’exécute à partir de son chemin absolu. Le contrôle préalable en mode simulation utilise la clé API réservée au processus. Il ne lance aucune analyse payante et ne vérifie ni l’authentification auprès de l’API, ni l’accès à Codex Security, ni le quota, ni la disponibilité du modèle.
Le workflow enregistre l’état et les résultats de l’analyse en dehors de l’arbre de travail et réserve OPENAI_API_KEY au processus d’analyse. La CLI reçoit uniquement un ensemble restreint de variables d’environnement définies explicitement, au lieu d’hériter de toutes les variables GitLab. Pour les analyses de diff, le workflow détermine la base de fusion et analyse les différences entre les révisions de base et de tête soumises à l’examen.
L’exemple fixe la version de @openai/codex-security à 0.8.1. Avant de changer de version, testez à nouveau l’authentification, la production des artefacts, l’importation SARIF et l’application de la politique de sécurité.
Séparez la publication des résultats de l’application de la politique de sécurité
GitLab importe le rapport SARIF lorsque le job de publication du rapport réussit. Le pipeline publie d’abord le rapport, puis reprend le code de sortie de l’analyse dans un job codex-security-gate distinct.
Le job de publication du rapport n’exporte les problèmes détectés que pour les codes de sortie 0 et 1. Tout autre code de sortie empêche l’exportation SARIF et bloque le pipeline. Un échec de l’exportation bloque également le pipeline.
Le job de publication du rapport propage les erreurs d’exécution et les interruptions. S’il réussit, le contrôle final reprend le résultat de l’analyse pour appliquer la politique de sécurité :
| Code de sortie | Signification |
|---|---|
0 |
L’analyse s’est terminée et satisfait aux critères de la politique de sécurité. |
1 |
L’analyse s’est terminée et a détecté un problème dont la gravité atteint ou dépasse le seuil configuré. |
2 |
L’analyse a rencontré une erreur liée aux données d’entrée, à l’exécution, à l’intégrité de la cible ou à une sortie requise. |
130 / 143 |
L’analyse a été interrompue ou arrêtée. |
L’exemple passe l’option --fail-on-severity high. Le contrôle échoue donc si l’analyse détecte un problème de gravité élevée ou critique. En l’absence de seuil de gravité, une analyse qui se termine renvoie par défaut le code 0. Dans results/scan-manifest.json, consultez scan.scope pour connaître le périmètre configuré et scan.review.excludedPaths pour connaître les chemins exclus de la comparaison des problèmes détectés. Consultez results/report.md pour connaître les suites à donner.
La correction et la publication précèdent le contrôle final de la politique de sécurité. Un problème qui remplit les critères de correction peut donc donner lieu à une demande de fusion en brouillon avec un correctif vérifié, même si le contrôle fait ensuite échouer le pipeline.
Activez la correction automatique avec vérification
La correction automatique est facultative et s’exécute uniquement dans les pipelines de la branche par défaut protégée. Ni le processus de correction de Codex ni les commandes de vérification définies dans le dépôt ne reçoivent le jeton d’accès au projet GitLab ou les identifiants injectés par le runner.
Le workflow procède comme suit :
- Il exige un manifeste attestant que l’analyse de la révision actuelle est terminée et qu’un problème de gravité
highoucriticala été détecté. - Il vérifie que le test de régression configuré échoue avant l’application du correctif.
- Il génère un correctif et rejette les modifications qui touchent les fichiers de CI, les fichiers d’identifiants, les fichiers binaires ou d’autres fichiers protégés.
- Il exécute le test de régression sans identifiants OpenAI, GitLab, de registre ou de déploiement, et sans jeton de job.
- Il utilise
verify-fixpour obtenir le résultatfixed,still_vulnerableouinconclusive. Le job ne publie le correctif que siverify-fixrenvoiefixedet que le processus de vérification n’a pas modifié le correctif.
Configurez les variables protégées suivantes pour activer la correction automatique :
- Définissez
CODEX_SECURITY_ENABLE_REMEDIATIONsurtrue. - Affectez à
CODEX_SECURITY_VERIFICATION_COMMANDla commande d’un test de régression existant qui renvoie1avant le correctif et0après son application. - Si nécessaire, affectez à
CODEX_SECURITY_SETUP_COMMANDune commande non interactive de configuration des dépendances.
Choisissez un test de régression qui vérifie la propriété de sécurité à garantir, indépendamment de sa mise en œuvre. Examinez avec la même rigueur les modifications générées dans les tests et dans le code source.
Configuration avancée : isolation des commandes du dépôt
Les commandes validate, patch et verify-fix reçoivent une clé OPENAI_API_KEY réservée au processus et utilisent --auth api-key. Les commandes de configuration et de test définies dans le dépôt s’exécutent sous un compte utilisateur distinct sans privilèges, dans une copie accessible en écriture des fichiers source suivis par Git. Cette copie exclut les métadonnées Git, le contenu des sous-modules et les artefacts téléchargés. Si les commandes de configuration ou de test nécessitent .git ou des sous-modules, exécutez-les dans un job distinct conçu pour fonctionner sans identifiants.
Seules les étapes Codex dont root est propriétaire peuvent accéder à la copie de référence du dépôt ou au répertoire adjacent où GitLab stocke les variables de type fichier. Dans la copie destinée aux tests, l’environnement 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 des valeurs autorisées après avoir examiné la commande. Si votre runner ne peut pas changer d’utilisateur, déplacez la vérification dans un job distinct sans identifiants avant d’activer la correction automatique.
Publiez une demande de fusion en 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 dans la variable protégée, masquée et cachée GITLAB_REMEDIATION_TOKEN, dont vous limiterez la portée à l’environnement codex-security/publish.
Définissez CODEX_SECURITY_CREATE_MR=true pour activer la publication. Affectez également à la variable non secrète CODEX_SECURITY_MR_TEST_COMMAND la commande du 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 le pipeline de la demande de fusion non protégée qui sera créée puisse lire la commande. Le workflow de publication fonctionne ainsi :
- Il reçoit le jeton d’écriture sur le dépôt, mais aucun identifiant OpenAI.
- Il crée une branche
codex-security/fix-<finding-hash>. - Il ouvre une demande de fusion en brouillon. Si un brouillon est déjà ouvert pour ce correctif, il le réutilise pour éviter les doublons.
- Il exécute le test de régression de la branche de correction non protégée sous un compte sans privilèges ni identifiants protégés, dans une copie contenant uniquement les fichiers suivis par Git.
- Il ne fusionne jamais automatiquement la modification générée.
Ne remplacez pas le jeton d’accès au projet par CI_JOB_TOKEN. Ce dernier ne permet pas de créer la demande de fusion requise. Avant la fusion, examinez le correctif proposé, les éléments de preuve issus de la vérification et le problème détecté.
Configurez les variables facultatives
Configurez uniquement les variables nécessaires aux fonctionnalités que vous activez :
| Variable | Utilisation | Valeur par défaut ou fonction |
|---|---|---|
CODEX_SECURITY_API_KEY |
Chaque analyse | Variable protégée, masquée et cachée, à limiter à codex-security/openai |
CODEX_SECURITY_VERSION |
Mise à niveau de la CLI | Version fixée à 0.8.1. Refaites les tests avant de la modifier |
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_MINUTES |
Analyses approfondies planifiées | Budget de temps obligatoire, en minutes, strictement supérieur à 0 et inférieur à 480 |
CODEX_SECURITY_DEEP_MAX_COST |
Analyses approfondies planifiées | Seuil obligatoire de coût estimé en dollars américains, strictement supérieur à 0 |
CODEX_SECURITY_ENABLE_REMEDIATION |
Génération de correctifs | Activation par variable protégée, désactivée par défaut |
CODEX_SECURITY_VERIFICATION_COMMAND |
Génération de correctifs | Commande du test de régression, stockée dans une variable protégée |
CODEX_SECURITY_SETUP_COMMAND |
Préparation facultative de la correction | Commande d’installation des dépendances, stockée dans une variable protégée |
CODEX_SECURITY_REMEDIATION_EFFORT |
Réglage facultatif de l’effort de correction | high |
CODEX_SECURITY_MAX_CHANGED_FILES |
Limite facultative de la taille du correctif | 8 par défaut, de 1 à 20 inclus |
CODEX_SECURITY_CREATE_MR |
Création d’une demande de fusion en brouillon | Activation par variable protégée, désactivée par défaut |
GITLAB_REMEDIATION_TOKEN |
Création d’une demande de fusion en brouillon | Jeton de projet doté du rôle Developer et limité à codex-security/publish |
CODEX_SECURITY_GITLAB_INTERNAL_URL |
Publication facultative sur une instance autohébergée | URL d’origine de GitLab accessible depuis le runner |
CODEX_SECURITY_MR_TEST_COMMAND |
Publication d’une demande de fusion en brouillon | Commande obligatoire et non secrète du test de régression propre au projet |
CODEX_SECURITY_MR_SETUP_COMMAND |
Préparation facultative de la branche de correction | Commande non secrète de configuration 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 comme variables de projet. Pour les analyses de diff, la CLI détermine l’identité canonique de la cible à partir des révisions de base et de tête normalisées.
Ajustez les critères de blocage et le coût des analyses
Utilisez les analyses de diff pour obtenir des résultats ciblés sur les demandes de fusion, les analyses standard du dépôt pour la branche par défaut et les analyses approfondies planifiées pour une couverture plus large. Les deux profils d’analyse du dépôt entier sont désactivés par défaut. Une analyse approfondie planifiée nécessite aussi CODEX_SECURITY_DEEP_MAX_TIME_MINUTES et CODEX_SECURITY_DEEP_MAX_COST. Fixez pour la CLI une durée inférieure au délai d’expiration du job, qui est de huit heures. Lors du passage au nouveau fichier YAML, convertissez en minutes les paramètres existants exprimés en heures. Mesurez la durée et le coût d’exécutions représentatives avant de fixer un budget. L’option --max-cost limite le coût estimé sans garantir de plafond de facturation.
Dans cet exemple, les problèmes de gravité élevée ou critique bloquent le pipeline. Pour publier uniquement un rapport, supprimez --fail-on-severity high. Choisissez un seuil après avoir examiné les problèmes détectés, la couverture, le coût et la durée d’analyses représentatives. Consultez la présentation de la CI/CD pour les politiques de gravité et la référence de la CLI pour le détail des codes de sortie.
En cas d’échec d’un job :
- Si les artefacts d’analyse sont absents, recherchez un problème de configuration ou de runner.
- En cas d’exclusions inattendues, vérifiez le périmètre de l’analyse et les détails de l’examen dans
results/scan-manifest.json. - Si les problèmes détectés n’apparaissent pas dans GitLab, vérifiez que le job de publication du rapport SARIF a réussi et que GitLab a accepté le rapport.
- Si la correction automatique ne s’est pas exécutée, vérifiez la protection de la branche, le manifeste d’analyse, la gravité du problème détecté, la commande de vérification et les variables d’activation.
- En cas d’erreur de publication, vérifiez le rôle associé au jeton de projet, ses portées et l’environnement auquel il est limité.
Pour le détail de chaque commande, option et artefact, consultez la référence de la CLI Codex Security.