CaenHackYouAcademy
DevSecOps

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.

RessourceCe que l'attaquant peut faireExemple concret
Secretsvoler jetons d'API, clés SSH, identifiants cloudaccéder à votre compte cloud avec vos propres clés
Code sourcemodifier le code avant compilationajouter une porte dérobée invisible
Artefactsinjecter du code malveillant dans les livrablesvos utilisateurs téléchargent une version infectée
Productiondéployer directement du code malveillantprendre 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'autre

Jetons éphémères plutôt que secrets permanents

CaractéristiqueSecret statiqueJeton éphémère (OIDC)
Durée de vieillimitéequelques minutes
S'il est voléutilisable jusqu'à détectionexpire de lui-même
Révocationmanuelle, souvent oubliéeautomatique

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@11bd71901bbe5b1630ceea73d27597364c9af683

L'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 verrouillageAvec
npm install récupère les dernières versionsnpm ci installe exactement les versions enregistrées
résultat différent à chaque exécutionrésultat identique à chaque exécution
une mise à jour peut casser la constructionles 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èrePourquoi 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 persistantRunner éphémère
le job 1 modifie des fichiersle job 1 s'exécute, le runner est détruit
le job 2 hérite de ces modificationsle job 2 obtient un runner neuf
un code malveillant peut persisterrien 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 inconnueorigine vérifiable
intégrité incertaineinté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 structurelPourquoi il est plus solide
Permissions minimales par défautimpossible d'obtenir plus de droits que prévu
Runners éphémèresimpossible de faire persister un code malveillant
Signature obligatoire avant déploiementimpossible de déployer un artefact non vérifié
OIDC au lieu de secrets statiquesimpossible 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

RessourceCe qu'on y trouve
Sécurité de la chaîne d'approvisionnementvue d'ensemble du domaine
SLSAniveaux de confiance, modèle de garanties
SBOMinventaire des composants d'un artefact
VEXexploitabilité des vulnérabilités, pour prioriser
Cosignsignature des artefacts, vérification d'origine
Syftgénération automatisée de SBOM
OpenSSF Scorecardévaluation de la santé d'un projet ouvert
Épinglage par SHAsécuriser les actions d'une forge

Huit points d'entrée pour approfondir, du modèle de garanties à l'outillage.

VérificationQuestion 1 / 3

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 ]

On this page