Un pipeline CI/CD mal sécurisé = porte ouverte aux compromissions. Ajoutez Docker et Kubernetes… et le risque explose.
Voici les 7 erreurs que je vois sur le terrain, et les bonnes pratiques pour les éliminer.
Un développeur pousse son code sur une branche. Le pipeline Jenkins, mal configuré, expose une variable d’environnement contenant une clé AWS secrète dans les logs. Un attaquant récupère cette clé, déploie un conteneur malveillant sur le cluster Kubernetes de production, et mine des cryptomonnaies pendant 48 heures avant détection. Leçon : chaque erreur de cette liste était présente (secrets exposés, runner non isolé, cluster permissif, absence de monitoring).
🛠️ Comparatif des outils de sécurité (SAST/SCA/DAST/Container/K8s)
| Outil | SAST | SCA | DAST | Container | K8s (config) |
|---|---|---|---|---|---|
| Trivy | ❌ | ✅ | ❌ | ✅ images | ✅ (misconfig) |
| Semgrep | ✅ | ❌ | ❌ | ❌ | ✅ (manifests) |
| OWASP ZAP | ❌ | ❌ | ✅ | ❌ | ❌ |
| Checkov | ❌ | ❌ | ❌ | ✅ Dockerfile | ✅ (Helm/K8s) |
| Falco | ❌ | ❌ | ❌ | ❌ | ✅ (runtime) |
| GitLab SAST | ✅ | ✅ (Dependency Scan) | ✅ (DAST) | ✅ (Container Scan) | ✅ (K8s scan) |
| GitHub Advanced Security | ✅ (CodeQL) | ✅ (Dependabot) | ❌ | ✅ (docker scan) | ❌ |
👉 Aucun outil ne couvre tout : pensez à une combinaison (ex: Trivy + Semgrep + Falco).
1. ❌ Secrets exposés dans les pipelines
🔴 Le problème
Tokens, clés SSH, secrets cloud en clair dans les variables d’environnement, les logs ou pire : dans le code (`.env`, `settings.py`). Un runner malveillant ou un log exposé suffit à tout compromettre.
✅ Bonne pratique
- Utiliser le gestionnaire de secrets natif : GitLab CI Variables (masked/protected), GitHub Actions Secrets, Jenkins Credentials + Vault.
- Ne jamais logger les variables d’environnement.
- Rotation automatique des secrets + audit des accès.
steps:
- name: Deploy
env: API_KEY: ${{ secrets.API_KEY }}
2. ❌ Absence de SAST / SCA / DAST
🔴 Le problème
Les vulnérabilités dans le code (injections SQL, XSS), les librairies tierces (Log4Shell, CVE inattendues) et les failles runtime ne sont jamais détectées. Résultat : un artefact vulnérable est déployé en production.
✅ Bonne pratique
- SAST : SonarQube, Semgrep, GitLab SAST, CodeQL (intégré au pipeline).
- SCA : Trivy, Dependency-Check, Snyk — analyser les dépendances avant build.
- DAST : OWASP ZAP, Nikto, GitLab DAST — tests dynamiques sur environnement de staging.
- Bloquer le pipeline en cas de faille critique (fail-fast).
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
3. ❌ Images Docker non sécurisées
🔴 Le problème
Image avec `root` comme utilisateur, packages obsolètes, secrets intégrés dans les layers, ou pire : pull d’images non officielles (contenant des malwares).
✅ Bonne pratique
- Images distroless ou basées sur Alpine.
- Dockerfile USER non-root, pas de secrets dans les layers (`--secret` mount en buildkit).
- Scan des vulnérabilités avant push :
docker scan, Trivy, Grype. - Registre privé avec signature des images (Cosign, Notary).
FROM alpine:3.18
RUN addgroup -g 1001 -S app && adduser -S app -u 1001
USER app
COPY --chown=app:app app.jar /app/app.jar
CMD ["java","-jar","/app/app.jar"]
4. ❌ Kubernetes en mode permissif
🔴 Le problème
Cluster avec RBAC désactivé, PodSecurityPolicy abandonnée (ou absente), conteneur en privileged, montage hostPath /var/run/docker.sock → escalade de privilèges immédiate.
✅ Bonne pratique
- Activer Pod Security Standards (mode Restricted par défault).
- Utiliser OPA/Gatekeeper ou Kyverno pour contrôler les ressources.
- Network Policies : isoler les namespaces, bloquer les accès non autorisés.
- Pas de secret en var d’env → utiliser CSI driver ou External Secrets.
kind: NetworkPolicy
metadata: name: deny-egress
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata: name: disallow-privileged
spec:
rules:
- name: privilege
match: {resources: {kinds: ["Pod"]}}
validate: {message: "Privileged pod interdit", pattern: {spec: {containers: [{securityContext: {privileged: false}}]}}}
5. ❌ Runner CI sans isolement
🔴 Le problème
Runner GitLab/Jenkins/GHA partagé avec privilèges root, ou non ephemeral. Un job malicieux peut altérer le runner et empoisonner les pipelines suivants.
✅ Bonne pratique
- Runners éphémères (docker-in-docker, Kubernetes, scale-from-zero).
- Privilèges limités : pas de mount Docker socket inutile.
- Isolation réseau, authentification forte du runner au control plane.
- Audit des jobs et des logs.
6. ❌ Absence de signature / SBOM
🔴 Le problème
Sans signature, on ne peut attester que l’image déployée est bien celle qui a passé les scans. De plus, sans SBOM (Software Bill of Materials), impossible de tracer une vulnérabilité dans la supply chain.
✅ Bonne pratique
- Cosign (Sigstore) pour signer et vérifier les images.
- Générer un SBOM avec
syft,trivy sbom, l’attacher à l’image ou au registre. - Vérifier la signature dans l’admission controller (Kyverno).
- Imposer un niveau de provenance (SLSA Level 3+ sur les artefacts critiques).
cosign generate-key-pair
cosign sign --key cosign.key myregistry/app:latest
# Admission policy : interdit si non signé
7. ❌ Monitoring & alerting des pipelines absents
🔴 Le problème
Un pipeline modifié pour injecter des backdoors, un job exfiltre des variables, des scans sont désactivés… mais personne ne le voit. Pas d’alerte, pas d’audit.
✅ Bonne pratique
- Centraliser les logs des pipelines (ELK, Datadog, Loki).
- Alertes sur : échecs répétés de SAST, modification des jobs master, exécution hors plage horaire.
- Sur Kubernetes : audit des déploiements (Cilium, Falco).
- Métriques de sécurité intégrées au dashboard DevSecOps.
🚀 Bonnes pratiques avancées
- SBOM attestation avec provenance SLSA : générez un attestation `cosign attest --type slsa-provenance`.
- Signature des commits (GPG) et vérification obligatoire dans le pipeline (GitLab : `only: [signed]`).
- Détection des secrets en amont : pre-commit + gitleaks/trufflehog pour éviter qu’un secret n’entre dans le dépôt.
- Network Policies par défaut en deny-all puis ouverture explicite.
- Image scanning dans le registry avec politiques de rétention (ex: refuser toute image avec faille critique > 7 jours).
- Admission controllers webhook pour valider les ressources Kubernetes avant déploiement.
✅ Checklist sécurité CI/CD & conteneurs
- ☑️ Secrets managés (Vault / variables masquées)
- ☑️ SAST + SCA + DAST intégrés au pipeline (avec fail-fast)
- ☑️ Images Docker : user non-root, scan des CVEs avant push
- ☑️ Kubernetes : Pod Security Standards, Network Policies, admission controller (Kyverno/OPA)
- ☑️ Runners éphémères et non privilégiés
- ☑️ Signature des images (Cosign) + SBOM attaché
- ☑️ Alerting sur anomalies des pipelines (logs centralisés)
- ☑️ Isolation des environnements (build, staging, prod)
- ☑️ Politique de mise à jour des runners et images de base
- ☑️ Détection de secrets (gitleaks) en pre-commit
- ☑️ Audit des déploiements Kubernetes (Falco, Cilium)
❓ FAQ – Vos questions fréquentes
🔹 Faut-il vraiment tout automatiser ?
Oui, l’automatisation est la seule façon de garantir la répétabilité et d’éviter les oublis. Mais commencez par les contrôles à fort impact (SAST, secret scanning) avant d’ajouter les plus complexes.
🔹 Quelle est la priorité : SAST ou SCA ?
SCA (analyse des dépendances) est souvent plus simple à mettre en place et rapporte rapidement en détectant des vulnérabilités connues. SAST est indispensable pour les applications métier personnalisées. Les deux sont complémentaires.
🔹 Comment convaincre son management d’investir dans ces contrôles ?
Présentez le coût moyen d’un incident de sécurité (ex: fuite de données, minage, rançon) vs le coût annuel des outils (souvent open source ou abordables). Un seul incident évité justifie l’investissement.
🔹 Peut-on sécuriser un pipeline existant sans tout casser ?
Oui, en mode “itératif” : ajoutez d’abord les scans en mode “warning” (sans bloquer), puis renforcez progressivement les règles et passez en mode bloquant après correction.
📚 Ressources & liens utiles
📖 Glossaire des termes techniques
- Cosign
- Outil de signature d’images Docker (projet Sigstore). Permet d’attester l’intégrité et la provenance d’une image avant déploiement.
- DAST (Dynamic Application Security Testing)
- Test de sécurité en boîte noire sur l’application en cours d’exécution. Simule des attaques externes (ex: OWASP ZAP) pour trouver des failles exploitables.
- Distroless
- Image Docker minimaliste sans shell, ni package manager, ni binaires système. Réduit drastiquement la surface d’attaque. Ex:
gcr.io/distroless/java. - Falco
- Outil de détection des menaces runtime pour Kubernetes. Analyse les appels système et les activités des conteneurs (ex: shell dans un pod, accès à /etc/shadow).
- Kyverno
- Moteur de politiques Kubernetes natif (sans apprendre un nouveau langage). Permet de valider, muter ou générer des ressources (ex: bloquer les pods privilégiés).
- Network Policy
- Règle de pare-feu intégrée à Kubernetes. Permet d’isoler les pods en définissant quels trafics entrants/sortants sont autorisés (ex: deny-all par défaut).
- OPA / Gatekeeper
- Open Policy Agent + Gatekeeper : moteur de politiques généraliste pour Kubernetes. Utilise le langage Rego pour appliquer des règles complexes (ex: labels obligatoires).
- RBAC (Role-Based Access Control)
- Contrôle d’accès basé sur les rôles dans Kubernetes. Permet de limiter les actions des utilisateurs et des services (ex: empêcher un pod de lister les secrets).
- SAST (Static Application Security Testing)
- Analyse statique du code source pour détecter des vulnérabilités (injections SQL, XSS, buffer overflows) sans exécuter l’application. S’intègre tôt dans le pipeline.
- SBOM (Software Bill of Materials)
- Inventaire complet des composants d’une application (librairies, versions, licences). Permet une réponse rapide aux vulnérabilités (ex: savoir si Log4j est présent).
- SCA (Software Composition Analysis)
- Analyse des dépendances open source et des bibliothèques tierces pour détecter des vulnérabilités connues (ex: Log4Shell) et des problèmes de licence.
- SLSA (Supply-chain Levels for Software Artifacts)
- Cadre de sécurisation de la chaîne d’approvisionnement logicielle (de level 1 à 4). Niveau 3+ requis pour les artefacts critiques.