Sécuriser votre pipeline CI/CD avec CodeMender

1. Avant de commencer

Bienvenue dans l'atelier de programmation pratique Sécuriser votre pipeline CI/CD avec CodeMender.

Dans la livraison de logiciels moderne, les outils d'analyse statique (comme CodeQL) sont essentiels pour détecter les modèles syntaxiques connus, mais ils passent souvent à côté de failles nuancées cachées au cœur de la logique métier et génèrent des alertes bruyantes et non vérifiées.

CodeMender (exécutable CLI : cm) améliore votre pipeline CI/CD (en parallèle des outils SAST existants) en déployant les agents de raisonnement de sécurité de Google optimisés par Gemini pour :

Détectez les failles complexes de la logique métier : raisonnez sur le contexte de l'application et les flux de données architecturaux au-delà des règles de modèle statiques rigides.

Réduisez considérablement les faux positifs grâce à la vérification automatique des failles : prouvez de manière dynamique l'exploitabilité dans des environnements de bac à sable avant d'alerter les développeurs.

Corriger de manière autonome les résultats vérifiés : synthétisez les correctifs de code, validez-les par rapport aux suites de tests pour éviter les régressions et envoyez des demandes d'extraction prêtes à être examinées.

Dans cet atelier de programmation, vous allez intégrer CodeMender au dépôt OWASP Juice Shop à l'aide de GitHub Actions et de la fédération d'identité de charge de travail (WIF) Google Cloud sans clé.

Prérequis

  • Recommandé : Connaissances de base des concepts de CodeMender (abordés dans Sécuriser votre application avec CodeMender)
  • Compréhension de base des workflows, des déclencheurs et de la syntaxe YAML de GitHub Actions
  • Connaissance de base des commandes Git et des workflows d'examen des demandes d'extraction
  • Connaissances de base des concepts Google Cloud IAM (comptes de service, rôles et API)
  • Connaissance des failles courantes des applications Web (telles que l'injection SQL et le XSS)

Points abordés

  • Configurer l'authentification sans clé zéro confiance entre GitHub Actions et Google Cloud via la fédération d'identité de charge de travail (WIF)
  • Comment créer un workflow d'analyse automatisée des failles à l'aide de CodeMender et de gemini-3.8-flash
  • Publier des rapports de sécurité exploitables à l'aide d'OASIS SARIF v2.1.0 et des résumés de jobs GitHub Actions natifs
  • Comment créer un workflow de correction autonome qui génère des correctifs de code validés par des tests et ouvre des demandes d'extraction pour un examen humain
  • Comment appliquer des contrôles de qualité automatisés (--fail-on) et la mise en cache des pipelines pour une sécurité continue à grande vitesse

Prérequis

  • Un projet Google Cloud avec facturation activée et des autorisations de propriétaire/éditeur du projet
  • Un compte GitHub avec les autorisations nécessaires pour créer des dépôts, configurer des secrets et gérer des actions (vous dupliquez le dépôt GitHub OWASP Juice Shop à l'étape 3 à l'aide de la CLI GitHub).

2. Comprendre l'architecture CI/CD de CodeMender

Dans les pratiques DevSecOps modernes des entreprises, la sécurité optimisée par l'IA ne peut pas se limiter à un outil de bureau manuel. Il doit fonctionner comme un gardien automatisé (bloquant les demandes d'extraction non sécurisées) et un co-développeur autonome (proposant des correctifs vérifiés directement dans Git).

Pour ce faire, vous allez implémenter une architecture à double workflow optimisée par la fédération d'identité de charge de travail (WIF) Google Cloud et les modèles de raisonnement Gemini Enterprise.

Architecture à double workflow

Architecture du pipeline CI/CD autonome CodeMender

Plutôt que de regrouper la détection et la correction dans un seul script monolithique, le pipeline sépare la sécurité en deux workflows distincts et spécialement conçus :

Workflow

Déclencheur principal

Responsabilité principale

Seuil de qualité strict

1. Outil d'analyse des failles(codemender-scan.yml)

Demandes d'extraction, pushs principaux, cron hebdomadaire, distribution manuelle

• Exécute des analyses AST différentielles rapides sur les demandes d'extraction (~15 s), des analyses de référence rapides sur les push (–quick) et des audits approfondis simultanés sur les planifications• Valide l'état de préparation en amont via cm health –strict• Génère des résumés de jobs d'actions natifs et importe OASIS SARIF dans l'onglet "Sécurité" de GitHub

Bloque la fusion de la RP si de nouvelles failles de gravité élevée ou critique sont détectées (–fail-on)

2. Autonomous Remediator(codemender-remediate.yml)

Déclencheur manuel (workflow_dispatch), Cron nocturne

• Reprend l'état à partir des artefacts d'analyse (cm report import) et state.db• Synthétise les correctifs à l'aide du raisonnement de Gemini• Préserve les limites d'un espace de travail propre et envoie des demandes d'extraction prêtes à être examinées

Assure des différences de production propres avant d'ouvrir une demande d'extraction

Trois principes fondamentaux de conception d'entreprise

Lorsque vous créerez ces workflows dans les sections suivantes, gardez à l'esprit ces trois piliers architecturaux fondamentaux :

🔑 Authentification sans clé zéro confiance et validation préalable :

Aucune clé JSON de compte de service Google Cloud à longue durée de vie n'est stockée dans GitHub Secrets. L'exécuteur génère un jeton OIDC de courte durée échangé via Google Cloud STS contre un identifiant éphémère d'une heure, définit persist-credentials: false sur les extractions Git et exécute cm health --strict pour vérifier les identifiants, la joignabilité du réseau et les autorisations IAM avant de consommer le quota du modèle.

⚡ Routage adaptatif des analyses et suppression de l'ancien bruit :

Au lieu d'exécuter des audits lents de l'intégralité du dépôt sur chaque demande d'extraction, CodeMender achemine chaque événement d'intégration continue vers le mode d'analyse optimal : les demandes d'extraction déclenchent une analyse AST différentielle (--diff="origin/$BASE_REF") sur les fichiers modifiés et les appelants à un saut en moins de 15 secondes ; les pushs de la branche principale exécutent des analyses de référence rapides en une seule session (--quick) ; et les planifications hebdomadaires exécutent des audits approfondis simultanés fichier par fichier (cm find . par défaut). Les failles préexistantes de la codebase qui ne sont pas affectées par une demande d'extraction sont étiquetées [LEGACY / UNTOUCHED] ; elles apparaissent dans les rapports SARIF pour plus de visibilité, mais ne bloquent pas la fusion de la demande d'extraction et ne déclenchent pas de correction automatique.

