Sécurité GitHub Actions : les bases
Mise à jour :
Vous ne le savez peut-être pas, mais vos workflows GitHub Actions ont accès à vos secrets, peuvent modifier votre code, et déployer en production du code malveillant sans que vous ne vous en rendiez compte. Un workflow mal sécurisé, c’est une porte ouverte pour les attaquants.
Pourquoi la sécurité sur les pipelines CI/CD est importante ?
Votre pipeline CI/CD est une cible de choix :
Concrètement, votre pipeline :
- A accès aux secrets : tokens d’API, mots de passe de bases de données, clés de déploiement cloud…
- Peut publier des packages : sur npm, PyPI, Docker Hub, ou votre registre privé
- Peut déployer en production : modifier ce qui tourne sur vos serveurs
- Exécute du code sur des machines : avec potentiellement des accès réseau internes
Un attaquant qui compromet votre pipeline peut faire tout ça à votre place. C’est comme s’il avait les clés de votre infrastructure.
C’est quoi une attaque “supply chain” ?
Une attaque supply chain (chaîne d’approvisionnement) ne vous cible pas directement. Elle cible quelque chose que vous utilisez.
Analogie : le restaurant
Imaginez un restaurant :
Un attaquant peut :
- Attaquer le restaurant (difficile, bien protégé)
- Attaquer le fournisseur de légumes (plus facile, moins surveillé)
Si le fournisseur est compromis, les légumes contaminés arrivent au restaurant, qui les sert aux clients. Le restaurant n’a rien fait de mal, mais ses clients sont impactés.
Dans GitHub Actions
Vous n’avez pas de faille dans votre code, mais :
- Une action que vous utilisez est compromise
- Une dépendance npm que vous installez contient du code malveillant (voir SCA)
- Une image Docker de base a été modifiée
Exemples réels d’attaques supply chain
Voici quelques attaques célèbres sur la supply chain logicielle :
| Année | Attaque | Ce qui s’est passé |
|---|---|---|
| 2021 | Codecov | Un script de téléchargement modifié volait les secrets CI |
| 2022 | ua-parser-js | Package npm populaire infecté, minait de la crypto |
| 2024 | xz-utils | Backdoor caché dans une lib de compression Linux |
Ces attaques ont touché des milliers d’entreprises sans qu’elles aient fait d’erreur dans leur propre code.
Les 3 risques principaux
Voici les 3 risques de sécurité les plus courants dans GitHub Actions :
1. Les secrets exposés
Qu’est-ce qu’un secret ? Un secret, c’est une information confidentielle dont votre application a besoin pour fonctionner : mot de passe de base de données, clé d’API pour un service externe, token d’accès à un registre Docker… Pensez-y comme les clés de votre maison : si quelqu’un les trouve, il peut entrer.
Pourquoi c’est un problème dans les workflows ? Votre workflow a souvent besoin de ces secrets pour déployer, publier un package ou accéder à un service. Le danger, c’est de les exposer par accident.
Deux erreurs classiques :
# ❌ Erreur 1 : Le secret est écrit en dur dans le code# Tout le monde peut le voir dans l'historique Git !- run: curl -H "Authorization: Bearer sk-123456789"
# ❌ Erreur 2 : Afficher un secret pour "débuguer"# Il apparaît dans les logs, visibles par tous les collaborateurs- run: echo "Debug: ${{ secrets.API_KEY }}"La bonne pratique : stockez vos secrets dans GitHub (Settings → Secrets) et
référencez-les avec ${{ secrets.NOM }}. GitHub les masque automatiquement dans
les logs.
# ✅ Le secret est stocké dans GitHub, pas dans le code# Personne ne peut le voir, même dans l'historique Git- run: curl -H "Authorization: Bearer ${{ secrets.API_KEY }}"2. Les actions tierces non vérifiées
Qu’est-ce qu’une action ? Une action GitHub, c’est un bout de code
réutilisable que quelqu’un a publié. Au lieu de réécrire la logique pour
“checkout le code” ou “publier sur npm”, vous utilisez une action existante avec
uses:.
Pourquoi c’est pratique ? Ça évite de réinventer la roue. La communauté a créé des milliers d’actions pour tout : déployer sur AWS, envoyer une notification Slack, analyser du code…
Pourquoi c’est risqué ? Quand vous écrivez uses: quelquun/super-action@v1,
vous exécutez du code écrit par un inconnu sur vos runners. Ce code a accès à
tout ce que votre workflow peut faire, y compris lire vos secrets.
C’est comme inviter un inconnu chez vous et lui donner vos clés. Peut-être qu’il est de confiance… ou peut-être pas.
# ⚠️ Questions à se poser :# - Qui est "random-user" ? Une entreprise ? Un particulier ?# - Que fait vraiment cette action ? Ai-je lu le code ?# - Est-elle maintenue ? Dernière mise à jour il y a 3 ans ?- uses: random-user/deploy-magic@v1 with: token: ${{ secrets.DEPLOY_KEY }} # On lui donne nos clés !La bonne pratique : n’utilisez que des actions de sources fiables (GitHub, grandes entreprises, projets populaires) et épinglez-les par SHA pour éviter les modifications surprises (détaillé plus bas).
3. Le code des pull requests
Qu’est-ce qu’une pull request (PR) ? Une PR, c’est une proposition de modification du code. Sur un projet open source, n’importe qui peut forker le repo (en faire une copie), modifier le code, puis proposer ses changements via une PR.
Pourquoi c’est un vecteur d’attaque ? Par défaut, quand quelqu’un ouvre une PR, les workflows du repo s’exécutent pour tester le code proposé. Un attaquant peut donc :
- Forker votre repo (créer sa propre copie)
- Modifier le workflow pour qu’il affiche ou envoie vos secrets quelque part
- Ouvrir une PR vers votre repo
- Récupérer vos secrets quand le workflow s’exécute
La bonne nouvelle : GitHub a prévu le coup. Par défaut, les workflows déclenchés par des PRs venant de forks n’ont pas accès aux secrets. L’attaquant peut modifier le workflow, mais il ne récupérera rien.
La règle d’or : ne désactivez jamais cette protection, et méfiez-vous de
pull_request_target qui contourne cette sécurité (on en reparle dans la
section avancée).
Les réflexes de base
Pour sécuriser vos workflows GitHub Actions, adoptez ces 5 réflexes simples :
1. Vérifier les actions avant de les utiliser
Avant d’ajouter une nouvelle action, demandez-vous :
- Qui l’a créée ? (GitHub, entreprise connue, inconnu ?)
- Est-elle maintenue ? (dernière mise à jour récente ?)
- Combien de personnes l’utilisent ? (populaire = plus d’yeux dessus)
- Ai-je vraiment besoin d’une action ? (parfois un
run:suffit)
2. Épingler les actions par SHA
Le problème des tags (@v1, @latest) : ils peuvent changer.
# ❌ Si quelqu'un modifie ce que pointe "v4", votre workflow change- uses: actions/checkout@v4
# ✅ Le SHA est immuable - personne ne peut le modifier- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2Le SHA (la longue chaîne de caractères) pointe vers une version exacte du code. Même si le mainteneur de l’action est compromis, votre workflow continue d’utiliser la version que vous avez vérifiée.
- Allez sur le repository de l’action (ex: github.com/actions/checkout)
- Cliquez sur “Releases”
- Trouvez la version souhaitée
- Copiez le SHA du commit
Ou utilisez pin-github-action pour le faire automatiquement :
npx pin-github-action .github/workflows/ci.yml3. Limiter les permissions
Par défaut, appliquez le principe de moindre privilège :
# ✅ Permissions explicites et minimalespermissions: contents: read # Juste lire le code, pas le modifier
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - run: npm testSi votre workflow est compromis et qu’il n’a que contents: read, l’attaquant
ne peut pas modifier votre code.
4. Ne jamais stocker de secrets dans le code
Ça paraît évident, mais c’est l’erreur la plus fréquente. Les secrets doivent être stockés dans GitHub (Settings → Secrets and variables → Actions) et jamais dans le code, même “temporairement”.
# ❌ JAMAIS - le secret est visible dans l'historique Git pour toujoursenv: API_KEY: "sk-1234567890abcdef"
# ✅ Le secret est stocké dans GitHub, référencé par son nomenv: API_KEY: ${{ secrets.API_KEY }}Même si vous supprimez le commit, il reste dans l’historique. Si vous avez commis un secret par erreur, considérez-le comme compromis et régénérez-le immédiatement.
5. Ne pas faire confiance aux PRs de forks
C’est le comportement par défaut de GitHub, ne le changez pas :
on: pull_request: # ✅ Pas d'accès aux secrets pour les forks
# ⚠️ DANGEREUX - pull_request_target donne accès aux secrets# Ne l'utilisez pas sans comprendre les risquesRécapitulatif : checklist de base
Avant de mettre un workflow en production :
Secrets et permissions :
- Pas de secrets dans le code — utilisez
${{ secrets.* }} - Permissions déclarées —
permissions:en haut du workflow avec le minimum nécessaire - Pas de
permissions: write-all— listez uniquement ce dont vous avez besoin
Actions et dépendances :
- Actions vérifiées — de source connue et maintenue
- Orthographe vérifiée — pas de typosquatting (
actions/checkoutet nonaction/checkout) - Évaluer les dépendances — utilisez OpenSSF Scorecard ↗ pour vérifier la maturité sécurité des projets
- Actions épinglées par SHA — pas de
@v1ou@latest
Pull requests :
- Pas de
pull_request_target— sauf si vous comprenez les risques - Approbation requise — pour les workflows sur PR de contributeurs externes
Bonnes pratiques avancées :
- Dependabot activé — pour les mises à jour automatiques des actions
- Branch protection — exiger des reviews et des checks avant merge
- Audit régulier — vérifier périodiquement les actions utilisées
Ce qu’il faut retenir
Cette page couvre les fondamentaux de la sécurité GitHub Actions. C’est une première étape : vous découvrirez d’autres bonnes pratiques au fil de la formation (OIDC, attestations, runners auto-hébergés…).
Oui, c’est beaucoup d’informations d’un coup. Mais si vous lisez cette page jusqu’au bout et que vous appliquez ces principes, vous aurez déjà une longueur d’avance sur la majorité des développeurs. La sécurité CI/CD est un sujet que peu maîtrisent vraiment — vous êtes sur le bon chemin.
On passe à la suite ! La gestion des secrets dans GitHub vous attend.
Contrôle des connaissances
Testez vos connaissances sur la sécurité GitHub Actions.
Pourquoi ce contrôle ?
Cet contrôle va vous permettre de valider vos connaissances sur le sujet abordé dans le guide. Il comporte des QCM, des questions vrai/faux et des réponses ouvertes à un mot.
🕒 Le chronomètre commence dès que vous cliquez sur Démarrer le test. Vous devrez terminer l’examen avant la fin du temps imparti.
🎯 Pour réussir, vous devez obtenir au moins 70% de bonnes réponses.
💡 Je ne fournis pas directement les réponses aux questions. Cependant, si certaines sont complexes, des pistes d’explication pourront être proposées dans le guide ou après l’examen.
Bonne chance ! 🚀
La suite …
Vous avez su répondre aux questions ? Félicitations ! Vous avez acquis les bases de la sécurité dans GitHub Actions. Vous pouvez aller à la suite avec la gestion des secrets dans GitHub