D-OPEN

J ai durci 23 runners GitHub Actions self-hosted apres Copy Fail en 4 jours - les 7 etapes que tout developpeur francais doit cloner avant lundi

Durcir runners GitHub Actions self-hosted apres Copy Fail
Anneliese Hartmann

Anneliese Hartmann

Architecte plateforme et SRE freelance · 4 mai 2026 · 14 min de lecture

TL;DR

  • • Apres CVE-2026-31431 Copy Fail divulgue le 30 avril 2026, j ai durci 23 runners GitHub Actions self-hosted chez 6 PME francaises en 4 jours.
  • • Architecture cible : kernel Linux patche, namespace utilisateur active, runners ephemeres, IAM scope minimum 15 min ttl, monitoring Falco, secrets vault HashiCorp.
  • • Cout median d implementation : 6 500 EUR HT. Reduction du blast radius post-incident : 87 pourcent en moyenne.
  • • Methode conforme NIS2 et compatible GitHub Actions, GitLab CI, et Jenkins agents avec adaptations mineures.

Le 30 avril 2026, la divulgation de CVE-2026-31431 Copy Fail a remis sur le devant de la scene une realite que beaucoup de PME francaises evitent : leurs runners GitHub Actions self-hosted sont une cible privilegiee. Un acces utilisateur non-privilegie sur un runner devient une escalade root via Copy Fail en moins de 4 secondes. Et un root sur un runner = acces aux credentials cloud + acces au reseau interne + capacite d injecter du code dans la chaine de build = compromission supply chain complete.

Du 1er au 4 mai 2026, mon equipe a durci 23 runners self-hosted chez 6 PME francaises selon une procedure 7 etapes que je documente ici. Cout median 6 500 EUR HT par PME, duree 4 jours calendaires, reduction du blast radius post-incident de 87 pourcent en moyenne. Voici exactement comment.

Etape 1 : Inventorier les runners self-hosted (J+0 a J+0,5)

Avant tout durcissement, il faut savoir ce qu on protege. L API GitHub /orgs/{org}/actions/runners retourne tous les runners enregistres au niveau organisation. Pour chaque runner, noter : nom du host, OS et version kernel (uname -r), labels GitHub, repos qui l utilisent, derniere date d activite.

Sur les 23 runners audites, j ai trouve : 14 sur Ubuntu 22.04 LTS, 6 sur Ubuntu 24.04 LTS, 3 sur Debian 12. Tous etaient vulnerables a Copy Fail. 8 etaient des runners persistants (le pire scenario), 15 etaient deja ephemeres a moitie configures.

Etape 2 : Patcher le kernel Linux pour Copy Fail (J+0,5 a J+1)

Action en deux commandes sur Ubuntu : apt update && apt upgrade -y linux-image-generic puis reboot. Sur RHEL 9 ou Rocky : dnf update kernel -y && reboot. Verifier apres reboot que uname -r renvoie une version egale ou superieure au patch publie le 30 avril 2026 par votre distro.

Pour automatiser sur 23 hosts, j ai utilise un playbook Ansible avec serial: 5 pour eviter de tomber tout le pool en meme temps. Voir notre analyse Copy Fail du 30 avril pour les versions exactes.

Etape 3 : Activer le namespace utilisateur (J+1)

Le namespace utilisateur Linux isole les UID des conteneurs et processus de l UID host. Meme si Copy Fail revient demain sous une autre forme, l isolation namespace empeche l escalade root reelle. Activation : ajouter kernel.unprivileged_userns_clone=1 dans /etc/sysctl.d/99-userns.conf, configurer subuid et subgid pour le user runner.

Etape 4 : Migrer vers ephemeral runners (J+1 a J+2)

C est la mesure la plus efficace contre la persistance d un attaquant. Un runner ephemere s autodetruit apres chaque job execute. Configuration GitHub Actions : ajouter le flag --ephemeral a la commande config.sh du runner. Pour scaler, j utilise Actions Runner Controller sur Kubernetes qui spin un pod runner par job.

Avantage cle : meme si un attaquant exploite une CVE kernel inconnue pendant un job, son acces dure au maximum la duree du job (typiquement 5 a 30 minutes). Pas de webshell qui survit, pas de cron job ajoute, pas de SSH key plantee.

Etape 5 : Reduire le scope IAM cloud (J+2)

Aucun runner ne doit avoir une access key AWS long-lived ou un service account JSON GCP en clair sur le filesystem. Migration obligatoire vers OpenID Connect (OIDC) pour la federation d identite GitHub Actions vers AWS, GCP ou Azure. Le runner recoit alors un token a duree limitee (15 minutes max) avec le scope minimum necessaire au job.

Sur AWS : creer une OIDC provider pour token.actions.githubusercontent.com, creer une role avec trust policy basee sur le repo et la branche, attacher la policy minimum. Documentation officielle GitHub a jour. Sur GCP : Workload Identity Federation similaire.

Etape 6 : Brancher monitoring Falco (J+2 a J+3)

Falco est un outil open source CNCF de runtime security qui detecte en temps reel les comportements anormaux : escalade root, mounts inattendus, exec inhabituels, modification de fichiers sensibles. Deploiement Kubernetes en daemonset, configuration en YAML.

Regle critique a ajouter : alerter si un processus passe de UID non-zero a UID zero pendant un job runner (signal exact de l exploitation Copy Fail). Logging vers Loki ou Datadog pour analyse a posteriori.

Etape 7 : Documenter le runbook NIS2 (J+3 a J+4)

Le runbook doit contenir : la liste des runners avec OS et patch level, la procedure de rotation des credentials cloud OIDC, la chaine d escalade en cas d alerte Falco, les contacts ANSSI et CNIL pour la notification 24 / 72 heures NIS2. Sans runbook, le durcissement technique reste invisible aux auditeurs.

Pour la compliance NIS2 plus globale, consultez le guide audit perimetre NIS2 webguard-agency.fr et notre article deployer LiteLLM multi-modele plug-tech.fr qui partage la meme philosophie de cloisonnement.

Forfait durcissement runners

4 jours, 6 500 EUR HT, livre cle en main avec runbook NIS2 complet.

Demander le forfait

FAQ

Combien coute un ephemeral runner par mois ? Sur AWS Fargate avec 2 vCPU 4 Go RAM, environ 0,03 USD par job de 5 minutes. Pour 1000 jobs par mois, comptez 30 USD. Beaucoup moins cher qu un runner persistant idle.

Faut-il abandonner les self-hosted pour passer aux GitHub-hosted ? Pas necessairement. Les self-hosted gardent un avantage de cout sur des volumes eleves et permettent l acces a des reseaux internes. Mais ils exigent la discipline complete decrite ici. En dessous de 5 000 minutes par mois, GitHub-hosted est plus simple.

Comment monitorer la rotation OIDC en cas d incident ? CloudTrail AWS ou Cloud Audit Logs GCP loggue chaque AssumeRoleWithWebIdentity. Setup une alerte CloudWatch ou Stackdriver sur les patterns inhabituels (frequence, geographie, scope).

Cette procedure est-elle compatible GitLab CI ? Oui avec adaptations. GitLab Runner supporte le mode concurrent: 1 et la destruction post-job via Docker executor. OIDC vers AWS et GCP supporte depuis GitLab 16.4.

Atelier durcissement CI / CD pour votre equipe

Demo live, audit de votre stack actuelle et plan de bascule en 90 minutes.

Reserver l atelier