🛡️ Observabilité de la sécurité résiliente et non bloquante :

Même lorsque --fail-on se ferme avec le code 1 pour bloquer une demande d'extraction non sécurisée, la protection des étapes d'exportation du rapport et d'importation SARIF avec steps.scan.outputs.completed == 'true' et hashFiles('results.sarif') != '' garantit que les alertes OASIS SARIF et les résumés de job sont toujours publiés, tout en ignorant l'exportation et l'importation si une exécution est annulée ou s'interrompt en raison d'une erreur de configuration ou de capacité (10–60).

3. S'authentifier et préparer le dépôt cible dans Cloud Shell

Pour établir l'authentification sans clé et exécuter des pipelines de sécurité automatisés, vous devez disposer d'un dépôt GitHub cible accessible dont vous êtes propriétaire. Dans cet atelier de programmation, vous allez utiliser OWASP Juice Shop, une application Web Node.js intentionnellement vulnérable, comme environnement de test de sécurité clé en main.

Vous allez utiliser la CLI GitHub (gh), préinstallée dans Google Cloud Shell, pour vous authentifier auprès de GitHub, capturer automatiquement vos informations utilisateur et préparer votre dépôt dans un flux simplifié.

Étape 1 : Ouvrez Cloud Shell et authentifiez GitHub CLI

Ouvrez la console Google Cloud et activez Cloud Shell (icône >_ dans la barre de navigation supérieure).

Authentifiez GitHub CLI (gh) pour configurer la gestion des identifiants Git :

gh auth login --hostname github.com --git-protocol https --web

Suivez les instructions à l'écran :

Copiez le code à usage unique à huit caractères affiché dans Cloud Shell (par exemple, 1234-ABCD).

Appuyez sur Entrée pour ouvrir https://github.com/login/device dans votre navigateur.

Collez le code, puis cliquez sur Authorize github (Autoriser GitHub).

Étape 2 : Exportez dynamiquement des variables et dupliquez OWASP Juice Shop

Exécutez les commandes suivantes dans Cloud Shell pour capturer automatiquement votre nom d'utilisateur GitHub et préparer le dépôt :

# 1. Automatically capture your GitHub username (customize GITHUB_REPO if desired)
export GITHUB_ORG=$(gh api user -q .login)
export GITHUB_REPO="${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_ORG:+${GITHUB_ORG}/${GITHUB_REPO}}"
echo "Authenticated as: ${GITHUB_REPOSITORY}"

# 2. Fork on GitHub server using GITHUB_REPO as the fork name
gh repo fork juice-shop/juice-shop --fork-name "${GITHUB_REPO}" --default-branch-only --clone=false 2>/dev/null || true

# 3. Shallow clone your fork (downloads only ~15 MB in 3-5 seconds, skipping heavy upstream git history)
[ -d ~/"${GITHUB_REPO}" ] || git clone --depth=1 "https://github.com/${GITHUB_REPOSITORY}.git" ~/"${GITHUB_REPO}" || \
 (sleep 2 && git clone --depth=1 "https://github.com/${GITHUB_REPOSITORY}.git" ~/"${GITHUB_REPO}")
cd ~/"${GITHUB_REPO}"

# 4. Confirm you are in the repository directory
git status

4. Configurer la fédération d'identité de charge de travail Google Cloud via gcloud

Dans cette étape, vous allez utiliser la CLI gcloud dans Google Cloud Shell pour activer les API requises, créer un compte de service CI/CD dédié, configurer le pool d'identités de charge de travail et établir une relation de confiance OIDC avec votre dépôt GitHub (${GITHUB_REPOSITORY}).

Étape 1 : Définissez les variables d'environnement Google Cloud

