DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesSécurité DevOps - Intermédiaire

Module

Intégrez la sécurité dans votre pipeline CI/CD : scanning automatique, SAST, protection des secrets et sécurisation des conteneurs.

  • 2h
  • Intermédiaire
  • 5 exercices
Voir les exercices

Formation 100 % Linux

Tous les modules nécessitent un environnement Linux. Si vous êtes sur Windows, installez d'abord WSL (Windows Subsystem for Linux) avant de continuer.

Sécurité DevOps - Intermédiaire

🎯 Objectifs

  • Automatiser le scanning de dépendances avec Dependabot
  • Analyser le code statiquement avec CodeQL (SAST)
  • Scanner les images Docker avec Trivy
  • Gérer les secrets de CI/CD de manière sécurisée
  • Sécuriser un workflow GitHub Actions

📋 Prérequis

  • Sécurité DevOps - Débutant terminé
  • Maîtriser les bases de GitHub Actions
  • Connaître Docker (images, Dockerfile)

🤔 Pourquoi automatiser la sécurité ?

La sécurité vérifiée à la main, c'est une sécurité oubliée.

Une revue de code manuelle ne détecte pas une dépendance vulnérable publiée hier. Un développeur fatigué laisse passer une faille d'injection. L'outil, lui, ne se fatigue jamais.

💡 Le principe : intégrer des outils de sécurité dans le pipeline CI/CD pour qu'ils tournent à chaque commit, sans intervention humaine.

C'est ce qu'on appelle le Shift Left Security : détecter les problèmes le plus tôt possible, quand ils coûtent le moins cher à corriger.


🤖 Dependabot : mises à jour automatiques des dépendances

Qu'est-ce que Dependabot ?

Dependabot est un outil GitHub qui surveille tes dépendances et ouvre automatiquement des Pull Requests quand une mise à jour est disponible - notamment quand une faille de sécurité est corrigée.

L'analogie

C'est comme avoir un assistant qui lit tous les bulletins de sécurité à ta place, et qui pose sur ton bureau un formulaire pré-rempli chaque fois qu'une mise à jour urgente est disponible. Il ne la fait pas lui-même - il te la propose.

Configuration

Créer le fichier .github/dependabot.yml :

yaml
version: 2
updates:
  # Dépendances Node.js
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"          # vérification chaque semaine
    open-pull-requests-limit: 10  # maximum 10 PRs ouvertes simultanément
    labels:
      - "dependencies"
      - "security"

  # Actions GitHub (les actions elles-mêmes ont des versions)
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"

💡 Dependabot s'occupe aussi des actions GitHub (uses: actions/checkout@v3 → @v4). C'est souvent oublié mais important.

Alertes de sécurité vs mises à jour

Dependabot propose deux fonctionnalités distinctes :

FonctionnalitéRôleActivation
Security alertsAlerte quand une CVE concerne tes dépendancesAutomatique (dépôts publics)
Security updatesOuvre une PR pour corriger la CVESecurity → Dependabot security updates
Version updatesOuvre une PR pour les nouvelles versionsVia dependabot.yml

🔍 SAST : analyser ton code statiquement

Qu'est-ce que le SAST ?

SAST = Static Application Security Testing. L'outil lit ton code source (sans l'exécuter) et cherche des patterns dangereux.

Exemples de ce qu'il détecte :

  • Une requête SQL construite par concaténation (injection SQL)
  • Un mot de passe codé en dur dans le code
  • L'utilisation de fonctions cryptographiques obsolètes

GitHub Code Scanning avec CodeQL

GitHub propose CodeQL gratuitement pour les dépôts publics et via GitHub Advanced Security pour les dépôts privés.

yaml
# .github/workflows/codeql.yml
name: "CodeQL"

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    # Scan complet chaque lundi matin
    - cron: '30 1 * * 1'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write   # nécessaire pour publier les résultats

    strategy:
      matrix:
        language: ['javascript', 'typescript']
        # Autres langages supportés : python, java, go, csharp, cpp, ruby

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}

      - name: Autobuild
        uses: github/codeql-action/autobuild@v3

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3

Les résultats apparaissent dans : Repository → Security → Code scanning alerts


