Sécuriser les runners GitHub Actions : architecture, risques et bonnes pratiques

GitHub Actions est devenu l’une des plateformes CI/CD les plus largement adoptées. Sa flexibilité, son intégration étroite avec les dépôts GitHub et son riche écosystème en font un choix attractif pour les équipes de toutes tailles.

Parallèlement, les runners GitHub Actions sont apparus comme une surface d’attaque critique dans les attaques modernes contre la chaîne d’approvisionnement logicielle.

Les runners exécutent du code non fiable, manipulent des secrets sensibles et opèrent souvent avec des permissions étendues sur les dépôts, les registres d’artefacts et les environnements cloud.

Cet article explique le fonctionnement des runners GitHub Actions, pourquoi ils sont fréquemment ciblés par les attaquants, et comment concevoir des architectures de runners qui réduisent significativement les risques sans perturber les workflows des développeurs.


Qu’est-ce qu’un runner GitHub Actions ?

Un runner est l’environnement d’exécution dans lequel les workflows GitHub Actions s’exécutent réellement. Chaque job d’un workflow est exécuté sur un runner.

Du point de vue de la sécurité, les runners sont le composant le plus sensible de l’architecture GitHub Actions car ils :

  • Exécutent du code arbitraire provenant des workflows
  • Traitent le contenu des dépôts et les dépendances
  • Accèdent aux secrets et aux tokens
  • Produisent les artefacts de build

Si un runner est compromis, l’attaquant peut être en mesure de :

  • Exfiltrer des secrets
  • Modifier les résultats de build
  • Persister entre les jobs ou les workflows
  • Se déplacer latéralement vers d’autres systèmes

Types de runners GitHub Actions

Comprendre la sécurité des runners commence par comprendre les types de runners. GitHub Actions prend en charge plusieurs modèles de runners, chacun avec des caractéristiques de confiance et de risque différentes.


Runners hébergés par GitHub

Les runners hébergés par GitHub sont gérés par GitHub et fournis sous forme de machines virtuelles éphémères. Chaque job s’exécute généralement sur une VM neuve qui est détruite après l’exécution.

Caractéristiques de sécurité :

  • Éphémères par défaut
  • Isolation forte entre les jobs
  • Pas d’état persistant entre les exécutions
  • Personnalisation limitée

Du point de vue de la sécurité, les runners hébergés par GitHub offrent une base solide pour les charges de travail non fiables telles que les pull requests.

Cependant, ils ne sont pas sans risque. L’exposition des secrets, l’utilisation abusive des permissions et la logique de workflow malveillante peuvent toujours conduire à une compromission.


Runners self-hosted

Les runners self-hosted s’exécutent sur une infrastructure gérée par l’organisation : machines virtuelles, serveurs physiques ou conteneurs.

Ils sont souvent utilisés pour :

  • Accéder aux ressources internes
  • Utiliser des outils ou environnements personnalisés
  • Optimiser les performances ou les coûts

Du point de vue de la sécurité, les runners self-hosted introduisent des risques significatifs :

  • Persistance entre les jobs
  • État partagé entre les workflows
  • Accès réseau aux systèmes internes
  • Rayon d’impact plus élevé en cas de compromission

Sans une isolation forte, un seul job compromis peut affecter les builds futurs ou d’autres dépôts.


Runners self-hosted éphémères

Les runners self-hosted éphémères combinent la flexibilité des runners self-hosted avec les avantages sécuritaires de l’éphémérité.

Chaque job s’exécute sur un runner fraîchement provisionné qui est détruit après la fin de l’exécution.

Ce modèle réduit significativement :

  • Le risque de persistance
  • La contamination inter-jobs
  • La compromission de longue durée

Du point de vue de la sécurité, les runners self-hosted éphémères sont fortement préférés aux runners persistants.


Pourquoi les runners sont une cible privilégiée

Les runners se situent à l’intersection des entrées non fiables et des opérations privilégiées. Cela en fait des cibles attractives pour les attaquants.


