Aller au contenu

Gitleaks — usage, précautions et dépannage CI

Guide pratique pour les dépôts DYNORS qui incluent le job gitleaks (template .gitlab/ci/gitleaks.template.yml + .gitleaks.toml). Complète le runbook technique dans le workspace dynors (copie / miroir selon organisation).


1. Ce que fait le job CI

Contexte pipeline Comportement Gitleaks Intérêt
Merge request gitleaks detect avec --log-opts "$CI_MERGE_REQUEST_DIFF_BASE_SHA..HEAD" Vérifie tous les commits de la MR par rapport à la branche cible. Un secret introduit puis « retiré » dans un commit ultérieur de la même MR peut encore être vu si Git expose le blob dans cette plage (selon l’historique).
Push sur main / master (hors MR) gitleaks detect avec --no-git Ne scanne que l’arborescence checkoutée (fichiers tels qu’à HEAD). Évite d’échouer sur d’anciens commits encore présents dans un clone shallow alors que les fichiers actuels sont déjà corrigés.

À retenir

Sur main, le CI ne « pardonne » pas l’historique : il impose que les fichiers présents dans le job ne contiennent pas de motifs interdits. Sur une MR, le périmètre est la plage de commits de la demande de fusion.


2. Précaution n°1 : la même version qu’en CI

L’image GitLab utilise zricethezav/gitleaks:v8.18.0. Une version locale plus récente (ex. Homebrew 8.30+) peut ne pas signaler ce que la CI signale, ou l’inverse selon l’évolution des règles par défaut (useDefault = true dans .gitleaks.toml).

Recommandation avant de pousser une doc sensible ou de clore un incident « Gitleaks » :

docker run --rm -v "$(pwd)":/repo -w /repo zricethezav/gitleaks:v8.18.0 \
  detect --source=/repo --config=/repo/.gitleaks.toml --no-git -v

Pour une MR, rapprocher du mode CI (avec historique local complet) :

docker run --rm -v "$(pwd)":/repo -w /repo zricethezav/gitleaks:v8.18.0 \
  detect --source=/repo --config=/repo/.gitleaks.toml \
  --log-opts "<SHA_BASE>..HEAD" -v

Remplacez <SHA_BASE> par le commit de la branche cible (équivalent origin/main au moment de la branche).


3. Précautions rédaction (doc, exemples JSON, scripts)

3.1 Jetons GitLab (glpat-, gloas-, …)

La config DYNORS définit des règles du type glpat- + au moins 20 caractères alphanumériques / tirets. Donc :

  • Interdit : coller un vrai PAT, même « pour un test rapide ».
  • À éviter : tout pseudo-exemple où le préfixe glpat- est suivi d’au moins 20 caractères a-z, 0-9, -, _ — cela matche la règle même s’il est « bidon » (préférer glpat-EXAMPLE-DEMO ou glpat-EXAMPLE).
  • Préférer : les formes explicitement allowlistées dans .gitleaks.toml, par ex. glpat-EXAMPLE, ou une formulation sans préfixe glpat- (variable d’environnement décrite en texte : « coller le token créé dans GitLab »).

3.2 JWT et chaînes en base64

Toute chaîne qui ressemble à un JWT (eyJ…) ou à une clé API longue peut tomber dans generic-api-key (règles par défaut Gitleaks). En documentation :

  • Utiliser un libellé du type <JWT retourné par l’endpoint …> ou <jeton à coller depuis …>.
  • Éviter les faux JWT tronqués du type eyJhbGciOiJIUzI1NiIs... dans des blocs copiables.

3.3 Faux positifs « métier »

Des identifiants d’exemple du type produit-order-00123 (lettres, tirets, chiffres) peuvent être classés generic-api-key selon la version et le contexte. Préférer des libellés clairement non secrets : exemple-ref-commande, REF-EXEMPLE, CMD-DEMO, etc.

3.4 Fichiers générés

Les dossiers build/, .gradle/, node_modules/, etc. sont en général exclus via [allowlist].paths du .gitleaks.toml. Ne pas committer de rapports gitleaks-report.json contenant des extraits sensibles.