🐳 Scanner les images Docker avec Trivy

Pourquoi scanner une image ?

Une image Docker contient un OS minimal + des paquets + tes dépendances applicatives. Chacun de ces composants peut avoir des vulnérabilités connues.

L'analogie

Construire une image Docker sans la scanner, c'est comme cuisiner avec des ingrédients sans vérifier leurs dates de péremption. Le plat a l'air bon, mais il peut rendre malade.

Utiliser Trivy en local

bash
# Installer Trivy
brew install trivy  # macOS
# ou
sudo apt install trivy  # Debian/Ubuntu

# Scanner une image
trivy image node:20-alpine

# Scanner ton image buildée localement
trivy image mon-app:latest

# Scanner uniquement les vulnérabilités HIGH et CRITICAL
trivy image --severity HIGH,CRITICAL mon-app:latest

# Scanner le filesystem (dépendances applicatives)
trivy fs --scanners vuln .

Exemple de sortie :

mon-app:latest (alpine 3.18.4)
===============================
Total: 3 (HIGH: 1, CRITICAL: 2)

┌────────────────┬────────────────┬──────────┬──────────────┬────────────────┐
│    Library     │  Vulnerability  │ Severity │ Installed    │ Fixed Version  │
├────────────────┼────────────────┼──────────┼──────────────┼────────────────┤
│ openssl        │ CVE-2023-5678   │ CRITICAL │ 3.1.1-r1     │ 3.1.4-r0       │
└────────────────┴────────────────┴──────────┴──────────────┴────────────────┘

Intégrer Trivy dans GitHub Actions

yaml
# .github/workflows/security.yml
name: Security Scan

on:
  push:
    branches: [main]
  pull_request:

jobs:
  trivy:
    runs-on: ubuntu-latest
    permissions:
      security-events: write

    steps:
      - uses: actions/checkout@v4

      - name: Build Docker image
        run: docker build -t mon-app:${{ github.sha }} .

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@0.24.0
        with:
          image-ref: 'mon-app:${{ github.sha }}'
          format: 'sarif'                        # format compatible GitHub Security
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'                         # fait échouer le pipeline si CVE trouvée

      - name: Upload Trivy scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v3
        if: always()                             # même si l'étape précédente a échoué
        with:
          sarif_file: 'trivy-results.sarif'

💡 exit-code: '1' est essentiel : il fait échouer le pipeline si une vulnérabilité critique est trouvée. Sans ça, le scan tourne mais ne bloque rien.


🔑 Gérer les secrets dans GitHub Actions

Les GitHub Secrets

Les secrets GitHub sont des valeurs chiffrées, stockées par GitHub, et injectées comme variables d'environnement dans tes workflows.

Ajouter un secret :

Repository → Settings → Secrets and variables → Actions → New repository secret

Utiliser un secret dans un workflow :

yaml
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        env:
          # ${{ secrets.NOM_DU_SECRET }} est remplacé par la valeur réelle
          # La valeur n'apparaît jamais dans les logs
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          API_KEY: ${{ secrets.API_KEY }}
        run: ./scripts/deploy.sh

⚠️ GitHub masque automatiquement les secrets dans les logs (***). Mais ne les affiche jamais volontairement avec echo.

Environments : secrets par environnement

Pour des secrets différents selon l'environnement (staging vs production) :

yaml
jobs:
  deploy-prod:
    runs-on: ubuntu-latest
    environment: production    # utilise les secrets de l'environnement "production"
    steps:
      - name: Deploy to production
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}  # la valeur de prod, pas de staging
        run: ./scripts/deploy.sh

🛡️ Sécuriser ses workflows GitHub Actions

Le risque : l'injection de commandes

Un workflow qui utilise ${{ github.event.pull_request.title }} peut être exploité si le titre d'une PR contient du code malveillant.

yaml
# ❌ Dangereux : un attaquant peut injecter des commandes dans le titre de la PR
- name: Greet contributor
  run: echo "Merci pour ${{ github.event.pull_request.title }}"

# ✅ Sécurisé : passer par une variable d'environnement
- name: Greet contributor
  env:
    PR_TITLE: ${{ github.event.pull_request.title }}
  run: echo "Merci pour $PR_TITLE"

