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, vous n’avez pas besoin de commencer par une plateforme complète de gouvernance. Vous avez besoin d’un premier scan clair. Plumber sert à ça : vous créez une configuration minimale, vous lancez plumber analyze, vous lisez trois ou quatre problèmes concrets, puis vous intégrez le contrôle dans GitLab CI/CD avec le composant officiel. Dans ce guide, on commence volontairement par la CLI, ensuite seulement 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 avec
plumber config init, puis la valider avant le premier scan - Lancer une analyse locale sur un dépôt GitLab et comprendre l’auto-détection du projet
- Corriger trois erreurs fréquentes : image non épinglée, include mutable, 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
Plumber en une phrase
Section intitulée « Plumber en une phrase »Plumber est un scanner de conformité pour GitLab CI/CD. Il lit votre configuration de pipeline, interroge votre projet GitLab, puis signale les écarts les plus fréquents : images non fiables, tags mutables, branches non protégées, includes obsolètes, scripts téléchargés sans vérification ou usage de Docker-in-Docker.
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 ;
- un token GitLab avec les scopes
read_apietread_repository; - le rôle Maintainer sur le projet, ou un Project Access Token doté de ce rôle ;
- 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/plumber@0.1.84brew tap getplumber/plumberbrew install getplumber/plumber/plumber@0.1.84# 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.1.84Vérification :
plumber versionVous devez voir plumber version 0.1.84 ou une version plus récente.
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.
-
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, 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. -
Créez votre token GitLab
Dans GitLab, ouvrez User Settings -> Access Tokens et créez un token avec
read_apietread_repository.Fenêtre de terminal export GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx -
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, Plumber détecte automatiquement l’URL GitLab et le chemin du projet. -
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 concerné.
Exemple réel de premier scan
Section intitulée « Exemple réel de premier scan »Sur le dépôt de lab Pipeline Craft, la commande suivante permet d’analyser une branche de solution :
plumber analyze --config /tmp/plumber-guide.yaml --branch solution/lab-12 --score-pointVoici le début de la sortie observée :
Auto-detected GitLab URL: https://gitlab.comAuto-detected project: Bob74/pipeline-craftUsing configuration: /tmp/plumber-guide.yamlAnalyzing project: Bob74/pipeline-craft on https://gitlab.com
Using remote CI configuration from branch: solution/lab-12✓ [████████████████████] (18/18) Analysis completeEt le résumé utile à lire :
Status: FAILEDTotal (required: 100%): 75.0%
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: E (0.0 / 100 pts)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 pas vers GitLab.
Dans ce cas, passez explicitement les paramètres :
plumber analyze --gitlab-url https://gitlab.com --project mon-groupe/mon-projetTrois erreurs fréquentes à corriger d’abord
Section intitulée « Trois erreurs fréquentes à corriger d’abord »Quand on débute, il est inutile de mémoriser immédiatement les 14 contrôles. Commencez par ces trois familles d’erreurs. Elles couvrent déjà une grande partie des problèmes visibles sur les pipelines réels.
1. Images non épinglées par digest
Section intitulée « 1. Images non épinglées par digest »Dans le lab 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 ici :
controls: containerImageMustNotUseForbiddenTags: enabled: true containerImagesMustBePinnedByDigest: true2. Includes sur main, master ou HEAD
Section intitulée « 2. Includes sur main, master ou HEAD »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.
3. Branche principale non protégée
Section intitulée « 3. 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 branchMustBeProtected vérifie cela et renvoie ISSUE-501 ou ISSUE-505 selon le problème : absence de protection ou protection incomplète.
controls: branchMustBeProtected: enabled: true defaultMustBeProtected: true namePatterns: - main allowForcePush: falseUne quatrième erreur très courante : Docker-in-Docker
Section intitulée « Une quatrième erreur très courante : Docker-in-Docker »Le lab a également remonté :
HIGH [ISSUE-412] Job 'docker-build' uses DinD service: docker:27-dindConsider using Kaniko or Buildah insteadSur 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.
Fichier de configuration : minimal d’abord, complet ensuite
Section intitulée « Fichier de configuration : minimal d’abord, complet ensuite »Le fichier .plumber.yaml reste volontairement simple au début. Vous n’avez pas besoin d’activer tous les contrôles dès le premier jour.
Exemple minimal pour démarrer
Section intitulée « Exemple minimal pour démarrer »version: "1.0"
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 - HEADCommandes 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
# Générer le template complet officielplumber config generate --output .plumber.yaml --forceAjouter 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.1.84Ce 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.1.84 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.1.84. -
Consommez ensuite le composant local dans vos pipelines.
include: - component: gitlab.example.com/infrastructure/plumber/plumber@v0.1.84Exporter 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 highAller 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 ;
- le lien vers la documentation officielle.
Utiliser le score A-E
Section intitulée « Utiliser le score A-E »plumber analyze --scoreplumber analyze --score-pointSur Pipeline Craft, le scan de solution/lab-12 a produit :
Plumber Score: EFinal points: 0.0 / 100High: 6Medium: 5Le score sert à prioriser. Il ne remplace pas la lecture des contrôles en échec.
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.1.84 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 14 contrôles CLI
Section intitulée « Annexe : les 14 contrôles CLI »| Contrôle | Code principal | À quoi il sert |
|---|---|---|
containerImageMustNotUseForbiddenTags | ISSUE-102 | Bloque les tags mutables comme latest ou dev |
containerImageMustComeFromAuthorizedSources | ISSUE-101 | Limite les images aux registries autorisés |
branchMustBeProtected | ISSUE-501 / 505 | Vérifie la protection des branches critiques |
pipelineMustNotIncludeHardcodedJobs | ISSUE-401 | Détecte les jobs définis directement dans le YAML |
includesMustBeUpToDate | ISSUE-403 | Contrôle que les includes ne sont pas obsolètes |
includesMustNotUseForbiddenVersions | ISSUE-404 | Interdit les refs mutables comme main ou HEAD |
pipelineMustIncludeComponent | ISSUE-408 / 409 | Imposent des composants GitLab obligatoires |
pipelineMustIncludeTemplate | ISSUE-405 / 406 | Imposent des templates GitLab obligatoires |
pipelineMustNotEnableDebugTrace | ISSUE-203 | Empêche l’exposition des secrets dans les logs |
pipelineMustNotUseUnsafeVariableExpansion | ISSUE-204 | Réduit le risque d’injection via des variables contrôlées par l’utilisateur |
securityJobsMustNotBeWeakened | ISSUE-410 | Détecte les jobs de sécurité neutralisés |
pipelineMustNotOverrideJobVariables | ISSUE-205 | Empêche de surcharger certaines variables de gouvernance |
pipelineMustNotExecuteUnverifiedScripts | ISSUE-411 | Détecte les motifs `curl |
pipelineMustNotUseDockerInDocker | ISSUE-412 / 413 | Détecte DinD et son mode non sécurisé |
Dépannage
Section intitulée « Dépannage »| 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 |
401 Unauthorized | Token incomplet ou invalide | Vérifiez read_api + read_repository |
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 et --project |
À retenir
Section intitulée « À retenir »- Plumber se comprend mieux par la CLI locale avant de passer au composant GitLab CI/CD
- Le chemin débutant est simple :
config init,config validate,plumber analyze - L’auto-détection repose sur un remote
originpointant vers GitLab - Commencez par corriger les images non épinglées, les includes mutables et les branches non protégées
- Le composant GitLab est la meilleure intégration par défaut ; le job manuel vient ensuite
- Le PBOM sert à inventorier le pipeline ; le CycloneDX facilite l’intégration avec Trivy et Grype
- Le score A-E,
plumber explain, les commentaires de MR et les badges sont utiles après le premier scan, pas avant - Gardez la Platform pour les besoins de gouvernance multi-projets