Les runners exécutent du code non fiable

Les workflows peuvent exécuter du code provenant de :

  • Pull requests
  • Branches de fonctionnalité
  • Dépendances
  • Actions tierces

N’importe laquelle de ces sources peut être influencée par un attaquant. Si du code non fiable s’exécute sur un runner disposant de secrets ou de permissions élevées, la compromission est immédiate.


Les runners ont souvent accès aux secrets

Les secrets sont couramment exposés aux runners via des variables d’environnement.

Si les conditions du workflow sont mal configurées, les secrets peuvent être accessibles par :

  • Les pull requests issues de forks
  • Les contributeurs non fiables
  • Les actions tierces malveillantes

Une fois qu’un secret est exposé, il est souvent difficile de le détecter ou de le contenir.


Les runners peuvent influencer les artefacts et les releases

Les runners compilent et empaquettent les artefacts logiciels.

Si un attaquant modifie le résultat du build, l’artefact résultant peut être distribué avec une confiance totale en aval.

Sans vérifications d’intégrité des artefacts, il peut être impossible de détecter la compromission.


Scénarios d’attaque courants liés aux runners

La modélisation des menaces sur les runners révèle des schémas d’attaque récurrents.


Scénario 1 : Abus de pull request

Un attaquant soumet une pull request qui modifie la logique du workflow ou introduit des étapes de build malveillantes.

Si le workflow expose des secrets ou des tokens privilégiés aux builds de PR, l’attaquant peut exfiltrer les identifiants.

Cette attaque ne nécessite aucune vulnérabilité — seulement une mauvaise configuration de la confiance.


Scénario 2 : Compromission d’une action tierce

Les workflows utilisent fréquemment des actions tierces.

Si une action est compromise en amont ou référencée sans épinglage sur un commit spécifique, l’attaquant peut injecter un comportement malveillant dans les workflows.

Le runner exécute l’action avec les mêmes permissions que le code de workflow interne.


Scénario 3 : Compromission d’un runner self-hosted persistant

Sur les runners self-hosted persistants, un attaquant peut :

  • Installer des backdoors
  • Modifier les outils locaux
  • Empoisonner les caches
  • Persister entre les jobs

Les workflows futurs peuvent exécuter du code contrôlé par l’attaquant sans le savoir.


Scénario 4 : Mouvement latéral via l’infrastructure des runners

Les runners self-hosted ont souvent un accès réseau aux systèmes internes ou aux environnements cloud.

Un runner compromis peut être utilisé comme pivot pour attaquer d’autres services internes.


Principes d’architecture de sécurité des runners

Sécuriser les runners GitHub Actions est un problème d’architecture, pas un problème de checklist.

Une sécurité efficace des runners repose sur quelques principes fondamentaux.


1. Traiter les runners comme des environnements d’exécution non fiables

Les runners exécutent des entrées non fiables par conception.

Ils ne devraient jamais être implicitement considérés comme fiables, même s’ils fonctionnent au sein d’une infrastructure interne.

Les secrets, l’accès réseau et les privilèges doivent être limités en conséquence.


2. Préférer l’éphémérité au nettoyage

Tenter de « nettoyer » un runner compromis n’est pas fiable.

Détruire et recréer les runners après chaque job offre une garantie de sécurité bien plus forte.

Les runners éphémères éliminent la persistance et réduisent significativement le temps de séjour de l’attaquant.


3. Appliquer le principe du moindre privilège au niveau du job

Chaque job ne devrait recevoir que les permissions dont il a besoin.

Cela inclut :

  • Les permissions sur les dépôts
  • Les scopes des tokens
  • Les identités cloud

Évitez d’accorder des permissions globales ou des permissions d’écriture par défaut.


4. Séparer les charges de travail fiables et non fiables

Les builds de pull requests, les contributions externes et le code non fiable doivent s’exécuter dans des environnements séparés des jobs de release ou de déploiement fiables.

