Si votre pipeline GitLab CI/CD utilise des images Docker non épinglées, des includes sur main ou un build basé sur Docker-in-Docker, ou si vos workflows GitHub Actions référencent encore des actions tierces par tag mutable, vous exposez votre chaîne à une attaque de supply chain. Plumber est un scanner de sécurité de pipelines : vous créez une configuration minimale au schéma v2.0, vous lancez plumber analyze, vous lisez trois ou quatre problèmes concrets, puis vous intégrez le contrôle dans votre CI avec le composant officiel. Ce guide s'adresse aux débutants et intermédiaires ; on commence volontairement par la CLI, ensuite par le composant GitLab, puis on termine par le PBOM, le score A-E et la Platform.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Créer une configuration minimale au schéma v2.0 avec
plumber config init, puis la valider avant le premier scan - Migrer une configuration v1 existante vers le schéma v2.0 avec
plumber config migrate - Lancer une analyse de sécurité locale sur un dépôt GitLab ou un dépôt GitHub et comprendre l'auto-détection
- Corriger les failles fréquentes : image non épinglée, action tierce non pinnée par SHA, source d'action non autorisée, branche non protégée
- Ajouter le composant GitLab CI/CD officiel sans créer de doubles pipelines ni de job
.preinutilisable - Exporter un PBOM et l'exploiter avec Trivy ou Grype
Qu'est-ce que Plumber ?
Section intitulée « Qu'est-ce que Plumber ? »Plumber est un scanner de sécurité pour GitLab CI/CD et GitHub Actions. Côté GitLab, il interroge l'API du projet et lit la configuration mergée ; côté GitHub, il analyse en local les fichiers de .github/workflows via le moteur Rego. Dans les deux cas, il signale les écarts les plus dangereux : images non fiables, tags mutables, actions tierces non épinglées par SHA, sources d'actions non autorisées, branches non protégées, includes obsolètes, scripts téléchargés sans vérification ou usage de Docker-in-Docker. Chaque problème porte un code d'issue (ISSUE-XXX) que vous pouvez détailler avec plumber explain.
Par où commencer ?
Section intitulée « Par où commencer ? »| Votre situation | Porte d'entrée recommandée | Pourquoi |
|---|---|---|
| Vous découvrez Plumber | CLI locale | Vous comprenez d'abord ce que l'outil détecte et comment lire la sortie |
| Vous voulez l'ajouter rapidement à un pipeline existant | Composant GitLab CI/CD | Vous évitez d'écrire un job manuel complet |
| Vous devez centraliser plusieurs projets | Platform | Vous passez de l'analyse projet par projet à la gouvernance |
Prérequis
Section intitulée « Prérequis »Avant de lancer votre premier scan, vous avez besoin de :
- un dépôt Git lié à un projet GitLab ou GitHub ;
- côté GitLab : un token avec les scopes
read_apietread_repository(rôle Maintainer sur le projet, ou un Project Access Token doté de ce rôle) ; - côté GitHub : la CLI
ghauthentifiée (gh auth login). Plumber lit le token depuis~/.config/ghautomatiquement ; aucune variable d'environnement n'est nécessaire ; - un terminal interactif si vous voulez utiliser
plumber config init; - au moins une configuration
.plumber.yamlsi vous passez par la CLI.
Installation
Section intitulée « Installation »mise use -g github:getplumber/plumberbrew tap getplumber/plumberbrew install getplumber/plumber/plumber# Télécharger une version précise depuis la page Releases# https://github.com/getplumber/plumber/releases# Toujours épingler la version, pas :latestdocker pull getplumber/plumber:0.3.82Vérification :
plumber versionLa sortie doit afficher plumber version 0.3.82 (ou la version plus récente que vous avez installée) avec le hash de commit et la date de build.
Premier scan local en 5 minutes
Section intitulée « Premier scan local en 5 minutes »Le chemin le plus simple est toujours le même : configurer, valider, scanner, corriger. Plumber détecte automatiquement le provider en lisant votre remote origin : si l'URL pointe vers GitLab, il bascule sur le chemin API GitLab ; si elle pointe vers GitHub, il scanne en local le dossier .github/workflows via le moteur Rego.
-
Créez une configuration minimale avec le wizard interactif
Fenêtre de terminal plumber config initplumber config validateplumber config initpose des questions ciblées puis génère un fichier court au schéma v2.0, adapté à votre projet.plumber config validatevérifie ensuite que le YAML est correct et signale les fautes de frappe dans les noms de contrôles ou de clés. -
Authentifiez-vous auprès de votre provider
Côté GitLab, créez un token via User Settings -> Access Tokens avec
read_apietread_repository, puis exportez-le :Fenêtre de terminal export GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxxCôté GitHub, authentifiez-vous une fois via la CLI
gh, Plumber lit ensuite le token depuis~/.config/ghsans variable d'environnement :Fenêtre de terminal gh auth logingh auth status -
Lancez l'analyse depuis le dépôt Git
Fenêtre de terminal cd mon-projetplumber analyzeSi votre dépôt possède un remote
originpointant vers GitLab ou GitHub, Plumber détecte automatiquement le provider, l'URL et le chemin du projet. Sur GitHub, l'analyse repose sur les fichiers locaux : aucun appel API n'est requis pour les contrôles workflow (l'API n'est appelée que pour la protection de branche). -
Lisez d'abord le résumé, pas toute la sortie
Cherchez en priorité :
- le pourcentage de conformité global ;
- les contrôles en échec ;
- les codes
ISSUE-XXX; - le nom précis du job ou du workflow concerné ;
- le score A-E et les points sur 100.
Exemple réel : pipeline GitLab opensource
Section intitulée « Exemple réel : pipeline GitLab opensource »Sur le dépôt de lab Bob74/pipeline-craft, la commande suivante analyse une branche de solution :
export GITLAB_TOKEN=glpat-xxxxplumber analyze --branch solution/lab-12 --scoreVoici le résumé observé :
Auto-detected GitLab URL: https://gitlab.comAuto-detected project: Bob74/pipeline-craftUsing configuration: .plumber.yamlAnalyzing project: Bob74/pipeline-craft on https://gitlab.com
Status: FAILED ✗Total (required: 100%): 72.7%
Controls in failure:- ISSUE-103 ×5 : images non épinglées par digest- ISSUE-412 ×1 : Docker-in-Docker détecté- ISSUE-401 ×5 : jobs hardcodés
Plumber Score: D (34 / 100 pts) Poor - High-severity issues impacting the pipeline Critical 0 High 6 Medium 6 Low 0Exemple réel : workflow GitHub open source
Section intitulée « Exemple réel : workflow GitHub open source »Le provider GitHub ne nécessite ni --gitlab-url ni GITLAB_TOKEN. Une fois gh auth login fait, lancez simplement :
git clone <url-du-depot>cd <depot>plumber config generate --output .plumber.yaml --forceplumber analyze --scoreVoici l'extrait d'un scan réel mené sur un projet open source très populaire (plusieurs dizaines de milliers d'étoiles), dont les workflows référencent 368 actions. La sortie est volontairement résumée et anonymisée :
Third-party actions must be pinned by commit SHA (0.0% compliant) Total Action Refs: 368 Pinned By SHA: 79 Not Pinned By SHA: 148 Trusted-Owner Exempt: 141
HIGH [ISSUE-701] job "…" references action "…@main" with a mutable ref - pin by commit SHA instead HIGH [ISSUE-713] job "…" references action "…" from an unauthorized source - restrict actions to authorized owners or an allowlist CRIT [ISSUE-703] action "…" carries a published security advisory
Status: FAILED ✗Total (required: 100%): 70.6%
Plumber Score Critical 1 High 127 Medium 119 Low 0 ▲ Critical malus applied (points capped at 30 while any Critical remains)ISSUE-701 est l'apport phare du provider GitHub : il détecte les uses: qui référencent une action tierce par tag ou branche au lieu d'un SHA de 40 caractères. C'est la classe de faille exploitée par la compromission tj-actions/changed-files (CVE-2025-30066) en mars 2025. Sur ce dépôt, 148 références sur 368 ne sont pas épinglées par SHA, et un CVE connu (ISSUE-703) suffit à plafonner le score à cause du malus critique.
Si l'auto-détection ne marche pas
Section intitulée « Si l'auto-détection ne marche pas »Le cas le plus fréquent est simple : le dépôt n'a pas de remote origin, ou l'URL du remote ne pointe ni vers GitLab ni vers GitHub.
Passez alors explicitement les paramètres :
# GitLab self-hostedplumber analyze --gitlab-url https://gitlab.com --project mon-groupe/mon-projet
# GitHub Enterprise Serverplumber analyze --github-url https://github.example.com --project mon-org/mon-projetErreurs fréquentes à corriger d'abord
Section intitulée « Erreurs fréquentes à corriger d'abord »Plumber documente 64 codes d'issues organisés en neuf familles (voir l'annexe en bas de guide). Mais sur un projet qui n'a jamais été audité, ce sont presque toujours les mêmes quatre erreurs qui dominent, quel que soit le provider. Commencez par celles-ci.
1. Images de conteneur non épinglées par digest
Section intitulée « 1. Images de conteneur non épinglées par digest »Dans le lab pipeline-craft testé, Plumber a signalé :
HIGH [ISSUE-103] Job 'pytest' uses image without digest pinning: docker.io/python:3.12-slimHIGH [ISSUE-103] Job 'docker-build' uses image without digest pinning: docker.io/docker:27Le problème n'est pas seulement l'usage de latest. Un tag de version comme python:3.12-slim reste mutable : si le registre republie l'image, votre pipeline peut exécuter autre chose demain.
Pour activer le mode strict, la clé se trouve dans le schéma v2.0 sous la section provider :
version: "2.0"gitlab: controls: containerImageMustNotUseForbiddenTags: enabled: true containerImagesMustBePinnedByDigest: true2. Actions tierces non pinnées par SHA (provider GitHub)
Section intitulée « 2. Actions tierces non pinnées par SHA (provider GitHub) »C'est la faille la plus visible détectée par le provider GitHub, désormais sous le code ISSUE-701 :
HIGH [ISSUE-701] job "…" references action "…@main" with a mutable ref - pin by commit SHA insteadUn uses: owner/action@v4 ou uses: owner/action@main reste mutable côté maintainer. Si l'action est compromise, comme tj-actions/changed-files en mars 2025 (CVE-2025-30066), votre workflow exécute silencieusement le code modifié avec ses secrets.
Activez le contrôle dans la section GitHub :
github: controls: actionsMustBePinnedByCommitSha: enabled: true trustGithubOfficialActions: trueL'option trustGithubOfficialActions exempte les actions GitHub de premier rang (actions/*, github/*) pour concentrer le signal initial sur la surface tierce, celle qui n'est pas maintenue par GitHub.
3. Includes sur main, master ou HEAD (provider GitLab)
Section intitulée « 3. Includes sur main, master ou HEAD (provider GitLab) »Un include pointant sur une branche mutable rend votre pipeline difficile à reproduire et peut casser sans changement dans votre dépôt.
include: - project: security/templates file: /pipelines/sast.yml ref: maininclude: - project: security/templates file: /pipelines/sast.yml ref: v2.4.1Le contrôle associé est includesMustNotUseForbiddenVersions avec ISSUE-404.
4. Branche principale non protégée
Section intitulée « 4. Branche principale non protégée »Si la branche par défaut n'est pas protégée, un push direct ou une modification non revue peut contourner vos pratiques de revue et de sécurité. Le contrôle existe sous les deux providers et renvoie ISSUE-501 (absence de protection) ou ISSUE-505 (protection incomplète).
gitlab: controls: branchMustBeProtected: enabled: true defaultMustBeProtected: true namePatterns: - main allowForcePush: falseUne cinquième erreur très courante : Docker-in-Docker
Section intitulée « Une cinquième erreur très courante : Docker-in-Docker »Le lab a également remonté :
HIGH [ISSUE-412] job "docker-build" uses Docker-in-Docker service "docker:27-dind" ↳ at .gitlab-ci.yml:55 ↳ docs: https://getplumber.io/docs/cli/issues/ISSUE-412Sur des runners partagés, DinD augmente le risque d'évasion de conteneur et de mouvement latéral. Si vous construisez des images, privilégiez Kaniko ou Buildah. Le contrôle existe aussi côté GitHub avec ISSUE-413 (mode daemon non sécurisé).
Les protections supply chain à activer ensuite
Section intitulée « Les protections supply chain à activer ensuite »Une fois les quatre erreurs de base corrigées, Plumber offre une famille de contrôles 7XX dédiée aux actions tierces, la surface la plus attaquée d'un workflow GitHub. Ces contrôles vont plus loin que le simple pinning et méritent d'être activés dès que votre pipeline est stable.
Restreindre les sources d'actions autorisées (ISSUE-713)
Section intitulée « Restreindre les sources d'actions autorisées (ISSUE-713) »Épingler une action par SHA garantit qu'elle ne change pas, mais pas qu'elle vienne d'un auteur de confiance. Le contrôle githubActionMustComeFromAuthorizedSources signale toute action dont le propriétaire n'est ni GitHub, ni votre organisation, ni sur votre allowlist. C'est la parade directe contre le squat de dépôt ou une action tierce inconnue qui hériterait de vos secrets.
github: controls: githubActionMustComeFromAuthorizedSources: enabled: true trustGithubOfficialActions: true trustSameOrgActions: true # Seuil d'étoiles minimal (0 = désactivé, nécessite l'API GitHub) minimumStars: 0 trustedGithubActions: - docker/setup-buildx-action - docker/login-action - ossf/scorecard-actionBloquer les actions portant un CVE connu (ISSUE-703)
Section intitulée « Bloquer les actions portant un CVE connu (ISSUE-703) »Le contrôle actionsMustNotCarryKnownCVEs croise chaque action épinglée avec les avis de sécurité publiés. Une seule action vulnérable remonte en Critical et, par le malus critique, plafonne le score global tant qu'elle n'est pas corrigée. Le contrôle complémentaire actionsMustNotBeArchived (ISSUE-702) signale les actions dont le dépôt amont est archivé, donc qui ne recevra plus aucun correctif.
github: controls: actionsMustNotCarryKnownCVEs: enabled: true actionsMustNotBeArchived: enabled: trueFermer la porte pull_request_target (ISSUE-804)
Section intitulée « Fermer la porte pull_request_target (ISSUE-804) »Le contrôle pullRequestTargetMustNotCheckoutHead détecte un workflow déclenché par pull_request_target qui fait un checkout de la HEAD de la pull request. C'est exactement le motif exploité par la compromission tj-actions/changed-files : le code non fusionné d'un contributeur externe s'exécute avec les secrets du dépôt.
github: controls: pullRequestTargetMustNotCheckoutHead: enabled: trueFichier de configuration : schéma v2.0 par provider
Section intitulée « Fichier de configuration : schéma v2.0 par provider »Le schéma v2.0 introduit en 0.3 organise les contrôles par provider : tout ce qui concerne GitLab CI/CD vit sous gitlab.controls:, tout ce qui concerne GitHub Actions vit sous github.controls:. Le top-level controls: de la v1 disparaît, et le bloc engine: aussi (le moteur Rego est désormais le seul disponible et tourne par défaut).
Exemple minimal pour démarrer
Section intitulée « Exemple minimal pour démarrer »version: "2.0"
gitlab: controls: containerImageMustNotUseForbiddenTags: enabled: true tags: - latest - dev - main containerImagesMustBePinnedByDigest: true
containerImageMustComeFromAuthorizedSources: enabled: true trustDockerHubOfficialImages: true trustedUrls: - $CI_REGISTRY_IMAGE:* - registry.gitlab.com/security-products/*
branchMustBeProtected: enabled: true defaultMustBeProtected: true namePatterns: - main allowForcePush: false
includesMustNotUseForbiddenVersions: enabled: true forbiddenVersions: - latest - main - HEAD
github: controls: actionsMustBePinnedByCommitSha: enabled: true trustedOwners: - actions - github
branchMustBeProtected: enabled: true defaultMustBeProtected: true namePatterns: - mainMigrer une configuration v1 en une commande
Section intitulée « Migrer une configuration v1 en une commande »Si vous arrivez d'une version antérieure et que votre .plumber.yaml utilise encore le top-level controls:, plumber config migrate ré-écrit le fichier au schéma v2.0 en préservant commentaires et ordre :
# Crée .plumber.yaml.v2 à côté du fichier originalplumber config migrate
# Ou écrase en place (le fichier original part en .plumber.yaml.bak)plumber config migrate --in-placeLa migration encapsule le bloc controls: existant sous gitlab.controls:, upgrade version: "1.0" vers "2.0" et supprime le bloc engine: devenu obsolète. Les sections gitlab: ou github: déjà présentes sont laissées intactes.
Commandes utiles autour de la configuration
Section intitulée « Commandes utiles autour de la configuration »# Vérifier le fichierplumber config validate
# Voir la configuration effective sans commentairesplumber config view
# Comparer la configuration locale au défaut (sortie colorisée)plumber config diff
# Générer le template complet officiel (sections gitlab: et github:)plumber config generate --output .plumber.yaml --forceplumber config diff est apparu en 0.3 et permet de voir d'un coup d'œil ce qui diffère du template officiel : vert pour ce que vous avez ajouté ou modifié, rouge pour ce que vous avez retiré. Utile sur un projet hérité avant de proposer un durcissement.
Ajouter Plumber à GitLab CI avec le composant officiel
Section intitulée « Ajouter Plumber à GitLab CI avec le composant officiel »Une fois le premier scan local compris, le bon point d'entrée côté GitLab est le composant CI/CD officiel.
Démarrage rapide recommandé
Section intitulée « Démarrage rapide recommandé »Ajoutez d'abord le token GITLAB_TOKEN dans Settings -> CI/CD -> Variables, puis utilisez ce squelette :
workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS when: never - if: $CI_COMMIT_BRANCH - if: $CI_COMMIT_TAG
include: - component: gitlab.com/getplumber/plumber/plumber@v0.3.9Ce bloc workflow:rules évite de créer à la fois un pipeline de branche et un pipeline de merge request sur le même push.
Variante personnalisée
Section intitulée « Variante personnalisée »workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS when: never - if: $CI_COMMIT_BRANCH - if: $CI_COMMIT_TAG
include: - component: gitlab.com/getplumber/plumber/plumber@v0.3.9 inputs: stage: test threshold: 80 config_file: .plumber.yaml pbom_file: plumber-pbom.json pbom_cyclonedx_file: plumber-cyclonedx-sbom.jsonPriorité de configuration du composant
Section intitulée « Priorité de configuration du composant »Le composant recherche la configuration dans cet ordre :
- l'input
config_files'il est défini ; - le fichier
.plumber.yamlà la racine du dépôt ; - la configuration par défaut embarquée dans l'image.
Et si vous écrivez un job manuel ?
Section intitulée « Et si vous écrivez un job manuel ? »Gardez cette variante pour les besoins spécifiques. Si vous voulez ajouter --mr-comment et --badge dans un job manuel, séparez-les en deux jobs : le commentaire de merge request n'a de sens qu'en pipeline de MR, et le badge ne se met à jour que sur la branche par défaut.
GitLab self-hosted : le minimum à savoir
Section intitulée « GitLab self-hosted : le minimum à savoir »Sur un GitLab auto-hébergé, vous ne pouvez pas consommer directement le composant depuis gitlab.com. Le chemin correct est le suivant :
-
Importez le dépôt
https://gitlab.com/getplumber/plumber.gitdans votre instance. -
Activez le CI/CD Catalog dans le projet importé.
-
Publiez une release en lançant un pipeline sur un tag déjà importé, par exemple
v0.3.9. -
Consommez ensuite le composant local dans vos pipelines.
include: - component: gitlab.example.com/infrastructure/plumber/plumber@v0.3.9Exporter un PBOM et l'analyser
Section intitulée « Exporter un PBOM et l'analyser »Une fois la lecture du scan comprise, vous pouvez passer au PBOM.
Le PBOM (Pipeline Bill of Materials) est l'inventaire des dépendances de votre pipeline : images Docker, composants GitLab, templates et includes.
plumber analyze \ --pbom plumber-pbom.json \ --pbom-cyclonedx plumber-cyclonedx-sbom.jsonQuand utiliser chaque format ?
Section intitulée « Quand utiliser chaque format ? »| Format | Quand l'utiliser | Ce qu'il contient |
|---|---|---|
| PBOM natif | Vous voulez comprendre le pipeline en détail | Métadonnées riches propres à Plumber |
| CycloneDX | Vous voulez brancher un autre outil | Format standard pour Trivy, Grype ou Dependency-Track |
Scanner le CycloneDX avec Trivy
Section intitulée « Scanner le CycloneDX avec Trivy »trivy sbom plumber-cyclonedx-sbom.json --severity HIGH,CRITICALScanner le CycloneDX avec Grype
Section intitulée « Scanner le CycloneDX avec Grype »grype sbom:plumber-cyclonedx-sbom.json --fail-on highRemonter les findings dans les tableaux de bord sécurité
Section intitulée « Remonter les findings dans les tableaux de bord sécurité »Le PBOM inventorie le pipeline ; pour faire remonter les écarts de
conformité dans les plateformes, Plumber produit deux rapports de findings
standardisés. Vous les générez en ajoutant un drapeau à plumber analyze.
--sarifécrit un rapport au format SARIF 2.1.0, consommé par GitHub Code Scanning (onglet Security du dépôt) et par le Security Dashboard de GitLab.--glsastécrit un rapport GitLab SAST (gl-sast-report.json) qui alimente le Security Dashboard et le widget de merge request GitLab.
# Rapport SARIF - GitHub Code Scanning ou Security Dashboard GitLabplumber analyze --sarif plumber.sarif
# Rapport SAST natif GitLab - widget de merge requestplumber analyze --glsast gl-sast-report.jsonDans un job GitLab manuel, déclarez le fichier produit comme artefact de
rapport sast pour que GitLab l'affiche automatiquement dans la merge
request :
plumber-scan: # ... un script qui lance « plumber analyze --glsast gl-sast-report.json » artifacts: reports: sast: gl-sast-report.jsonCes deux formats ne remplacent pas la lecture du résumé : ils servent à historiser les findings et à les rapprocher des autres scanners de sécurité déjà branchés sur vos tableaux de bord.
Aller plus loin après le premier scan
Section intitulée « Aller plus loin après le premier scan »À ce stade, vous savez déjà lancer Plumber et lire les erreurs les plus utiles. Les fonctionnalités suivantes sont pratiques, mais elles ne doivent pas être votre point d'entrée.
Comprendre un code avec plumber explain
Section intitulée « Comprendre un code avec plumber explain »plumber explain ISSUE-412# raccourci accepté : plumber explain 412Cette commande renvoie la description du problème, son impact, la remédiation et le lien vers la documentation officielle. Trois flags complètent l'usage :
# Liste compacte des 64 codes disponiblesplumber explain --list
# Référence exhaustive (description + remédiation pour chaque code)plumber explain --all
# Sortie JSON, exploitable dans un scriptplumber explain ISSUE-701 --jsonUtiliser le score A-E
Section intitulée « Utiliser le score A-E »Le score est désormais toujours calculé à chaque plumber analyze : il alimente automatiquement le badge de conformité et les commentaires de merge request. Le flag --score reste accepté pour afficher le détail à l'écran, et --score-point montre le décompte de points.
plumber analyze --scoreplumber analyze --score-pointSur le scan réel présenté plus haut, le résultat était :
Plumber Score Critical 1 High 127 Medium 119 Low 0 ▲ Critical malus applied (points capped at 30 while any Critical remains)Le score sert à prioriser. Il ne remplace pas la lecture des contrôles en échec. Le scoring-v3 applique des plafonds par code et des poids rééquilibrés : un même nombre d'issues ne produit pas mécaniquement la même note. Surtout, une seule issue Critical déclenche un malus qui plafonne les points tant qu'elle n'est pas corrigée.
Cibler seulement certains contrôles
Section intitulée « Cibler seulement certains contrôles »# Uniquement les images et la protection de brancheplumber analyze --controls containerImageMustNotUseForbiddenTags,branchMustBeProtected
# Tout sauf la protection de brancheplumber analyze --skip-controls branchMustBeProtectedCommentaires de merge request et badges projet
Section intitulée « Commentaires de merge request et badges projet »Avec le composant GitLab, activez-les ainsi :
include: - component: gitlab.com/getplumber/plumber/plumber@v0.3.9 inputs: mr_comment: true badge: trueQuand passer à la Platform ?
Section intitulée « Quand passer à la Platform ? »La Platform n'est pas le bon point de départ pour un débutant. Elle devient pertinente quand vous devez :
- suivre plusieurs projets dans le temps ;
- disposer d'un tableau de bord centralisé ;
- gérer des politiques communes à plusieurs équipes ;
- auditer des variables, des quotas ou des règles de merge request à plus grande échelle.
Annexe : les 64 codes d'issues par famille
Section intitulée « Annexe : les 64 codes d'issues par famille »Plumber v0.3.82 documente 64 codes d'issues organisés en neuf familles, chacun avec une description et une remédiation accessibles via plumber explain ISSUE-XXX. La numérotation a évolué : les actions tierces ont désormais leur propre famille 7XX. Pour obtenir la liste exacte depuis votre installation, utilisez :
# Liste compacte (un code = une ligne)plumber explain --list
# Référence complète (description + remédiation pour chaque code)plumber explain --all
# Détail d'un code en JSON, exploitable dans un scriptplumber explain ISSUE-701 --jsonLe tableau ci-dessous donne la grille de lecture pour identifier rapidement la famille concernée par une issue remontée :
| Famille | Plage | Couvre | Exemples |
|---|---|---|---|
| Images de conteneurs | ISSUE-1XX (3 codes) | Sources, tags, digest | ISSUE-101 source non autorisée, ISSUE-102 tag interdit, ISSUE-103 image non pinnée par digest |
| Exécution et expressions | ISSUE-2XX (12 codes) | Variables, injection, contexte | ISSUE-203 debug trace, ISSUE-207 injection template, ISSUE-209 $GITHUB_ENV écrit, ISSUE-213 toJson(github) |
| Secrets et jetons | ISSUE-3XX (8 codes) | Fuites, secrets: inherit, tokens | ISSUE-302 secrets: inherit, ISSUE-307 credentials persistés, ISSUE-309 toJson(secrets) |
| Jobs, templates et structure | ISSUE-4XX (17 codes) | Jobs, includes, DinD, OIDC | ISSUE-401 job hardcodé, ISSUE-404 include mutable, ISSUE-412 DinD, ISSUE-421 publish sans OIDC |
| Protection de branche | ISSUE-5XX (2 codes) | branchMustBeProtected | ISSUE-501 absence de protection, ISSUE-505 protection incomplète |
| Hygiène de workflow | ISSUE-6XX (1 code) | Nommage | ISSUE-601 workflow sans name: |
| Actions tierces (supply chain) | ISSUE-7XX (12 codes) | Pinning, sources, CVE, archivage | ISSUE-701 action non SHA, ISSUE-702 dépôt archivé, ISSUE-703 CVE connu, ISSUE-713 source non autorisée |
| Permissions et déclencheurs | ISSUE-8XX (4 codes) | permissions:, triggers | ISSUE-801 pas de permissions:, ISSUE-802 trigger dangereux, ISSUE-804 pull_request_target piégé |
| Hygiène du dépôt | ISSUE-9XX (5 codes) | Dependabot, scanners, SECURITY.md | ISSUE-903 pas d'outil de mise à jour, ISSUE-904 pas de scanner statique, ISSUE-905 pas de SECURITY.md |
La famille 7XX est la plus stratégique pour la supply chain : elle concentre les protections contre les actions tierces compromises, la surface la plus attaquée d'un workflow GitHub. Les familles 8XX et 9XX sont quasi-exclusivement GitHub : elles couvrent ce que l'écosystème Actions expose comme risques (permissions du GITHUB_TOKEN, Dependabot, scanners CI, SECURITY.md).
Dépannage
Section intitulée « Dépannage »Avant de parcourir le tableau, gardez en tête deux pièges propres à la 0.3 : la migration v1 → v2 est nécessaire dès que votre .plumber.yaml utilise encore le top-level controls:, et le provider GitHub s'appuie sur la CLI gh pour l'authentification (pas de variable d'environnement à exporter).
| Symptôme | Cause probable | Solution |
|---|---|---|
configuration file not found | Aucun .plumber.yaml présent pour la CLI | Créez le fichier avec plumber config init ou plumber config generate |
unknown key 'controls' at root | Configuration encore au schéma v1 | Lancez plumber config migrate pour passer au schéma v2.0 |
GITLAB_TOKEN environment variable is required | Variable manquante côté provider GitLab | Exportez GITLAB_TOKEN avant plumber analyze |
401 Unauthorized (GitLab) | Token incomplet ou invalide | Vérifiez read_api + read_repository sur le token |
| Aucune authentification GitHub détectée | Pas de session gh active | Lancez gh auth login ; Plumber lit ensuite ~/.config/gh automatiquement |
403 Forbidden on MR comment | Scope insuffisant | Utilisez api si vous activez mr_comment |
403 Forbidden on badge | Scope insuffisant ou rôle trop faible | Utilisez api et un rôle Maintainer |
| Le composant ne s'exécute pas | Job en .pre sans autre stage normal | Forcez stage: test |
| Deux pipelines sont créés sur le même push | workflow:rules absent | Ajoutez le bloc recommandé par GitLab |
| Le projet n'est pas auto-détecté | Remote Git absent ou mal nommé | Vérifiez le remote origin ou passez --gitlab-url / --github-url et --project |
À retenir
Section intitulée « À retenir »- Plumber scanne la sécurité de vos pipelines GitLab CI/CD et GitHub Actions depuis la même CLI (v0.3.82 ; composant GitLab v0.3.9, versionnages distincts)
- Le chemin débutant est simple :
config init,config validate,plumber analyze - Le schéma v2.0 sépare les contrôles par provider (
gitlab.controls:/github.controls:) ;plumber config migratefait la conversion depuis la v1 - Commencez par corriger les images non épinglées, les actions non SHA (ISSUE-701), les includes mutables et les branches non protégées
- Activez ensuite les protections supply chain : sources autorisées (ISSUE-713), CVE connues (ISSUE-703),
pull_request_targetpiégé (ISSUE-804) - Le PBOM sert à inventorier le pipeline ; le CycloneDX facilite l'intégration avec Trivy et Grype
- Les rapports
--sarifet--glsastfont remonter les findings dans GitHub Code Scanning et le Security Dashboard GitLab - Le score est toujours calculé (scoring-v3) : une seule issue Critical plafonne les points tant qu'elle n'est pas corrigée
- 64 codes d'issues en neuf familles ; la liste exacte vient toujours de
plumber explain --listsur votre version - Gardez la Platform pour les besoins de gouvernance multi-projets
FAQ : questions fréquentes
Section intitulée « FAQ : questions fréquentes »Qu'est-ce que Plumber, en une phrase ?
Section intitulée « Qu'est-ce que Plumber, en une phrase ? »Plumber est un scanner de sécurité de pipelines CI/CD qui analyse vos configurations GitLab CI/CD et GitHub Actions pour détecter les failles de supply chain : actions non épinglées, sources non fiables, secrets exposés, branches non protégées. Il rend un score et un rapport de findings exploitable dans vos tableaux de bord.
Plumber est-il gratuit ?
Section intitulée « Plumber est-il gratuit ? »La CLI et le composant GitLab couverts par ce guide sont utilisables en ligne de commande et en pipeline. La Platform (tableau de bord multi-projets, historique, gouvernance) est un produit distinct, pertinent seulement quand vous pilotez un portefeuille de projets.
Quelle différence entre Plumber et Trivy ou zizmor ?
Section intitulée « Quelle différence entre Plumber et Trivy ou zizmor ? »Trivy scanne des images et des SBOM à la recherche de CVE. zizmor cible spécifiquement les workflows GitHub Actions. Plumber couvre les deux plateformes (GitLab et GitHub) sous une même configuration, produit un score et un PBOM, et se concentre sur la posture du pipeline plutôt que sur les vulnérabilités des dépendances. Les trois sont complémentaires : Plumber peut d'ailleurs exporter un CycloneDX que Trivy ou Grype analysent ensuite.
Plumber modifie-t-il mes pipelines ?
Section intitulée « Plumber modifie-t-il mes pipelines ? »Non. Plumber lit et analyse votre configuration, il ne la réécrit pas. Les corrections (épingler une action par SHA, ajouter un bloc permissions:, protéger une branche) restent à votre main. C'est un détecteur, pas un correcteur automatique.