Dans votre terminal Cloud Shell (dans l'espace de travail de votre dépôt cloné), capturez l'ID de votre projet Google Cloud actif, vérifiez la variable de votre dépôt GitHub et définissez les noms des ressources WIF :

# Capture active Google Cloud Project ID and verify GitHub repository
export PROJECT_ID=$(gcloud config get-value project)
export GITHUB_USER=$(gh api user -q ".login")
export GITHUB_REPO="${GITHUB_REPO:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*/##; s#\.git$##')}"
export GITHUB_REPO="${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_USER:+${GITHUB_USER}/${GITHUB_REPO}}"

# Define WIF and Service Account resource names
export WORKLOAD_IDENTITY_POOL="codemender-github-pool"
export WORKLOAD_IDENTITY_PROVIDER="codemender-github-provider"
export SERVICE_ACCOUNT_NAME="codemender-ci-runner"

if [ -z "${PROJECT_ID}" ] || [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: PROJECT_ID ('${PROJECT_ID}') or GITHUB_REPOSITORY ('${GITHUB_REPOSITORY}') is empty. Check 'gcloud config get-value project' and 'gh auth status'."
else
 echo "Project ID:        ${PROJECT_ID}"
 echo "GitHub Repository: ${GITHUB_REPOSITORY}"
fi

Étape 2 : Activez les API Google Cloud requises

Activez l'API IAM, l'API Security Token Service, l'API IAM Credentials, l'API Agent Platform et l'API Resource Manager :

gcloud services enable \
 iam.googleapis.com \
 iamcredentials.googleapis.com \
 sts.googleapis.com \
 aiplatform.googleapis.com \
 cloudresourcemanager.googleapis.com \
 --project=${PROJECT_ID}

Étape 3 : Créez un compte de service CI/CD dédié

Créez un compte de service Google Cloud avec le moindre privilège dédié à l'exécution du pipeline CI/CD (en le réutilisant de manière sécurisée s'il existe déjà) :

export SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud iam service-accounts describe "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" >/dev/null 2>&1 || \
gcloud iam service-accounts create "${SERVICE_ACCOUNT_NAME}" \
 --display-name="CodeMender CI/CD Pipeline Runner" \
 --project="${PROJECT_ID}"

echo "Service Account Email: ${SERVICE_ACCOUNT_EMAIL}"

Étape 4 : Accordez des autorisations IAM Agent Platform

Attribuez le rôle roles/aiplatform.user (Utilisateur Agent Platform) au compte de service pour qu'il puisse communiquer avec Gemini Enterprise Agent Platform :

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
 --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
 --role="roles/aiplatform.user"

Étape 5 : Créez le pool d'identités de charge de travail

Créez le pool d'identités de charge de travail pour gérer les assertions d'identité GitHub Actions (ou restaurez-le et activez-le automatiquement s'il existe déjà dans votre projet) :

POOL_STATE=$(gcloud iam workload-identity-pools list \
 --location="global" \
 --show-deleted \
 --project="${PROJECT_ID}" \
 --filter="name ~ /${WORKLOAD_IDENTITY_POOL}$" \
 --format="value(state)")

if [ -z "${POOL_STATE}" ]; then
 gcloud iam workload-identity-pools create "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --display-name="CodeMender GitHub Pool" \
   --project="${PROJECT_ID}"
else
 [ "${POOL_STATE}" = "DELETED" ] && gcloud iam workload-identity-pools undelete "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --project="${PROJECT_ID}"
 gcloud iam workload-identity-pools update "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --no-disabled \
   --project="${PROJECT_ID}"
fi

Étape 6 : Créez le fournisseur Workload Identity avec GitHub OIDC

Créez (ou mettez à jour) le fournisseur OIDC dans le pool, en liant l'URL de l'émetteur https://token.actions.githubusercontent.com et en mappant les assertions de jeton GitHub aux attributs Google STS :

PROVIDER_STATE=$(gcloud iam workload-identity-pools providers list \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --show-deleted \
 --project="${PROJECT_ID}" \
 --filter="name ~ /${WORKLOAD_IDENTITY_PROVIDER}$" \
 --format="value(state)")

if [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: GITHUB_REPOSITORY is empty. Re-run Step 1 before configuring the OIDC provider."
elif [ -z "${PROVIDER_STATE}" ]; then
 gcloud iam workload-identity-pools providers create-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --display-name="CodeMender GitHub Provider" \
   --issuer-uri="https://token.actions.githubusercontent.com" \
   --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
   --attribute-condition="assertion.repository == '${GITHUB_REPOSITORY}'" \
   --project="${PROJECT_ID}"
else
 [ "${PROVIDER_STATE}" = "DELETED" ] && gcloud iam workload-identity-pools providers undelete "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --project="${PROJECT_ID}"
 gcloud iam workload-identity-pools providers update-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --issuer-uri="https://token.actions.githubusercontent.com" \
   --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
   --attribute-condition="assertion.repository == '${GITHUB_REPOSITORY}'" \
   --no-disabled \
   --project="${PROJECT_ID}"
fi

Étape 7 : Autorisez le dépôt GitHub à emprunter l'identité du compte de service

Associez le rôle roles/iam.workloadIdentityUser pour permettre aux jetons provenant de votre dépôt d'emprunter l'identité du compte de service de l'exécuteur d'intégration continue, puis vérifiez la liaison de stratégie :

# Retrieve the canonical Workload Identity Pool resource ID
export POOL_ID=$(gcloud iam workload-identity-pools describe "${WORKLOAD_IDENTITY_POOL}" \
 --project="${PROJECT_ID}" \
 --location="global" \
 --format="value(name)")

if [ -z "${POOL_ID}" ] || [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: POOL_ID ('${POOL_ID}') or GITHUB_REPOSITORY ('${GITHUB_REPOSITORY}') is empty. Re-run Step 1 and Step 5."
else
 # Bind Workload Identity User role to the principalSet of your repository
 gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_EMAIL}" \
   --project="${PROJECT_ID}" \
   --role="roles/iam.workloadIdentityUser" \
   --member="principalSet://iam.googleapis.com/${POOL_ID}/attribute.repository/${GITHUB_REPOSITORY}"

 # Verify the principalSet binding on the Service Account
 gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT_EMAIL}" \
   --project="${PROJECT_ID}"
fi

Étape 8 : Récupérez les valeurs de configuration des secrets GitHub

Récupérez le nom complet de la ressource de votre fournisseur d'identité de charge de travail et stockez-le dans une variable d'environnement pour l'enregistrement automatique à l'étape suivante :

# Retrieve full Workload Identity Provider name
export WORKLOAD_PROVIDER_NAME=$(gcloud iam workload-identity-pools providers describe ${WORKLOAD_IDENTITY_PROVIDER} \
 --workload-identity-pool=${WORKLOAD_IDENTITY_POOL} \
 --location="global" \
 --project=${PROJECT_ID} \
 --format="value(name)")

echo "=========================================================="
echo "WIF CONFIGURATION READY:"
echo "=========================================================="
echo "GCP_WORKLOAD_IDENTITY_PROVIDER: ${WORKLOAD_PROVIDER_NAME}"
echo "GCP_SERVICE_ACCOUNT:            ${SERVICE_ACCOUNT_EMAIL}"
echo "=========================================================="

5. Configurer les secrets du dépôt GitHub et les autorisations de workflow

Maintenant que la fédération d'identité de charge de travail Google Cloud est provisionnée, vous allez configurer les secrets du dépôt GitHub et accorder les autorisations de workflow nécessaires pour l'analyse de sécurité automatisée et les demandes d'extraction de correction automatique.

Vous pouvez configurer ces paramètres directement depuis Cloud Shell à l'aide de la CLI GitHub (gh), ce qui élimine complètement le copier-coller manuel de longs noms de ressources.

Étape 1 : Définissez les secrets du dépôt à l'aide de la CLI GitHub

Dans votre terminal Cloud Shell, exécutez les commandes suivantes pour définir de manière sécurisée les deux secrets de dépôt requis à l'aide des variables d'environnement actives :

# 1. Set the Workload Identity Provider resource name
gh secret set GCP_WORKLOAD_IDENTITY_PROVIDER \
 --body "${WORKLOAD_PROVIDER_NAME}" \
 --repo "${GITHUB_REPOSITORY}"

# 2. Set the CI/CD Service Account email
gh secret set GCP_SERVICE_ACCOUNT \
 --body "${SERVICE_ACCOUNT_EMAIL}" \
 --repo "${GITHUB_REPOSITORY}"

# 3. Verify the secrets are registered
gh secret list --repo "${GITHUB_REPOSITORY}"

Étape 2 : Accordez des autorisations de workflow pour les RP automatisées

Par défaut, les workflows GitHub Actions s'exécutent avec des autorisations en lecture seule et ne peuvent pas créer de demandes d'extraction. À l'étape 9, CodeMender génère et envoie de manière autonome des demandes d'extraction de correction vérifiées.

Accordez des autorisations d'écriture et activez la création de demandes d'extraction directement via l'API GitHub :

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"

gh api \
 --method PUT \
 -H "Accept: application/vnd.github+json" \
 /repos/${GITHUB_REPOSITORY}/actions/permissions/workflow \
 -f default_workflow_permissions="write" \
 -F can_approve_pull_request_reviews=true

Étape 3 : Désactivez les workflows Juice Shop en amont hérités

La duplication de Juice Shop de l'OWASP entraîne le transfert de 16 workflows d'intégration continue en amont (tels que PR Compliance Check, CI/CD Pipeline et CodeQL Scan) ainsi que d'un modèle de demande d'extraction de contributeur en amont qui ferme automatiquement les demandes d'extraction ciblant master. Désactivez tous les workflows non-CodeMender via la CLI GitHub et supprimez les fichiers en amont localement pour que votre fork n'exécute que les workflows CodeMender :

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"

# 1. Disable all inherited non-CodeMender workflows in GitHub Actions (and CodeQL default setup if active)
for WF_ID in $(gh workflow list --all --limit 100 --repo "${GITHUB_REPOSITORY}" --json id,path \
 -q '.[] | select((.path | startswith(".github/workflows/")) and (.path | test("codemender-") | not)) | .id'); do
 gh workflow disable "${WF_ID}" --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
done
gh api -X PATCH "/repos/${GITHUB_REPOSITORY}/code-scanning/default-setup" \
 -f state=not-configured >/dev/null 2>&1 || true

# 2. Remove upstream workflow files and PR template from the local workspace
for f in .github/workflows/*; do
 case "$f" in *codemender-*) ;; *) rm -f "$f" ;; esac
done
rm -f .github/PULL_REQUEST_TEMPLATE.md

6. Créer le workflow d'analyse des failles automatique avec SARIF

Au cours de cette étape, vous allez créer le workflow d'analyse de sécurité continue principal (.github/workflows/codemender-scan.yml) qui exécute des analyses de référence sur les push de branche, des portes différentielles sur les demandes d'extraction et des exportations SARIF vers l'analyse de code GitHub.

Étape 1 : Téléchargez le workflow d'analyse CodeMender

Téléchargez codemender-scan.yml depuis le dépôt de démarrage dans .github/workflows/ :

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
mkdir -p .github/workflows
curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-scan.yml \
 -o .github/workflows/codemender-scan.yml

Étape 2 : Validez, effectuez un push et déclenchez l'analyse d'intégration continue

Validez les modifications du workflow et déployez-les directement dans la branche principale de votre dépôt (master pour Juice Shop ou main) :

# Stage workflow changes, commit, and push to primary branch
git add -A .github
git commit -m "ci: add CodeMender SARIF security scanning workflow"
git push origin $(git branch --show-current)

Dans votre navigateur :

Accédez à votre dépôt GitHub dupliqué : https://github.com/YOUR_GITHUB_USER/juice-shop (par exemple, https://github.com/octocat/juice-shop).

Cliquez sur l'onglet Actions dans la barre de navigation supérieure.

Dans la barre latérale de gauche, sous Workflows, sélectionnez CodeMender Security Scan & SARIF Export.

Déclenchez ou affichez l'exécution du workflow :

Déclencheur automatique : si une exécution automatique déclenchée par votre push est listée, cliquez directement dessus pour surveiller l'exécution en direct.

Déclencheur manuel à la demande (workflow_dispatch) : si aucune exécution n'a encore démarré, cliquez sur le bouton Exécuter le workflow ▾ à droite, assurez-vous que Branch: master est sélectionné (laissez la case deep_scan décochée pour que l'analyse de référence rapide --quick s'exécute), puis cliquez sur le bouton vert Exécuter le workflow.

Cliquez sur l'exécution en cours et sélectionnez Autonomous Code Vulnerability Scan (Analyse autonome des failles du code) pour voir le workflow se lancer en temps réel.

Dans codemender-scan.yml : routage des analyses en fonction des événements

Pendant que l'analyse de référence --quick s'exécute dans le cloud (environ 3 à 5 minutes), examinez comment codemender-scan.yml (lignes 118 à 155) achemine chaque événement GitHub vers son mode d'analyse dédié dans l'exécuteur :

# Excerpt from .github/workflows/codemender-scan.yml
if [ "${{ github.event_name }}" = "pull_request" ]; then
 cm find . \
   --diff="origin/${{ github.base_ref }}" \
   --diff-workers=16 \
   --fail-on="CRITICAL,HIGH" \
   --sandbox=false --yes --bypass-warning || status=$?
elif [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event.inputs.deep_scan }}" = "true" ]; then
 cm find . \
   --deep-workers=8 \
   --sandbox=false --yes --bypass-warning || status=$?
else
 cm find . \
   --quick \
   --sandbox=false --yes --bypass-warning || status=$?
fi

Configuration du runner renforcé ( lignes 27 à 117) : ignore les forks externes non approuvés et les RP dependabot[bot], extrait avec persist-credentials: false, met en cache ~/.local/bin/cm et ~/.codemender/state.db, et exécute cm health --strict avant de consommer le quota du modèle.

Limites du bac à sable sans interface graphique (--sandbox=false --yes --bypass-warning) : désactive l'isolation de l'espace de noms utilisateur Linux (restreinte dans les conteneurs GitHub Actions non privilégiés) tout en maintenant les limites du chemin d'accès de l'espace de travail (project_paths) et command_policy.yaml.

Exportation SARIF et d'artefacts protégée par un code de sortie ( lignes 147 à 194) : définit steps.scan.outputs.completed=true strictement lorsque cm find se termine par 0 (propre) ou 1 (seuil --fail-on atteint). Cela garantit que les rapports SARIF (cm report -f sarif avec les scores de gravité CVSS), les tables $GITHUB_STEP_SUMMARY (cm report -f md) et les artefacts codemender-findings.json sont toujours publiés lorsque --fail-on bloque une demande d'extraction, tout en ignorant l'exportation en cas d'erreurs de configuration ou de capacité (10–60) afin que les fichiers SARIF vides ne ferment jamais les alertes existantes.

7. Inspecter les alertes et le tableau de bord de sécurité de l'analyse de code GitHub

Une fois le workflow de push de référence terminé, GitHub traite le fichier SARIF importé et remplit à la fois le résumé de l'exécution des actions et l'onglet "Security" (Sécurité) du dépôt.

Étape 1 : Inspectez le récapitulatif du job natif sur GitHub Actions

Chaque exécution de workflow ajoute un tableau récapitulatif Markdown (cm report -f md) directement à la vue d'ensemble de l'exécution de GitHub Actions :

Dans votre dépôt GitHub, cliquez sur l'onglet Actions.

Sélectionnez l'exécution CodeMender Security Scan & SARIF Export terminée (les audits de push de la branche de référence se terminent par une coche verte ✅ après la publication des résultats SARIF).

Faites défiler la page jusqu'à la section 🛡️ Résumé de l'analyse de sécurité CodeMender pour inspecter la répartition des résultats :

🔒 Rapport de sécurité CodeMender

Résumé

Nombre total de résultats : 28

Gravité

Nombre

🔴 CRITIQUE

6

🟠 ÉLEVÉ

16

🟡 MOYENNE

6

État

Nombre

🔴 OUVERT

28

Résultats

ID

Gravité

Confiance

État

Solution

Fichier

Title

c1b96b9a

🔴 CRITIQUE

100 %

OUVERTE

—

routes/userProfile.ts

Exécution de code à distance via l'injection de code côté serveur dans le profil utilisateur

cd47b38a

🔴 CRITIQUE

100 %

OUVERTE

—

routes/login.ts

Injection SQL dans la route d'authentification des utilisateurs

a47a9e45

🔴 CRITIQUE

100 %

OUVERTE

—

routes/b2bOrder.ts

Exécution de code à distance via une évasion de bac à sable dans le traitement des commandes B2B

Étape 2 : Explorez le tableau de bord centralisé de l'analyse de code

Dans la barre de navigation supérieure de votre dépôt GitHub, cliquez sur l'onglet Security and quality (Sécurité et qualité) ou Security (Sécurité).

Dans la barre latérale de gauche, sous Résultats, sélectionnez Analyse du code.

Si plusieurs outils sont actifs, filtrez Outil sur CodeMender (is:open branch:master tool:CodeMender) pour inspecter les alertes mappées avec des badges de gravité CVSS natifs :

Badge de gravité

Titre de la faille

Emplacement détecté

Branch

🔴 Critique

Exécution de code à distance via l'injection de code côté serveur dans le profil utilisateur

routes/userProfile.ts:58

master

🔴 Critique

Injection SQL dans la route d'authentification des utilisateurs

routes/login.ts:34

master

🔴 Critique

Exécution de code à distance via une évasion de bac à sable dans le traitement des commandes B2B

routes/b2bOrder.ts:21

master

Cliquez sur Injection SQL dans la route d'authentification des utilisateurs (routes/login.ts:34) pour examiner le flux de données corrompu et l'analyse de la cause principale synthétisée par Gemini.

8. Bloquer une demande d'extraction non sécurisée avec l'analyse différentielle

Votre analyse de référence a révélé 28 failles préexistantes dans OWASP Juice Shop. Avec les analyseurs statiques traditionnels, ces 28 résultats hérités feraient échouer chaque demande d'extraction future jusqu'à ce que l'intégralité du backlog soit corrigée, ce qui obligerait les équipes à désactiver le blocage des fusions.

Vous allez maintenant tester la porte AST différentielle de demande d'extraction de CodeMender (--diff + --fail-on="CRITICAL,HIGH") en action : ouvrez une demande d'extraction qui introduit une nouvelle faille et observez CodeMender isoler le delta, bloquer la fusion en 15 à 25 secondes environ et annoter les lignes incriminées.

Étape 1 : Ouvrez une demande d'extraction introduisant une faille d'injection de commande

Dans Cloud Shell (dans l'espace de travail de votre dépôt cloné), créez une branche de fonctionnalité, ajoutez une route Express contenant une faille d'injection de commande d'OS, puis ouvrez une demande d'extraction sur votre duplication :

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"
PRIMARY_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's@^origin/@@')

# Reset any previous demo PR/branch so this step can be re-run cleanly
gh pr close feat/diagnostics --repo "${GITHUB_REPOSITORY}" --delete-branch 2>/dev/null || true
git checkout "${PRIMARY_BRANCH}"
git checkout -B feat/diagnostics

# Introduce an Express endpoint vulnerable to OS Command Injection (CWE-78)
cat << 'EOF' > routes/diagnostics.ts
import { execSync } from 'node:child_process'
import { type Request, type Response } from 'express'

export function systemDiagnostics () {
 return (req: Request, res: Response) => {
   const host = String(req.query.host ?? '127.0.0.1')
   const output = execSync(`ping -c 1 ${host}`).toString()
   res.status(200).json({ status: 'ok', output })
 }
}
EOF

git add routes/diagnostics.ts
git commit -m "feat: add network diagnostics endpoint"
git push -f -u origin feat/diagnostics

gh pr create \
 --repo "${GITHUB_REPOSITORY}" \
 --base "${PRIMARY_BRANCH}" \
 --head feat/diagnostics \
 --title "feat: add network diagnostics endpoint" \
 --body "Adds a ping diagnostics handler."

Étape 2 : Vérifiez la porte de fusion différentielle et l'annotation de RP intégrée

Ouvrez l'URL de la demande d'extraction affichée à la fin du résultat du terminal.

Faites défiler la page jusqu'à la section Checks (Vérifications) en bas de la page de conversation de la demande d'extraction, puis observez l'analyse autonome des failles du code :

Vitesse delta : au lieu d'analyser les plus de 680 fichiers du dépôt (~3 à 5 minutes), cm find . --diff="origin/${PRIMARY_BRANCH}" limite l'analyse strictement à routes/diagnostics.ts (et à tous les appelants à un saut), ce qui permet de terminer l'analyse en ~15 à 25 secondes.

Isolation de la dette héritée et blocage de la fusion : aucune des 28 vulnérabilités héritées non modifiées de Juice Shop n'échoue à la vérification. Seule l'injection de commande CRITICAL nouvellement introduite déclenche --fail-on="CRITICAL,HIGH", qui se termine avec le code d'état 1 (❌ rouge) pour bloquer la fusion de la demande d'extraction.

Cliquez sur l'onglet Files changed (Fichiers modifiés) en haut de la demande d'extraction :

Comme la protection du code de sortie du workflow (steps.scan.outputs.completed == 'true') exporte et importe toujours results.sarif lorsque --fail-on se termine avec le code 1, l'analyse de code GitHub affiche une annotation de sécurité intégrée CodeMender — Critical directement sous execSync dans routes/diagnostics.ts.

Étape 3 : Nettoyez la RP de test et revenez à la branche principale

Repassez sur la branche principale dans votre espace de travail Cloud Shell et fermez la demande d'extraction de test non sécurisée avant de passer à la correction autonome :

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"
PRIMARY_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's@^origin/@@')
git checkout "${PRIMARY_BRANCH}"
gh pr close feat/diagnostics --repo "${GITHUB_REPOSITORY}" --delete-branch
git branch -D feat/diagnostics 2>/dev/null || true

9. Créer le workflow de correction autonome et de RP automatique

Maintenant que votre barrière de demande d'extraction empêche l'introduction de nouvelles failles dans la codebase, vous allez déployer la correction autonome (.github/workflows/codemender-remediate.yml) pour corriger activement les failles existantes et ouvrir des demandes d'extraction prêtes à être examinées.

Étape 1 : Téléchargez le fichier du workflow de correction

CodeMender propose deux modèles de correction en fonction de la visibilité du dépôt :

Dépôts publics/Open Source (codemender-remediate.yml) : Mode de divulgation responsable : liens vers les alertes SARIF de GitHub Code Scanning sans exposer publiquement les vecteurs d'exploitation bruts.

Dépôts privés/d'entreprise (codemender-remediate-private-repo.yml) : Mode de preuve d'audit interne : intègre les artefacts de vérification (PLAN.md, REPORT.md, exploit.sh) dans des sections de RP réductibles tout en les excluant des commits Git.

Téléchargez le workflow de correction public-safe dans votre dépôt :

mkdir -p .github/workflows
curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-remediate.yml \
 -o .github/workflows/codemender-remediate.yml

Étape 2 : Validez et déclenchez le workflow de correction autonome

Validez et déployez le workflow correctif dans votre branche principale :

git add .github/workflows/codemender-remediate.yml
git commit -m "ci: add CodeMender autonomous remediation workflow"
git push origin $(git branch --show-current)

Dans votre navigateur, accédez à l'onglet Actions de votre dépôt GitHub.

Dans la barre latérale de gauche, sous Workflows, sélectionnez CodeMender Autonomous Security Remediation & Auto-PR.

Cliquez sur le menu déroulant vert Run workflow (Exécuter le workflow) à droite :

Utiliser le workflow de : assurez-vous que la branche par défaut (master) est sélectionnée.

ID ou préfixe du résultat spécifique à corriger : saisissez le préfixe à huit caractères pour routes/login.ts que vous avez noté à l'étape 7 (par exemple, cd47b38a). Si vous laissez ce champ vide, la correction par lot est exécutée sur tous les résultats critiques et élevés ouverts (environ 10 à 15 minutes). Le ciblage d'un seul ID prend environ 45 à 60 secondes.

Cliquez sur le bouton vert Exécuter le workflow dans la fenêtre pop-over, puis ouvrez l'exécution en cours.

Déclenchez le workflow de correction de sécurité autonome CodeMender via le menu déroulant &quot;Exécuter le workflow&quot;.

Dans codemender-remediate.yml : synthèse autonome des correctifs

Pendant que CodeMender synthétise le correctif dans le cloud (environ 30 à 45 secondes), examinez comment codemender-remediate.yml (lignes 111 à 184) orchestre la correction dans l'exécuteur :

Zero-Scan Resume (cm report import) : télécharge l'artefact codemender-findings.json à partir du workflow d'analyse et l'importe dans l'espace de travail (cm report import -f codemender-findings.json), en revenant à cm find . --quick uniquement si aucun artefact antérieur n'existe.

Synthèse de correctifs sans interface graphique (cm fix) : épingle project_paths à $GITHUB_WORKSPACE, redirige < /dev/null pour éviter les blocages interactifs et transmet --no-reset pendant les boucles de traitement par lot afin que les correctifs cumulatifs soient conservés d'un résultat à l'autre :

# Executed inside the GitHub Actions runner (codemender-remediate.yml)
cm fix "${SPECIFIC_TARGET}" --sandbox=false --yes --bypass-warning < /dev/null

Clean Production Commits ( lignes 155 à 252) : purge .cm_project, .exploit/ et les fichiers temporaires via .git/info/exclude avant que peter-evans/create-pull-request@v8 n'ouvre la branche (codemender/auto-remediation-${{ github.run_id }}), en validant strictement les modifications du code de production :

--- a/routes/login.ts
+++ b/routes/login.ts
@@ -28,8 +28,8 @@ module.exports = function login () {
-    models.sequelize.query(`SELECT * FROM Users WHERE email = '${req.body.email || ''}' AND password = '${security.hash(req.body.password || '')}' AND deletedAt IS NULL`, { model: models.User })
+    models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', {
+      replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') },
+      model: models.User
+    })

Étape 3 : Examinez la demande d'extraction que vous venez d'ouvrir sur GitHub

Accédez à l'onglet Demandes d'extraction de votre dépôt et ouvrez la nouvelle demande d'extraction (par exemple, 🛡️ [CodeMender] Fix: SQL Injection in User Authentication Route).

Cliquez sur Files changed (Fichiers modifiés) pour confirmer que seul routes/login.ts est modifié, toutes les métadonnées d'exécution internes étant exclues.

Examinez la description de la demande d'extraction qui renvoie directement à l'alerte GitHub Code Scanning (SARIF) pour que le responsable de la maintenance l'approuve.

10. Résoudre les problèmes liés aux cas particuliers et aux dépôts privés

Dépôts privés sans GitHub Advanced Security (GHAS)

Les dépôts GitHub publics bénéficient d'une ingestion SARIF sans frais et illimitée pour l'analyse de code GitHub. Toutefois, si vous déployez ce workflow dans un dépôt Private Enterprise qui ne dispose pas d'une licence GitHub Advanced Security (GHAS) active, l'étape upload-sarif échouera avec le message suivant :

HTTP 403: Advanced Security must be enabled for this repository to use code scanning.

Résolution : Solution de remplacement pour le rapport HTML interactif autonome

Le générateur de rapports HTML intégré de CodeMender (cm report -f html) crée un tableau de bord de sécurité interactif et autonome, qui comprend des fiches de métriques de gravité, des extraits de code avec coloration syntaxique et numéros de ligne, ainsi qu'un lecteur de différences de correctifs intégré, sans aucune dépendance Web externe.

Pour prendre en charge les dépôts privés sans licence GHAS, mettez à jour .github/workflows/codemender-scan.yml pour archiver un artefact de rapport HTML au lieu d'importer SARIF :

Générez le rapport HTML autonome : à l'étape Export Security Reports & Publish Job Summary, exportez un tableau de bord HTML avec votre résumé Markdown à l'aide de cm report -f html > codemender-audit-report.html.

Archiver le rapport en tant qu'artefact de workflow : remplacez l'étape Upload SARIF Report to GitHub Code Scanning (github/codeql-action/upload-sarif@v4) par actions/upload-artifact@v4 configurée pour importer codemender-audit-report.html (par exemple, sous le nom d'artefact codemender-security-report).

Inspecter localement dans n'importe quel navigateur : téléchargez codemender-security-report.zip directement depuis la page de résumé de l'exécution du workflow GitHub Actions, extrayez-le et ouvrez codemender-audit-report.html dans n'importe quel navigateur Web pour un tri visuel.

Correction autonome des dépôts privés avec preuves d'audit intégrées

Dans les dépôts d'entreprise privés, les équipes d'ingénierie et de sécurité ont besoin d'une visibilité totale sur l'analyse de la cause principale, la démonstration de faisabilité du code d'exploitation et le plan de correction, sans avoir besoin de tableaux de bord d'outils externes. Cependant, l'envoi de scripts d'exploitation (exploit.sh) ou de fichiers Markdown internes (PLAN.md, LOG.md) vers la branche du dépôt pollue l'historique Git et peut déclencher de fausses alertes provenant d'autres scanners de sécurité.

Pour résoudre ce problème, déployez le workflow de correction de dépôt privé dédié (codemender-remediate-private-repo.yml) :

curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-remediate-private-repo.yml \
 -o .github/workflows/codemender-remediate.yml
git add .github/workflows/codemender-remediate.yml
git commit -m "ci: switch to private repository remediation workflow with embedded audit evidence"
git push origin $(git branch --show-current)

Fonctionnement de la correction des dépôts privés

Validation dynamique de la preuve de concept (cm verify) : synthétise et teste un exploit fonctionnel avant de générer le correctif pour confirmer l'exploitabilité, en ignorant automatiquement cm fix si la validation marque un résultat non exploitable comme DISMISSED.

Embedded PR Audit Collapsibles : extrait REPORT.md, PLAN.md et exploit.sh dans /tmp/codemender-evidence/ et les formate directement dans la description de la demande d'extraction dans des blocs réductibles <details open> pour que l'examinateur puisse les inspecter en un clic.

Archivage des artefacts : archive l'intégralité du dossier de preuves via actions/upload-artifact@v4.

Pristine Git Commits : purge toutes les métadonnées d'exécution et les répertoires .exploit afin que le commit Git de la demande d'extraction ne contienne que les modifications du code de production.

Checklist de dépannage de la fédération d'identité de charge de travail (WIF)

Par défaut, google-github-actions/auth@v2 écrit un fichier de configuration d'identifiants fédérés local lors de la configuration, et l'échange de jetons OAuth 2.0 réel se produit au démarrage de cm health --strict ou cm find. Utilisez la checklist ci-dessous pour diagnostiquer les erreurs d'authentification HTTP 400 ou HTTP 403 :

Symptôme de l'erreur

Cause principale courante

Validation et correction

HTTP 403 (iam.serviceAccounts.getAccessToken refusé)

Liaison roles/iam.workloadIdentityUser manquante sur le compte de service, secret GCP_SERVICE_ACCOUNT incorrect ou iamcredentials.googleapis.com non activé.

Vérifiez que GCP_SERVICE_ACCOUNT correspond à codemender-ci-runner@.iam.gserviceaccount.com, puis exécutez la vérification de la stratégie IAM ci-dessous pour vérifier la liaison principalSet.

HTTP 400 (unauthorized_client ou condition d'attribut refusée)

Le nom (ou la casse) du dépôt OIDC –attribute-condition ne correspond pas au dépôt GitHub qui déclenche le workflow, ou le fournisseur WIF est désactivé.

Réexécutez l'étape 4 (étapes 1 et 6) en vous assurant que ${GITHUB_REPOSITORY} correspond exactement à la casse de votre owner/repo sur GitHub et que –no-disabled est appliqué.

HTTP 400 (invalid_grant lors de l'échange de jetons)

Mappage –issuer-uri incorrect ou attribute.repository=assertion.repository manquant sur le fournisseur OIDC.

Vérifiez que –issuer-uri est défini strictement sur https://token.actions.githubusercontent.com (sans barre oblique finale).

Erreur HTTP 403 temporaire immédiatement après la configuration

La propagation globale d'IAM et de la fédération d'identité de charge de travail peut prendre de 1 à 5 minutes pour les liaisons nouvellement créées.

Attendez une à deux minutes, puis cliquez sur Réexécuter les jobs ayant échoué dans GitHub Actions.

Pour inspecter la liaison Workload Identity active sur votre compte de service CI/CD dans Cloud Shell, exécutez la commande suivante :

gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" \
 --flatten="bindings[].members" \
 --filter="bindings.role=roles/iam.workloadIdentityUser"

Vérifiez que le résultat lie roles/iam.workloadIdentityUser à principalSet://iam.googleapis.com/<POOL_ID>/attribute.repository/<GITHUB_USER>/<GITHUB_REPO> :

---
bindings:
 members: principalSet://iam.googleapis.com/.../attribute.repository/<OWNER>/<REPO>
 role: roles/iam.workloadIdentityUser

Résoudre les problèmes liés aux vérifications préliminaires CI/CD et aux codes de sortie de la CLI

Les commandes CodeMender (cm health --strict, cm find, cm verify et cm fix) renvoient des codes de sortie déterministes afin que les pipelines CI/CD puissent immédiatement distinguer les résultats de sécurité des erreurs de configuration ou de service :

Code de sortie

Catégorie

Cause principale et correction courantes

0

Opération réussie

Les vérifications d'état ont réussi ou l'analyse s'est terminée sans résultat bloquant.

1

Findings / General

–fail-on a détecté des failles CRITICAL ou HIGH bloquantes dans une demande d'extraction (échec attendu de la porte de fusion).

10

credentials

Échec de l'échange de jetons WIF OAuth/ADC (400/401). Vérifiez GCP_WORKLOAD_IDENTITY_PROVIDER, GCP_SERVICE_ACCOUNT et la liaison roles/iam.workloadIdentityUser ci-dessus.

20

config

Syntaxe .codemender/config.yaml ou ~/.codemender/config.yaml incorrecte.

30

reachability

L'exécuteur ne peut pas accéder à aiplatform.googleapis.com (DNS, proxy, interruption de service ou VPC Service Controls).

40

authorization

Le compte de service ne dispose pas de l'autorisation roles/aiplatform.user sur le projet cible, ou cloudresourcemanager.googleapis.com/aiplatform.googleapis.com est désactivé.

50

timeout

La vérification préliminaire cm health a dépassé le délai de 30 secondes.

60

capacity

L'agent a atteint sa limite de tâches actives simultanées. Relancez le workflow après un court délai.

Pour d'autres erreurs d'exécution, telles que la résolution de la branche de base de la différence Git (fetch-depth: 0), les retards de propagation des ressources ou les autorisations de création de demandes d'extraction GitHub Actions, consultez le guide de dépannage officiel de la CI/CD CodeMender.

11. Effectuer un nettoyage des ressources

Pour éviter une consommation continue de ressources ou nettoyer les configurations de test dans vos environnements Google Cloud et GitHub, procédez comme suit.

Étape 1 : Supprimez les secrets du dépôt GitHub et désactivez les workflows via la CLI gh

Utilisez la CLI GitHub (gh) pour supprimer proprement les secrets Actions du dépôt et désactiver les workflows CodeMender :

# Delete the repository Actions secrets
gh secret delete GCP_WORKLOAD_IDENTITY_PROVIDER --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh secret delete GCP_SERVICE_ACCOUNT --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true

# Disable the CodeMender workflows to prevent unwanted automatic triggers
gh workflow disable codemender-scan.yml --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh workflow disable codemender-remediate.yml --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true

Étape 2 : Désactivez ou supprimez les ressources de la fédération d'identité de charge de travail Google Cloud

Les pools d'identités de charge de travail, les fournisseurs et les comptes de service n'entraînent aucun coût d'inactivité lorsqu'ils n'échangent pas de jetons. Choisissez le mode de nettoyage qui correspond à votre workflow :

Option A : Suspendre l'accès (recommandé si vous prévoyez de réexécuter le script dans ce projet) : désactive immédiatement l'échange de jetons OIDC sans déclencher la conservation de 30 jours de suppression réversible de Cloud IAM Google Cloud ni les délais de propagation du compte de service uniqueId :

gcloud iam workload-identity-pools providers update-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --disabled \
 --project="${PROJECT_ID}"

Option B : suppression complète : supprime le fournisseur WIF, le pool (conservé à l'état DELETED pendant 30 jours) et le compte de service dédié :

# Delete Workload Identity Provider
gcloud iam workload-identity-pools providers delete "${WORKLOAD_IDENTITY_PROVIDER}" \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --project="${PROJECT_ID}" \
 --quiet

# Delete Workload Identity Pool
gcloud iam workload-identity-pools delete "${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --project="${PROJECT_ID}" \
 --quiet

# Delete CI/CD Service Account
gcloud iam service-accounts delete "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" \
 --quiet

12. Félicitations

Félicitations ! Vous avez terminé l'atelier de programmation Sécuriser votre pipeline CI/CD avec CodeMender.

Vous avez conçu, créé et automatisé un pipeline DevSecOps de niveau production et sans confiance à l'aide de la fédération d'identité de charge de travail Google Cloud, de CodeMender et de GitHub Actions.

Points abordés

Authentification sans clé Zero Trust : élimination des clés JSON de compte de service risquées et de longue durée en associant des jetons OIDC GitHub éphémères à Google Cloud IAM via la fédération d'identité de charge de travail (WIF).

Analyse AST différentielle des RP et suppression du bruit existant : analyse continue limitée aux fichiers modifiés et aux dépendances (--diff="origin/$BASE_REF"), isolant la dette technique existante ([LEGACY / UNTOUCHED]) pour maintenir les boucles de rétroaction des développeurs à moins de 15 secondes.

Rapports multiformats et résumés de jobs natifs : combinaison du format OASIS SARIF v2.1.0 pour l'analyse centralisée du code GitHub avec le format Markdown natif (cm report -f md >> $GITHUB_STEP_SUMMARY) pour une visibilité instantanée des dirigeants directement sur les pages d'exécution des workflows d'intégration continue.

Correction autonome avec examen humain : nous sommes passés des notifications d'alerte passives à des pipelines de correction actifs qui synthétisent de manière autonome les correctifs de code proposés, les vérifient par rapport aux suites de tests de régression et ouvrent des demandes d'extraction d'examen avec des artefacts d'audit pour approbation par un ingénieur.

Contrôles de qualité automatisés : mise en place d'une protection stricte des branches et d'un contrôle des fusions (--fail-on) pour empêcher les failles dangereuses d'atteindre la production.

Transfert d'état basé sur les artefacts et isolation de l'espace de travail : les résultats ont été transférés de manière fluide entre les jobs CI à l'aide de cm report import, tandis que .git/info/exclude a été utilisé pour préserver l'historique Git d'origine et éviter les fuites d'identifiants.

Changement d'état d'esprit des développeurs

Pratique DevSecOps traditionnelle

Pipeline CI/CD autonome CodeMender

Dump d'alertes passif : les scanners affichent des journaux de terminal bruts ou des listes d'erreurs statiques, ce qui reporte entièrement la charge du tri sur les développeurs.

Co-développeur actif : synthétise les correctifs de code vérifiés et ouvre des demandes d'extraction prêtes à être fusionnées pour approbation par l'ingénieur.

Nombre élevé de faux positifs : les heuristiques AST statiques signalent des milliers de failles théoriques sans preuve d'exploitabilité.

Vérification des exploits à deux niveaux : la génération dynamique de tests en bac à sable (cm verify) confirme la vulnérabilité réelle, ce qui élimine les faux positifs.

Stockage risqué des secrets : les clés JSON de compte de service à longue durée de vie stockées dans des secrets d'intégration continue risquent d'être divulguées accidentellement et d'entraîner une prolifération des identifiants.

WIF zéro confiance : authentification sans clé via des jetons OIDC éphémères échangés avec Google Cloud STS à la demande.

Nouvelles analyses monolithiques : chaque commit déclenche des audits complets du dépôt, ce qui retarde les workflows d'intégration continue et gaspille des jetons coûteux.

Routage AST basé sur les événements : les demandes d'extraction exécutent des analyses AST différentielles de 15 secondes (–diff), tandis que les tâches Cron effectuent des audits approfondis.

Historique du dépôt pollué : scripts d'exploitation temporaires et journaux d'attaque commités directement dans les branches du dépôt.

Hygiène de l'espace de travail d'entreprise : les preuves d'attaque sont intégrées de manière propre dans les descriptions de RP et les artefacts de workflow, ce qui permet de préserver l'intégrité des commits de code.

Étapes suivantes

🚀 Poursuivez le parcours d'apprentissage CodeMender :

Partie 1 : Sécuriser votre application avec CodeMender : maîtrisez la découverte autonome des failles dans les dépôts, la vérification des exploits de preuve de concept et la synthèse des correctifs locaux.

Shift Left Locally & Serverless Cloud Native CI/CD : explorez les implémentations de référence du guide officiel sur l'intégration et la livraison continues pour Google Cloud Build (cloudbuild.yaml) et les hooks de pré-commit Git locaux (cm find . --diff --staged).

📖 Consultez la documentation et les ressources :

Guide officiel d'intégration CI/CD de Google Cloud CodeMender

Documentation officielle de Google Cloud CodeMender

Dépôt de modèles de démarrage GitHub Actions CodeMender

Documentation sur la fédération d'identité de charge de travail Google Cloud

💡 Appliquer à vos propres dépôts :

Dupliquez le workflow de démarrage et sécurisez les dépôts Python, Go, Java, Rust et Node.js de votre organisation avec CodeMender.