Sécuriser une pipeline
Secrets, permissions, isolation : durcir la chaîne elle-même.
Une pipeline est un moteur d'exécution qui a accès à tout ce qui compte : vos secrets — mots de passe, clés d'API, jetons —, votre code source, et vos environnements de production. Si elle est compromise, l'attaquant injecte du code malveillant dans tout ce que vous livrez sans jamais toucher directement à vos serveurs. C'est empoisonner la source plutôt que chaque verre.
En bref
L'objectif de ce cours n'est pas de lister des outils, mais de comprendre les surfaces de contrôle sur lesquelles agir — identités, dépendances, runners, artefacts — quel que soit l'outil employé.
La pipeline comme surface d'attaque
Une chaîne d'intégration concentre trois choses qu'un attaquant recherche : des identifiants vers la production, un droit d'écriture sur les artefacts livrés, et une exécution de code automatique que personne ne relit. C'est la combinaison, plus que chaque élément isolé, qui en fait une cible de premier plan.
| Ressource | Ce que l'attaquant peut faire | Exemple concret |
|---|---|---|
| Secrets | voler jetons d'API, clés SSH, identifiants cloud | accéder à votre compte cloud avec vos propres clés |
| Code source | modifier le code avant compilation | ajouter une porte dérobée invisible |
| Artefacts | injecter du code malveillant dans les livrables | vos utilisateurs téléchargent une version infectée |
| Production | déployer directement du code malveillant | prendre le contrôle de vos serveurs |
Quatre ressources, un seul point d'entrée.
Cas réel : `tj-actions/changed-files` (2025)
Une action GitHub très employée a été compromise. En quelques heures, elle a exfiltré les secrets de milliers de projets. Rien n'était visible : l'action fonctionnait normalement, mais envoyait les secrets à un serveur externe.
Les quatre piliers
La sécurité d'une pipeline repose sur quatre piliers. Chacun correspond à une décision de confiance qui doit être explicite et vérifiable.
Négliger un pilier suffit : les quatre portent la même chaîne.
Pilier 1 — identités et permissions
La question n'est pas de savoir si la pipeline doit s'authentifier, mais avec quoi et pour combien de temps. Un secret de longue durée reste valable après le départ de son auteur, et après la compromission qui l'a fait fuiter.
Moindre privilège
{Chaque job n'obtient que ce dont il a besoin — rien de plus.}
# À ÉVITER : tous les droits, pour tout le monde
permissions: write-all
# CORRECT : le strict necessaire
permissions:
contents: read # lire le code, pas le modifier
packages: write # publier des paquets, rien d'autreJetons éphémères plutôt que secrets permanents
| Caractéristique | Secret statique | Jeton éphémère (OIDC) |
|---|---|---|
| Durée de vie | illimitée | quelques minutes |
| S'il est volé | utilisable jusqu'à détection | expire de lui-même |
| Révocation | manuelle, souvent oubliée | automatique |
OIDC permet de demander un jeton temporaire à chaque exécution, au lieu de stocker un secret permanent.
Séparation par environnement
Les secrets de staging doivent différer de ceux de production : si un secret de développement fuite, la production reste protégée. C'est le même principe que celui posé au chapitre , appliqué ici comme contrôle de sécurité et non comme commodité.
Avant de configurer les accès d'un job
- ce jeton a-t-il besoin d'écrire, ou seulement de lire ?
- peut-on employer OIDC au lieu d'un secret statique ?
- que se passe-t-il si ce secret est volé ?
- quand a-t-il été renouvelé pour la dernière fois ?
Pilier 2 — dépendances
Le code que vous écrivez ne représente qu'une fraction de ce qui s'exécute. Le
reste vient de paquets tiers dont vous ne contrôlez ni les mainteneurs, ni les
mises à jour, ni les scripts d'installation. Chaque npm install, chaque
pip install, chaque action tierce est du code qui s'exécute avec les
permissions de votre pipeline.
Épingler par empreinte, pas par tag
Un tag comme @v4 est mutable : le mainteneur peut le déplacer à tout
moment. Une empreinte SHA est immuable.
{Le tag désigne une intention l'empreinte désigne un contenu.}
# À ÉVITER : tag mutable, peut changer sans prevenir
- uses: actions/checkout@v4
# CORRECT : empreinte immuable, toujours le meme code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683L'empreinte se relève sur la page des publications du dépôt de l'action : on copie le SHA complet du commit correspondant à la version voulue.
Versionner les fichiers de verrouillage
| Sans fichier de verrouillage | Avec |
|---|---|
npm install récupère les dernières versions | npm ci installe exactement les versions enregistrées |
| résultat différent à chaque exécution | résultat identique à chaque exécution |
| une mise à jour peut casser la construction | les montées de version sont contrôlées et testées |
Le fichier de verrouillage est une mesure de sécurité autant qu'une mesure de reproductibilité.
Auditer avant d'ajouter
| Critère | Pourquoi c'est important |
|---|---|
| Qui la maintient ? | un mainteneur unique est un risque |
| Depuis combien de temps ? | une dépendance récente n'a pas fait ses preuves |
| Combien de téléchargements ? | peu d'usages, peu d'yeux pour détecter un problème |
| Le code est-il lisible ? | du code obfusqué cache peut-être quelque chose |
Quatre questions à se poser avant d'ajouter une ligne à un fichier de dépendances.
Avant d'ajouter une dépendance
- cette dépendance est-elle vraiment nécessaire ?
- avons-nous regardé son code source ?
- que se passe-t-il si le mainteneur perd l'accès à son compte ?
- avons-nous un plan si elle disparaît ?
Pilier 3 — runners et isolation
Le runner exécute le code de vos jobs avec ses propres droits, sur sa propre machine. Tout ce qu'il conserve d'une exécution à l'autre — cache, identifiants, fichiers temporaires — devient accessible au job suivant, y compris s'il provient d'une contribution externe.
| Runner persistant | Runner éphémère |
|---|---|
| le job 1 modifie des fichiers | le job 1 s'exécute, le runner est détruit |
| le job 2 hérite de ces modifications | le job 2 obtient un runner neuf |
| un code malveillant peut persister | rien ne peut persister |
L'éphémérité supprime le vecteur principal de contamination d'un job à l'autre.
Deux mesures complètent l'éphémérité. L'isolation réseau : le runner n'accède qu'aux ressources strictement nécessaires, jamais au réseau interne par défaut. La séparation des contextes : quand une personne extérieure ouvre une demande de fusion depuis un fork, le code qu'elle propose s'exécute sur vos runners — il ne doit jamais voir vos secrets.
Par défaut, certaines plateformes donnent accès aux secrets même depuis un fork : c'est à vérifier explicitement.
Sur l'exécution
- le runner est-il détruit après chaque job ?
- que peut voir un job malveillant exécuté dessus ?
- les forks ont-ils accès aux mêmes ressources que les branches internes ?
- comment détecterait-on une compromission du runner ?
Pilier 4 — artefacts et chaîne de confiance
Entre la construction d'un artefact et son déploiement, rien ne prouve par défaut qu'il s'agit du même contenu. Sans empreinte vérifiable ni signature, un remplacement en cours de route est indétectable par celui qui l'installe.
| Artefact non signé | Artefact signé |
|---|---|
| origine inconnue | origine vérifiable |
| intégrité incertaine | intégrité garantie |
| « faites-moi confiance » | « vérifiez vous-même » |
Signer, c'est apposer une empreinte qui rend toute modification ultérieure détectable.
Deux compléments à la signature. L'attestation de provenance décrit comment l'artefact a été construit : quel commit, quelle pipeline, dans quel environnement, avec quelles dépendances. Le SBOM — inventaire logiciel — énumère tous les composants inclus, comme la liste des ingrédients sur un emballage : quand une vulnérabilité majeure est publiée, vous savez en quelques secondes si vos artefacts sont concernés.
Trois preuves distinctes : l'origine, le procédé, le contenu.
Sur les livrables
- nos artefacts sont-ils signés ?
- peut-on vérifier leur provenance ?
- avons-nous l'inventaire de ce qu'ils contiennent ?
- qui peut publier dans notre registre ?
Contrôles structurels et contrôles ponctuels
Il existe deux types de contrôles, et ils ne se valent pas. Les contrôles ponctuels sont des vérifications exécutées à un moment précis : scan de vulnérabilités avant déploiement, analyse statique, tests de sécurité sur une demande de fusion. Leur limite : un contrôle ponctuel peut être contourné, désactivé, ou simplement oublié. Les contrôles structurels sont des contraintes architecturales qu'on ne peut pas contourner.
| Contrôle structurel | Pourquoi il est plus solide |
|---|---|
| Permissions minimales par défaut | impossible d'obtenir plus de droits que prévu |
| Runners éphémères | impossible de faire persister un code malveillant |
| Signature obligatoire avant déploiement | impossible de déployer un artefact non vérifié |
| OIDC au lieu de secrets statiques | impossible de voler un jeton permanent |
Privilégiez le structurel : le ponctuel est un filet supplémentaire, pas un rempart.
Modèle de maturité
Niveau 1 — hygiène de base
- permissions minimales sur chaque job
- fichiers de verrouillage versionnés et utilisés (
npm ci) - aucun secret en dur dans le code.
Niveau 2 — épinglage et isolation
- dépendances et actions épinglées par empreinte
- runners éphémères, détruits après chaque job
- secrets distincts par environnement.
Niveau 3 — vérification et traçabilité
- artefacts signés cryptographiquement
- SBOM généré à chaque construction
- attestations de provenance.
Niveau 4 — confiance zéro
- OIDC partout où c'est possible
- vérification obligatoire avant tout déploiement
- surveillance des comportements anormaux sur les runners.
À retenir de cette séance
Une pipeline compromise donne accès à vos secrets, votre code et votre production. Les quatre piliers sont les identités, les dépendances, les runners et les artefacts. Moindre privilège : chaque job n'a que les permissions strictement nécessaires. Épinglage par empreinte : les tags sont mutables, les SHA ne le sont pas. Runners éphémères : détruire après chaque job empêche toute persistance. Signez vos artefacts. Et privilégiez les contrôles structurels, impossibles à contourner, aux contrôles ponctuels.
Pour aller plus loin
| Ressource | Ce qu'on y trouve |
|---|---|
| Sécurité de la chaîne d'approvisionnement | vue d'ensemble du domaine |
| SLSA | niveaux de confiance, modèle de garanties |
| SBOM | inventaire des composants d'un artefact |
| VEX | exploitabilité des vulnérabilités, pour prioriser |
| Cosign | signature des artefacts, vérification d'origine |
| Syft | génération automatisée de SBOM |
| OpenSSF Scorecard | évaluation de la santé d'un projet ouvert |
| Épinglage par SHA | sécuriser les actions d'une forge |
Huit points d'entrée pour approfondir, du modèle de garanties à l'outillage.
Réponse unique
Pourquoi épingler une action par son empreinte plutôt que par son tag ?
Indice · Qu'est-ce qui peut être redéplacé après coup ?
[ METTRE EN PRATIQUE ]
Durcir une pipeline
3 étapes · 30 min · 130 XP
[ CETTE LEÇON DANS LES PARCOURS ]
- Cybersécuritéétape 10 / 13suivant — La confiance implicite →