En 2026, le rapport OSSRA révèle que 65% des organisations ont subi une attaque supply chain et que les codebases contiennent en moyenne 581 vulnérabilités open source. Pour les projets open source, le pipeline CI/CD est à la fois la dernière ligne de défense et le premier vecteur d'attaque si mal configuré. Ce guide vous accompagne pas à pas pour construire un pipeline CI/CD qui détecte les vulnérabilités avant qu'elles n'atteignent la production, avec des exemples concrets pour GitHub Actions et GitLab CI.
Étape 1 : Structurer le pipeline avec des stages séparés
La première erreur que je vois dans les projets open source, c'est le pipeline monolithique : un seul job qui fait tout (build, test, lint, deploy) dans un script bash de 200 lignes. Un pipeline sécurisé repose sur une séparation stricte des stages. Chaque stage a une responsabilité unique et peut échouer indépendamment des autres.
Voici la structure recommandée pour un pipeline CI/CD sécurisé :
- Build : compilation du code, génération des artefacts. Pas de secrets, pas d'accès réseau externe si possible.
- Test : tests unitaires et d'intégration. Exécutés dans un environnement isolé avec des données de test, jamais des données de production.
- Security : analyse statique (SAST), scanning de dépendances, vérification des secrets exposés. Ce stage doit bloquer le merge en cas de vulnérabilité critique.
- Package : construction des images de conteneurs, signature des artefacts, scanning des images.
- Deploy : déploiement sur l'environnement cible avec les credentials minimales nécessaires.
Avec GitHub Actions, cette structure se traduit par un workflow multi-jobs avec des dépendances explicites via le mot-clé needs. Chaque job tourne dans un runner isolé, ce qui garantit qu'un job compromis ne peut pas accéder aux secrets ou aux artefacts d'un autre job sans passage explicite via actions/upload-artifact et actions/download-artifact.
Avec GitLab CI, utilisez les stages natifs dans votre .gitlab-ci.yml. GitLab exécute les jobs d'un même stage en parallèle et attend leur complétion avant de passer au stage suivant. Activez les rules pour exécuter les scans de sécurité sur les merge requests mais pas sur chaque commit de branche de travail.
💡 Notre avis d'expert
Le piège le plus courant est de configurer les scans de sécurité comme des jobs non-bloquants (« allow_failure: true » sur GitLab ou « continue-on-error: true » sur GitHub). Cette configuration rend les scans purement informatifs — personne ne lit les rapports, et les vulnérabilités passent en production. Rendez les scans de sécurité bloquants pour les vulnérabilités critiques et high. Vous ajusterez les seuils avec le temps, mais commencez strict.
Étape 2 : Verrouiller les dépendances et scanner automatiquement
Les dépendances open source sont le premier vecteur d'attaque supply chain. Avec 581 vulnérabilités par codebase en moyenne (OSSRA 2026), la gestion des dépendances n'est plus optionnelle — c'est le fondement de la sécurité de votre pipeline.
Les actions concrètes :
- Lockfiles obligatoires :
package-lock.json(npm),yarn.lock(Yarn),poetry.lock(Python),Cargo.lock(Rust),go.sum(Go). Le lockfile garantit que les mêmes versions sont installées en CI et en local. Utiliseznpm ci(pasnpm install) etpip install --require-hashespour vérifier l'intégrité des packages. - Scanning de dépendances : configurez
Dependabot(GitHub) ouDependency Scanning(GitLab) pour détecter automatiquement les dépendances vulnérables. Sur GitHub, activez également les Dependabot security updates pour recevoir des PRs automatiques de mise à jour. - SCA (Software Composition Analysis) : intégrez un outil comme
Trivy,SnykouGrypedans votre pipeline pour une analyse plus approfondie que Dependabot. Ces outils détectent les vulnérabilités dans les dépendances transitives et fournissent des chemins de remontée. - Pinning des actions CI : sur GitHub Actions, référencez les actions par leur SHA de commit (
actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29) plutôt que par tag (actions/checkout@v4). Un tag peut être réécrit, pas un SHA.
Exemple avec GitHub Actions et Trivy pour le scanning de dépendances :
# .github/workflows/security.yml
name: Security Scan
on: [pull_request]
permissions:
contents: read
security-events: write
jobs:
dependency-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
exit-code: '1' # Fail the build on critical/high vulnsPour approfondir la sécurisation de vos dépendances, consultez notre guide détaillé Comment sécuriser vos dépendances npm en 8 étapes.
Étape 3 : Intégrer l'analyse statique de sécurité (SAST)
L'analyse statique de sécurité (SAST) examine votre code source sans l'exécuter pour détecter des patterns de vulnérabilités connus : injections SQL, cross-site scripting (XSS), désérialisation non sécurisée, chemins de fichiers arbitraires, etc. Le SAST est l'outil le plus rentable de votre pipeline de sécurité car il détecte les problèmes au plus tôt dans le cycle de développement — avant même que le code ne soit mergé.
Les outils SAST recommandés pour les projets open source :
- Semgrep : moteur de règles rapide, extensible, avec un registre de règles communautaires couvrant 30+ langages. Gratuit pour l'open source. C'est notre recommandation principale.
- CodeQL (GitHub) : analyse sémantique profonde intégrée à GitHub Advanced Security. Gratuit pour les repos publics. Puissant mais plus lent que Semgrep.
- GitLab SAST : intégré nativement dans GitLab CI, gratuit pour les projets open source. Utilise plusieurs analyseurs en parallèle selon les langages détectés.
- Bandit (Python), Brakeman (Ruby), gosec (Go) : analyseurs spécifiques à un langage, souvent plus précis que les outils génériques pour leur écosystème.
Exemple avec Semgrep sur GitHub Actions :
# .github/workflows/sast.yml
name: SAST
on: [pull_request]
permissions:
contents: read
security-events: write
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- run: semgrep scan --config auto --sarif --output semgrep.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
if: always()Exemple équivalent avec GitLab CI :
# .gitlab-ci.yml (extrait)
include:
- template: Security/SAST.gitlab-ci.yml
sast:
stage: security
variables:
SAST_EXCLUDED_ANALYZERS: "spotbugs"
SAST_EXCLUDED_PATHS: "tests/, node_modules/"
rules:
- if: $CI_MERGE_REQUEST_IIDÉtape 4 : Gérer les secrets sécurité — OIDC, vaults et rotation
La gestion des secrets est le talon d'Achille de la plupart des pipelines CI/CD. Les erreurs classiques : des tokens API codés en dur dans les fichiers de workflow, des secrets copiés entre les environnements, des credentials sans date d'expiration qui trainent depuis des années.
Les principes fondamentaux :
- Zéro secret en dur : aucun token, aucune clé API, aucun mot de passe dans le code source ou les fichiers de workflow. Utilisez les GitHub Secrets (Settings > Secrets) ou les CI/CD Variables GitLab (Settings > CI/CD > Variables) marquées comme « masked » et « protected ».
- OIDC pour les cloud providers : au lieu de stocker des clés d'accès cloud statiques, utilisez OpenID Connect (OIDC) pour établir une relation de confiance entre votre pipeline et votre cloud provider. GitHub Actions et GitLab CI supportent nativement OIDC avec AWS, GCP et Azure. Le pipeline reçoit un token éphémère à chaque exécution — aucun secret à stocker.
- Principe du moindre privilège : limitez les
permissionsde chaque job au strict nécessaire. Sur GitHub Actions, utilisez le blocpermissionsau niveau du workflow et du job. Sur GitLab, utilisez les variables protégées et les environnements protégés. - Détection de secrets exposés : intégrez
gitleaks,truffleHogou le secret scanning natif de GitHub/GitLab pour détecter les credentials committés par erreur. Configurez-le comme un pre-commit hook ET comme un job CI.
# GitHub Actions - OIDC avec AWS (pas de clé statique)
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # Required for OIDC
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/github-actions
aws-region: eu-west-3 # Paris💡 Notre avis d'expert
L'adoption d'OIDC est le changement le plus impactant que vous puissiez faire pour la sécurité de votre pipeline. Chaque clé d'accès cloud statique stockée dans vos secrets CI est un risque permanent : elle ne tourne pas automatiquement, elle peut être exfiltrée par un job compromis, et elle donne un accès persistant. OIDC élimine tout cela en générant des tokens éphémères liés à une exécution spécifique. Si vous ne faites qu'une seule chose dans ce guide, faites celle-ci.
Étape 5 : Scanner les conteneurs et signer les artefacts
Si votre projet produit des images de conteneurs (Docker, OCI), chaque image est une surface d'attaque potentielle. L'image de base peut contenir des vulnérabilités connues, vos dépendances système (apt packages) peuvent être obsolètes, et l'image elle-même peut être altérée entre le build et le déploiement.
Les mesures essentielles :
- Scanning d'images : intégrez
Trivy,Grypeou le Container Scanning GitLab dans votre pipeline pour analyser chaque image construite. Scannez les vulnérabilités OS (packages système) et applicatives (dépendances du langage). - Images de base minimales : utilisez des images
distroless(Google),alpineouchainguardcomme base. Moins il y a de packages dans l'image, moins il y a de surface d'attaque. Évitez les imagesubuntu:latestounode:latesten production. - Signature d'artefacts : signez vos images avec
cosign(Sigstore) pour garantir leur intégrité et leur provenance. La signature permet aux consommateurs de vérifier que l'image n'a pas été altérée après le build. - SBOM (Software Bill of Materials) : générez un SBOM pour chaque image avec
syftoutrivy image --format spdx-json. Le SBOM liste tous les composants de l'image, facilitant l'analyse post-incident et la conformité réglementaire.
# Scanning d’image + signature avec cosign
jobs:
container-security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:$GITHUB_SHA .
- name: Scan with Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
severity: 'CRITICAL,HIGH'
exit-code: '1'
- name: Sign image with cosign
run: cosign sign --yes myapp:$GITHUB_SHA
env:
COSIGN_EXPERIMENTAL: 1Étape 6 : Configurer les tests dynamiques (DAST)
Le DAST (Dynamic Application Security Testing) complète le SAST en testant votre application en cours d'exécution. Là où le SAST analyse le code source, le DAST simule des attaques réelles sur vos endpoints HTTP, détectant les vulnérabilités de configuration, les headers de sécurité manquants, les problèmes CORS et les failles d'injection que le SAST ne peut pas voir.
Le DAST est plus coûteux en temps d'exécution que le SAST (minutes vs. secondes). Pour cette raison, il est généralement exécuté sur les merge requests vers les branches protégées (main, develop) plutôt que sur chaque push.
Les outils recommandés :
- OWASP ZAP : le standard open source pour le DAST. Disponible comme action GitHub (
zaproxy/action-full-scan) et comme template GitLab. Scanne les 10 catégories de risques OWASP Top 10. - Nuclei : scanner de vulnérabilités rapide avec des templates communautaires. Excellent pour les checks de configuration (TLS, headers, etc.).
- GitLab DAST : intégré nativement, basé sur ZAP, avec des résultats directement dans le rapport de merge request.
Configuration type avec ZAP sur GitHub Actions :
# DAST avec OWASP ZAP
jobs:
dast:
runs-on: ubuntu-latest
needs: [deploy-staging]
steps:
- name: ZAP Full Scan
uses: zaproxy/action-full-scan@v0.10.0
with:
target: 'https://staging.monprojet.fr'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a'Étape 7 : Monitorer, alerter et améliorer en continu
Un pipeline de sécurité n'est pas un « set and forget ». Les vulnérabilités évoluent, les dépendances changent, les configurations dérivent. La dernière étape est la mise en place d'un cycle d'amélioration continue.
- Tableaux de bord de sécurité : centralisez les résultats de vos scans dans un dashboard. GitHub Advanced Security fournit un onglet Security natif. GitLab propose le Security Dashboard dans le tier Ultimate (gratuit pour l'open source). Pour les solutions cross-plateformes,
DefectDojo(open source) agrège les résultats de multiples scanners. - Alertes en temps réel : configurez des notifications Slack/Teams/email pour les vulnérabilités critiques détectées. Sur GitHub, les Dependabot alerts et les code scanning alerts peuvent déclencher des notifications automatiques.
- Métriques de suivi : suivez le MTTR (Mean Time To Remediate) pour les vulnérabilités. Objectif : moins de 7 jours pour les critiques, moins de 30 jours pour les high. Suivez également le taux de couverture SAST (pourcentage de code analysé) et le nombre de faux positifs (un taux de faux positifs élevé détruit la confiance de l'équipe dans les alertes).
- Revue trimestrielle : révisez vos règles SAST, vos seuils de blocage, vos exclusions et vos suppressions de faux positifs. Les règles qui génèrent trop de faux positifs doivent être ajustées, pas désactivées. Les règles désactivées sont des angles morts.
💡 Notre avis d'expert
La métrique la plus importante n'est pas le nombre de vulnérabilités détectées — c'est le MTTR (temps moyen de remédiation). Un pipeline qui détecte 500 vulnérabilités mais n'en corrige aucune est pire qu'un pipeline qui en détecte 50 et les corrige toutes en une semaine. Concentrez-vous sur la réduction du MTTR plutôt que sur l'augmentation du nombre de scans. Et pour aller plus loin sur l'audit de votre supply chain, consultez notre guide Auditer la supply chain open source en 7 étapes.
Conclusion : Un pipeline CI/CD sécurisé n'est pas un luxe réservé aux grandes organisations — c'est une nécessité pour tout projet open source qui prend la sécurité de ses utilisateurs au sérieux. Les 7 étapes de ce guide couvrent les fondamentaux : structure du pipeline, gestion des dépendances, SAST, gestion des secrets, scanning de conteneurs, DAST et monitoring continu. Commencez par les étapes 1 à 4 — elles couvrent 80% des risques. Ajoutez les étapes 5 à 7 une fois les fondamentaux en place. Chaque vulnérabilité détectée en CI coûte 10 fois moins cher à corriger qu'en production. L'investissement est rentable dès le premier mois. Contactez-nous pour un accompagnement sur la sécurisation de votre pipeline CI/CD.
Besoin d'aide pour sécuriser votre pipeline ?
D-Open accompagne les équipes de développement françaises sur la mise en place de pipelines CI/CD sécurisés. De l'audit de votre configuration actuelle à l'implémentation complète, nous adaptons notre accompagnement à votre stack technique et à vos contraintes.
Demander un audit CI/CDQuestions fréquentes
Quelle est la différence entre SAST et DAST ?▼
SAST analyse le code source sans l'exécuter, détectant les vulnérabilités dans le code (injections, XSS, etc.). DAST teste l'application en cours d'exécution, simulant des attaques réelles sur les endpoints. Les deux sont complémentaires : SAST détecte tôt dans le cycle, DAST identifie les problèmes de configuration et de runtime. Un pipeline sécurisé intègre les deux.
Comment sécuriser les secrets dans GitHub Actions ?▼
Utilisez les GitHub Secrets pour stocker les credentials. Ne jamais coder en dur des tokens dans les workflows. Limitez l'accès par environnement. Privilégiez OIDC pour les connexions aux cloud providers au lieu de clés statiques. Activez les logs d'audit et effectuez une rotation régulière des secrets.
GitHub Actions ou GitLab CI pour l'open source ?▼
Les deux sont excellents. GitHub Actions offre 20 000+ actions communautaires et des minutes gratuites pour les repos publics. GitLab CI intègre nativement le scanning de sécurité (SAST, DAST, dependency et container scanning) dans le tier gratuit pour l'open source. Le choix dépend de votre hébergement de code et de vos besoins en sécurité intégrée.
Combien de temps pour mettre en place un pipeline CI/CD sécurisé ?▼
Pour un projet de taille moyenne : 2-3 jours pour un pipeline de base (build, test, lint, SAST) et 1-2 semaines pour un pipeline complet avec DAST, scanning de conteneurs, signature d'artefacts et déploiement sécurisé. Le retour est immédiat : chaque vulnérabilité détectée en CI coûte 10x moins qu'en production.