Cette séparation peut être appliquée via :

  • Des pools de runners différents
  • Des workflows différents
  • Des ensembles de permissions différents

5. Réduire la surface d’attaque des runners

Minimisez ce qui est disponible sur les runners :

  • Désactivez les outils inutiles
  • Restreignez l’accès réseau sortant
  • Limitez l’accès en écriture au système de fichiers
  • Évitez les caches de longue durée

Une surface d’attaque réduite limite les options de l’attaquant.


Bonnes pratiques pour sécuriser les runners GitHub Actions

Les pratiques suivantes répondent aux risques les plus courants liés aux runners sans modifier fondamentalement les workflows des développeurs.


Utiliser les runners hébergés par GitHub pour le code non fiable

Pour les pull requests et les contributions externes, les runners hébergés par GitHub offrent une isolation forte et une éphémérité automatique.

Évitez d’exposer des secrets à ces jobs sauf en cas de nécessité absolue.


Adopter les runners self-hosted éphémères pour les charges sensibles

Si des runners self-hosted sont nécessaires, rendez-les éphémères.

Chaque job devrait :

  • Provisionner un runner neuf
  • Exécuter un seul job
  • Être détruit immédiatement après

Ce modèle réduit considérablement le risque de persistance.


Verrouiller explicitement les permissions

Utilisez le modèle de permissions granulaires de GitHub.

Définissez les permissions au niveau du workflow ou du job au lieu de vous appuyer sur les valeurs par défaut.

Examinez les modifications de permissions aussi attentivement que les modifications de code.


Épingler et auditer les actions tierces

Épinglez toujours les actions sur un SHA de commit spécifique.

Évitez d’utiliser des actions qui :

  • Ne sont plus maintenues
  • Manquent de transparence
  • Exécutent une logique inattendue

Traitez les actions comme faisant partie de votre chaîne d’approvisionnement.


Protéger agressivement les secrets

Évitez d’exposer des secrets aux workflows déclenchés par :

  • Des dépôts forkés
  • Des pull requests non fiables

Préférez les identifiants à durée de vie courte et l’accès basé sur l’identité plutôt que les secrets statiques.


Valider les résultats de build

Ne présumez pas que les artefacts produits par les runners sont fiables.

Utilisez :

  • La signature des artefacts
  • Les attestations de provenance
  • Des portes de vérification avant le déploiement

Cela garantit que des runners compromis ne peuvent pas empoisonner silencieusement les releases.


Place de la sécurité des runners dans une stratégie CI/CD globale

La sécurité des runners est une composante de la sécurité des pipelines, mais elle ne peut pas fonctionner seule.

Elle doit être combinée avec :

  • La modélisation des menaces CI/CD
  • Les frontières de confiance des pipelines
  • L’application des politiques
  • La vérification de l’intégrité des artefacts

Sans ces éléments, même des runners bien sécurisés peuvent encore produire des résultats non fiables.


Conclusion

Les runners GitHub Actions sont un puissant outil d’automatisation, mais ils représentent également un environnement d’exécution à haut risque.

Ils exécutent du code non fiable, manipulent des identifiants sensibles et produisent des artefacts auxquels les systèmes en aval font confiance.

Sécuriser les runners nécessite des décisions architecturales : éphémérité, isolation, moindre privilège et séparation explicite des niveaux de confiance.

Les organisations qui traitent les runners comme des environnements d’exécution jetables et non fiables — plutôt que comme une infrastructure de confiance — sont bien mieux positionnées pour se défendre contre les attaques modernes visant les pipelines CI/CD et la chaîne d’approvisionnement.


À propos de l’auteur

Cet article est rédigé par un architecte senior DevSecOps et sécurité disposant de plus de 15 ans d’expérience en ingénierie logicielle et en sécurité applicative. Le contenu reflète une approche pragmatique, orientée ingénierie et ancrée dans les contraintes du monde réel.