L'isolation des runners permet de contrôler quels workflows peuvent s'exécuter sur quelles machines. C'est essentiel pour la sécurité et la gestion des ressources dans les grandes organisations.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre pourquoi isoler les runners (sécurité, performance, conformité)
- Router les jobs avec les labels et les groupes de runners
- Appliquer les patterns d'isolation : par environnement, confiance, équipe
- Contrôler l'accès au niveau dépôt ou organisation
- Segmenter le réseau pour cloisonner les runners
Pourquoi isoler les runners ?
Section intitulée « Pourquoi isoler les runners ? »Sécurité
Section intitulée « Sécurité »- Empêcher les PRs non fiables d'accéder au réseau de production
- Limiter l'impact d'un workflow compromis
- Respecter le principe de moindre privilège
Performance
Section intitulée « Performance »- Réserver des runners puissants aux builds critiques
- Éviter la contention entre équipes
- Garantir des SLAs différents par projet
Conformité
Section intitulée « Conformité »- Séparer les données sensibles par environnement
- Traçabilité des exécutions par équipe
- Respect des zones géographiques
Labels et groupes de runners
Section intitulée « Labels et groupes de runners »Labels personnalisés
Section intitulée « Labels personnalisés »Les labels identifient les capacités d'un runner :
# À l'enregistrement./config.sh --url https://github.com/ORG/REPO \ --token TOKEN \ --labels linux,x64,docker,gpu,productionUtilisation dans un workflow :
jobs: build: runs-on: [self-hosted, linux, docker]
deploy-prod: runs-on: [self-hosted, production]
ml-training: runs-on: [self-hosted, gpu]Groupes de runners (organisation)
Section intitulée « Groupes de runners (organisation) »Au niveau organisation, les groupes permettent de limiter l'accès :
- Allez dans Settings > Actions > Runner groups
- Créez un groupe (ex:
production-runners) - Assignez des runners au groupe
- Définissez quels repos peuvent l'utiliser
# Seuls les repos autorisés peuvent utiliser ce runnerjobs: deploy: runs-on: group: production-runners labels: [linux, x64]Patterns d'isolation
Section intitulée « Patterns d'isolation »Trois découpages couvrent la plupart des besoins. Ils se combinent : un runner
peut être à la fois production, team-platform et gpu.
Par environnement
Section intitulée « Par environnement »┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐│ Dev Runners │ │ Staging Runners │ │ Prod Runners ││ │ │ │ │ ││ Labels: │ │ Labels: │ │ Labels: ││ - dev │ │ - staging │ │ - production ││ - self-hosted │ │ - self-hosted │ │ - self-hosted ││ │ │ │ │ ││ Accès: tous │ │ Accès: équipe QA │ │ Accès: ops │└─────────────────┘ └──────────────────┘ └─────────────────┘jobs: test: runs-on: [self-hosted, dev]
staging: runs-on: [self-hosted, staging] environment: staging # Protection supplémentaire
production: runs-on: [self-hosted, production] environment: productionPar niveau de confiance
Section intitulée « Par niveau de confiance »┌─────────────────────┐ ┌─────────────────────┐│ Trusted Runners │ │ Untrusted Runners ││ │ │ ││ Pour: │ │ Pour: ││ - Pushes sur main │ │ - PRs externes ││ - Tags de release │ │ - Forks ││ │ │ ││ Accès: │ │ Accès: ││ - Réseau interne │ │ - Internet seul ││ - Secrets sensibles │ │ - Secrets limités │└─────────────────────┘ └─────────────────────┘name: CI
on: push: branches: [main] pull_request:
jobs: test: # Code de confiance (push) → runner trusted ; PR → runner untrusted runs-on: - self-hosted - ${{ github.event_name == 'push' && 'trusted' || 'untrusted' }}Par équipe
Section intitulée « Par équipe »jobs: frontend-build: runs-on: [self-hosted, team-frontend]
backend-build: runs-on: [self-hosted, team-backend]
ml-training: runs-on: [self-hosted, team-data, gpu]Contrôle d'accès aux runners
Section intitulée « Contrôle d'accès aux runners »Le niveau d'enregistrement d'un runner détermine qui peut l'utiliser. Plus le périmètre est large, plus le contrôle d'accès doit être strict.
Repository level
Section intitulée « Repository level »Un runner enregistré au niveau repository :
- N'est accessible que par ce repository
- Isolation maximale
./config.sh --url https://github.com/OWNER/REPO ...Organization level
Section intitulée « Organization level »Un runner enregistré au niveau organisation :
- Peut être partagé entre repos
- Contrôlé par les groupes
./config.sh --url https://github.com/ORG ...Workflow permissions
Section intitulée « Workflow permissions »Utilisez les environments pour ajouter une couche de contrôle :
jobs: deploy: runs-on: [self-hosted, production] environment: name: production # Nécessite approbation manuelleRéseau et firewall
Section intitulée « Réseau et firewall »Segmentation réseau
Section intitulée « Segmentation réseau »┌─────────────────────────────────────────────────────────────┐│ VPC / Réseau │├─────────────────┬─────────────────┬─────────────────────────┤│ Subnet Dev │ Subnet Staging │ Subnet Production ││ │ │ ││ ┌─────────────┐ │ ┌─────────────┐ │ ┌─────────────────────┐ ││ │ Dev Runner │ │ │Staging Runner│ │ │ Prod Runner │ ││ │ │ │ │ │ │ │ │ ││ │ Accès: │ │ │ Accès: │ │ │ Accès: │ ││ │ - DB dev │ │ │ - DB staging│ │ │ - DB prod │ ││ │ - API dev │ │ │ - API staging│ │ │ - K8s prod │ ││ └─────────────┘ │ └─────────────┘ │ └─────────────────────┘ │└─────────────────┴─────────────────┴─────────────────────────┘Règles firewall par label
Section intitulée « Règles firewall par label »# Runner dev : accès limitéiptables -A OUTPUT -d 10.0.1.0/24 -j ACCEPT # Subnet deviptables -A OUTPUT -d 0.0.0.0/0 -p tcp --dport 443 -j ACCEPT # GitHubiptables -A OUTPUT -j DROP
# Runner production : accès plus large mais contrôléiptables -A OUTPUT -d 10.0.0.0/16 -j ACCEPT # Tout le VPCiptables -A OUTPUT -d 0.0.0.0/0 -p tcp --dport 443 -j ACCEPTiptables -A OUTPUT -j DROPExemple complet d'architecture
Section intitulée « Exemple complet d'architecture »Ce workflow met bout à bout les patterns du guide : tests sur runners mutualisés, build sur runners d'équipe, déploiements sur runners par environnement avec approbation pour la production.
name: CI/CD Pipeline
on: push: branches: [main, develop] pull_request:
# Aucun droit par défaut : chaque job demande le minimumpermissions: {}
jobs: # Tests sur runners mutualisés test: runs-on: [self-hosted, linux, shared] permissions: contents: read steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - run: npm test
# Build sur runners de l'équipe build: needs: test runs-on: [self-hosted, linux, team-platform] permissions: contents: read steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - run: docker build -t app .
# Déploiement staging (réseau staging) deploy-staging: if: github.ref == 'refs/heads/develop' needs: build runs-on: [self-hosted, staging-network] environment: staging steps: - run: kubectl --context staging apply -f k8s/
# Déploiement production (réseau prod, approbation requise) deploy-production: if: github.ref == 'refs/heads/main' needs: build runs-on: group: production-runners labels: [linux, x64] environment: name: production url: https://app.company.com steps: - run: kubectl --context production apply -f k8s/Bonnes pratiques
Section intitulée « Bonnes pratiques »1. Nommer clairement les labels
Section intitulée « 1. Nommer clairement les labels »# ✅ Labels explicites--labels linux,x64,docker,production,team-platform
# ❌ Labels vagues--labels runner1,fast2. Documenter l'architecture
Section intitulée « 2. Documenter l'architecture »Maintenez un document décrivant :
- Quels runners existent
- Leurs labels et capacités
- Quels repos/équipes peuvent les utiliser
- Les règles réseau
3. Auditer régulièrement
Section intitulée « 3. Auditer régulièrement »# Lister les runners et leurs labelsgh api /orgs/ORG/actions/runners --jq '.runners[] | {name, labels: [.labels[].name]}'4. Automatiser le provisioning
Section intitulée « 4. Automatiser le provisioning »Utilisez Infrastructure as Code pour les runners :
- Terraform pour les VMs
- Helm/Kubernetes pour ARC
- Ansible pour la configuration
À retenir
Section intitulée « À retenir »- L'isolation contrôle quel workflow tourne sur quelle machine — un levier de sécurité et de performance.
- Les labels routent les jobs ; les groupes de runners restreignent quels dépôts peuvent les utiliser.
- Séparez au minimum les runners trusted (push, releases) des runners untrusted (PR, forks).
- Un runner enregistré au niveau dépôt offre l'isolation maximale ; au niveau organisation, il se mutualise via les groupes.
- Complétez l'isolation logique par une segmentation réseau : chaque environnement dans son sous-réseau.