Pincer les versions des actions

yaml
# ❌ Dangereux : si le mainteneur pousse du code malveillant sur @main, tu l'exécutes
- uses: some-action/checkout@main

# ✅ Bien : version sémantique (le mainteneur peut modifier un tag existant)
- uses: actions/checkout@v4

# ✅✅ Optimal : SHA de commit (immuable - impossible à modifier)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

Principe du moindre privilège

yaml
# ❌ Trop de permissions
permissions: write-all

# ✅ Permissions minimales et explicites
permissions:
  contents: read      # lire le code
  packages: write     # publier une image Docker
  # tout le reste est refusé par défaut

Exemple : workflow sécurisé complet

yaml
name: CI Sécurisé

on:
  pull_request:
    branches: [main]

# Permissions minimales par défaut pour tout le workflow
permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      # SHA pinné
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci    # préféré à npm install en CI : reproductible et sécurisé

      - name: Run tests
        run: npm test

      - name: Audit dependencies
        run: npm audit --audit-level=high  # échoue si vulnérabilité HIGH ou CRITICAL

📊 Récapitulatif des outils

OutilTypeCe qu'il détecteGratuit
DependabotSCADépendances vulnérables, mises à jour✅
CodeQLSASTFailles dans le code source✅ (dépôts publics)
TrivyScannerVulnérabilités dans les images Docker✅
npm auditSCADépendances Node.js vulnérables✅
gitleaksDétectionSecrets commités dans Git✅

✅ Checklist Sécurité Intermédiaire

  • dependabot.yml configuré (npm + github-actions)
  • Dependabot security updates activé
  • Workflow CodeQL en place sur main et PRs
  • Trivy intégré dans le pipeline CI (avec exit-code: 1)
  • Secrets stockés dans GitHub Secrets (pas dans le code)
  • Environments configurés pour prod vs staging
  • Actions pinnées par version ou SHA
  • permissions: explicites dans chaque workflow
  • Variables d'environnement pour les inputs GitHub (pas d'injection directe)

🚀 Prochaines Étapes

Tu sécurises maintenant ton code et ton pipeline automatiquement. L'étape suivante : la sécurité de l'infrastructure et de la supply chain.

  • 👉 Sécurité DevOps - Avancé - Vault, supply chain, Kubernetes, compliance as code
  • 👉 Kubernetes - Débutant - Déployer ses premiers pods

Exercices Pratiques

5 exercices pour mettre en pratique

01

01 - Configurer Dependabot pour la mise à jour automatique des dépendances

25 minutesIntermédiaire
02

02 - Mettre en place CodeQL pour l'analyse statique du code

30 minutesIntermédiaire
03

03 - Intégrer Trivy dans un pipeline CI/CD GitHub Actions

30 minutesIntermédiaire
04

04 - Gérer les secrets dans GitHub Actions avec les environnements

30 minutesIntermédiaire
05

05 - Capstone : Pipeline DevSecOps complet

1hAvancé
Retour aux modules

Sur cette page

  • 🎯 Objectifs
  • 📋 Prérequis
  • 🤔 Pourquoi automatiser la sécurité ?
  • 🤖 Dependabot : mises à jour automatiques des dépendances
  • Qu'est-ce que Dependabot ?
  • L'analogie
  • Configuration
  • Alertes de sécurité vs mises à jour
  • 🔍 SAST : analyser ton code statiquement
  • Qu'est-ce que le SAST ?
  • GitHub Code Scanning avec CodeQL
  • 🐳 Scanner les images Docker avec Trivy
  • Pourquoi scanner une image ?
  • L'analogie
  • Utiliser Trivy en local
  • Intégrer Trivy dans GitHub Actions
  • 🔑 Gérer les secrets dans GitHub Actions
  • Les GitHub Secrets
  • Environments : secrets par environnement
  • 🛡️ Sécuriser ses workflows GitHub Actions
  • Le risque : l'injection de commandes
  • Pincer les versions des actions
  • Principe du moindre privilège
  • Exemple : workflow sécurisé complet
  • 📊 Récapitulatif des outils
  • ✅ Checklist Sécurité Intermédiaire
  • 🚀 Prochaines Étapes