Retour au cours

infra / github-actions

Self-hosted runners

Leçon 111 exercice

Explication

Ce que vous allez apprendre

  • Comprendre la limite des runners hébergés par GitHub (matériel générique, pas d'accès réseau interne)
  • Configurer et cibler un self-hosted runner avec des labels
  • Comprendre le risque de sécurité central des self-hosted runners sur un dépôt public
  • Protéger un self-hosted runner en exigeant une approbation pour les contributeurs externes
  • Comprendre l'intérêt des runners éphémères pour limiter la persistance d'un job compromis

Dans quel contexte ?

Une équipe doit exécuter ses tests d'intégration contre une base de données interne, accessible uniquement depuis le réseau de l'entreprise, jamais exposée sur Internet. Les runners hébergés par GitHub, sur des machines génériques quelque part dans le cloud, ne peuvent tout simplement pas atteindre cette base. Un self-hosted runner, installé sur une machine à l'intérieur du réseau de l'entreprise, résout ce problème — mais introduit un risque de sécurité qu'il faut comprendre avant de l'activer, en particulier sur un dépôt public.

Le problème : les machines de GitHub ont des limites

D'abord, par défaut, chaque job GitHub Actions s'exécute sur une machine fournie et gérée par GitHub, un "runner hébergé", avec du matériel générique et sans accès à ton réseau interne.

Des besoins qui ne rentrent pas dans ce cadre

Certains besoins ne rentrent pas dans ce cadre : accéder à une base de données interne non exposée sur Internet, utiliser un GPU spécifique, ou respecter une licence logicielle liée à une machine précise.

La solution : une machine que tu contrôles

Un "self-hosted runner" répond à ce besoin : c'est une machine que tu administres toi-même, sur laquelle l'agent GitHub Actions vient simplement écouter et exécuter les jobs qu'on lui envoie.

Type de runnerContrôleCas d'usage typique
Runner hébergé (GitHub)Aucun accès réseau interne, matériel génériqueLa majorité des projets
Self-hosted runnerAccès réseau interne, matériel spécifique (GPU...)Base de données interne, licence liée à une machine
Self-hosted éphémèreDétruit et recréé après chaque jobDépôt public, isolation maximale

Cibler précisément le bon runner

Comme plusieurs runners auto-hébergés peuvent coexister, différents matériels, différentes équipes, des étiquettes, labels, permettent à un job de spécifier exactement quel type de machine il requiert.

Un niveau d'organisation supplémentaire

Les "groupes de runners" ajoutent un niveau supplémentaire d'organisation, utile pour isoler l'accès entre plusieurs équipes au sein d'une même organisation.

Le risque de sécurité central à comprendre

Un self-hosted runner exécute du code arbitraire fourni par le workflow, y compris, potentiellement, du code venant d'une pull request externe.

Piège fréquent

Sur un dépôt public, n'importe qui peut proposer une pull request. Si un workflow déclenche un job sur ton propre self-hosted runner sans contrôle, un attaquant obtient littéralement une exécution de code sur ta machine. Exiger une approbation avant l'exécution des workflows venant de contributeurs externes est indispensable dès qu'un self-hosted runner tourne sur un dépôt public.

Ce que ça signifie sur un dépôt public

Sur un dépôt public, n'importe qui peut proposer une pull request : si celle-ci déclenche un job sur ta propre infrastructure sans contrôle, un attaquant obtient littéralement une exécution de code sur ta machine.

La protection indispensable dans ce cas

C'est pourquoi exiger une approbation avant l'exécution des workflows venant de contributeurs externes est indispensable dès qu'un self-hosted runner est utilisé sur un dépôt public.

Les runners éphémères : limiter la persistance des dégâts

Un runner "éphémère" est détruit après chaque job et recréé à neuf pour le suivant, souvent automatiquement via un orchestrateur comme Kubernetes.

Bonne pratique

Sur un self-hosted runner exposé à du code externe (dépôt public, contributions ouvertes), privilégie systématiquement des runners éphémères plutôt que des machines persistantes. Même en cas de compromission d'un job, la machine repart de zéro pour le job suivant, sans trace exploitable.

Ce que ça évite

Cela évite qu'un job compromis, ou simplement mal isolé, laisse des traces exploitables pour le job suivant exécuté sur la même machine.

Maintenant que tu sais où exécuter tes jobs, la leçon suivante assemble tout ce qui a été vu dans ce cours pour construire un pipeline de déploiement continu complet.

Commandes & code

Self-hosted runners

Un runner auto-hébergé exécute les jobs sur une machine que VOUS contrôlez (accès réseau interne, GPU, licence spécifique).

bash
# Enregistrer un runner (Settings > Actions > Runners > New self-hosted runner)
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64.tar.gz -L \
  https://github.com/actions/runner/releases/download/v2.319.1/actions-runner-linux-x64-2.319.1.tar.gz
tar xzf actions-runner-linux-x64.tar.gz

./config.sh --url https://github.com/org/repo --token <TOKEN_GENERE_PAR_GITHUB>
./run.sh                       # exécution en avant-plan, pour tester

# En production : l'installer comme service système
sudo ./svc.sh install
sudo ./svc.sh start
yaml
jobs:
  build-on-prem:
    runs-on: [self-hosted, linux, x64, gpu]    # labels custom pour cibler un runner précis
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/train-model.sh          # ex: nécessite un GPU local
yaml
# Groupes de runners (organisation) pour isoler des équipes/environnements
jobs:
  deploy-internal:
    runs-on:
      group: production-runners
      labels: [self-hosted, linux]
    steps:
      - run: ./scripts/deploy-internal.sh
bash
# Ephemeral runners : détruits après CHAQUE job, recréés à la demande (souvent via Kubernetes)
# Évite qu'un job compromis laisse des traces pour le job suivant sur la même machine
./config.sh --url https://github.com/org/repo --token <TOKEN> --ephemeral
bash
# Risque de sécurité majeur : un self-hosted runner sur un dépôt PUBLIC est dangereux.
# N'importe qui peut ouvrir une PR et exécuter du code arbitraire sur votre infrastructure.
# -> "Require approval for all outside collaborators" est indispensable sur un repo public.

Résumé

  • Un self-hosted runner tourne sur une infra propre : accès réseau interne, GPU, matériel spécifique.
  • runs-on: [self-hosted, <labels>] cible précisément un groupe de runners.
  • Les runners éphémères limitent les risques de persistance entre deux jobs.
  • Sur un dépôt public, exiger une approbation avant exécution des workflows de contributeurs externes.

Exercices pratiques

1 disponible
1

Mission : un runner auto-hébergé exposé sur un dépôt public

Objectif : Identifier une faille de sécurité liée à un self-hosted runner mal configuré sur un dépôt public, et la corriger.

Contexte

Un projet open source a ajouté un self-hosted runner équipé d'un GPU pour exécuter ses tests de modèles de machine learning, ciblé via runs-on: [self-hosted, gpu]. Le dépôt est public : n'importe qui peut y ouvrir une pull request. Rien n'a été configuré pour restreindre l'exécution des workflows provenant de contributeurs externes, et cette même machine sert aussi à d'autres jobs internes de l'équipe.

Résoudre l’exercice →