4. Le pipeline échoue : diagnostic pas à pas

Étape A — Récupérer le rapport

Le job publie en échec un artifact gitleaks-report.json (JSON tableau de findings). Téléchargez-le depuis GitLab (job gitleaksBrowse / Télécharger).

Extraits utiles avec jq :

jq '.[] | {RuleID, File, StartLine, Secret: .Secret[0:40]}' gitleaks-report.json
jq '.[] | .Fingerprint' gitleaks-report.json

Étape B — Reproduire localement

  1. Se placer à la même révision que le pipeline (CI_COMMIT_SHA).
  2. Lancer Gitleaks en image v8.18.0 (voir section 2).
  3. Si le job était une MR, utiliser --log-opts avec la même base que GitLab ; si main, utiliser --no-git.

Étape C — Classifier la finding

Nature Action
Vrai secret (PAT, mot de passe, clé privée, token Vault prod) Révoquer / faire tourner le secret côté fournisseur ; ne pas se contenter d’une entrée allowlist. Puis retirer toute trace du fichier ou réécrire l’historique si la politique sécu l’exige.
Faux positif documenté Adapter le texte (préféré) ou, exceptionnellement, étendre [allowlist].regexes dans .gitleaks.toml avec un motif très étroit et un commentaire de justification.
Secret uniquement dans l’historique (scan avec Git, pas --no-git) Rotation du secret ; ensuite git filter-repo / outil équivalent si la surface d’exposition impose de purger l’historique (coordination équipe).

5. Exemples (cas fréquents)

Exemple 1 — « Ça passe chez moi, pas en CI »

  • Cause typique : Gitleaks 8.30 en local vs 8.18 dans le runner.
  • Action : reproduire avec Docker v8.18.0 ; ajuster l’exemple dans la doc pour respecter les règles de cette version.

Exemple 2 — PAT dans un fichier Markdown

  • Symptôme : RuleID: gitlab-pat ou generic-api-key, fichier *.md.
  • Action : remplacer par glpat-EXAMPLE ou texte sans token ; vérifier qu’aucun paragraphe ne cite un vrai glpat-… long.

Exemple 3 — MR verte mais plainte sur « historique »

  • Le job MR scanne une plage de commits. Si un contributeur a ajouté un secret au commit A et l’a enlevé au commit B, la plage peut encore contenir A.
  • Action : interactive rebase / squash pour que le secret n’ait jamais existé dans la branche, ou ouvrir une nouvelle branche propre depuis main et cherry-pick proprement les bons commits.

Exemple 4 — main rouge après avoir « nettoyé » les fichiers

  • Cause : CI en mode historique complet sur un clone qui inclut encore d’anciens commits avec blobs sensibles non présents à HEAD.
  • Action côté infra : pour les dépôts concernés, le template peut utiliser --no-git sur les pipelines push hors MR (comportement dynors-core documenté dans le template). Les vrais secrets en tête de branche doivent quand même être corrigés.

6. Références internes

Ressource Emplacement
Runbook détaillé (hook, migration, scan historique) Workspace dynorsdocs/runbooks/gitleaks-secret-scanning.md
Config canonique .gitleaks.toml à la racine de chaque sous-dépôt ; ne pas diverger sans revue sécu
Template CI .gitlab/ci/gitleaks.template.yml (include local ou projet de templates)
Stratégie Vault, secrets CI & feuille de route Vault, secrets CI & feuille de route
Règle / ADR secrets Workspace → vault-secrets-dynors.mdc, docs/adr/ADR-2026-04-26-vault-strategie-completion.md

7. Résumé « checklist » avant push

  • [ ] Aucun glpat- / gloas- / … qui ressemble à un vrai jeton dans les fichiers suivis.
  • [ ] Exemples JWT / API : placeholders textuels, pas de préfixes eyJ en copier-coller.
  • [ ] Vérification locale avec gitleaks:v8.18.0 (Docker) alignée sur le mode du pipeline (--no-git vs --log-opts).
  • [ ] En cas d’échec : télécharger gitleaks-report.json, identifier RuleID + fichier + ligne, corriger ou ouvrir un ticket sécu si fuite réelle.