Sécuriser les runners CI/CD n’est pas un bricolage de sécurité ponctuel, mais une tâche opérationnelle durable : les runners extraient le code source, construisent des artefacts et ont souvent accès aux credentials, aux caches et au réseau interne. Pour les administrateurs et opérateurs, il est crucial de réduire de manière mesurable la surface d’attaque et d’avoir des chemins clairs de contrôle et de repli. Ce guide fournit des mesures concrètes, des étapes de vérification et du dépannage pour l’isolation des identifiants, un nettoyage robuste des espaces de travail et la protection de la chaîne de build.
Pourquoi les runners sont un vecteur d’attaque critique
Les runners sont des environnements d’exécution pour les jobs CI/CD (builds, tests, packaging). Un runner compromis peut :
- exfiltrer des secrets (tokens, clés SSH, credentials cloud).
- modifier des artefacts ou les signer de manière manipulée.
- effectuer du cache-poisoning et ainsi influencer les builds suivants.
- permettre du pivoting vers le réseau interne.
Distinction importante : trusted-Builds (p. ex. branches protégées ou Releases) versus untrusted-Builds (forks, PR externes, contributions publiques). Pour les builds non fiables, l’hypothèse opérationnelle doit être : le job est potentiellement malveillant.
Principes de base : droits minimaux, isolation, traçabilité
Renforcez l’exploitation selon trois objectifs mesurables :
- Objectif d’isolation : aucun job ne doit voir l’état d’un autre job.
- Objectif Credential : les jobs reçoivent uniquement les credentials strictement nécessaires, de préférence éphémères.
- Objectif d’intégrité : l’origine et l’inaltérabilité des dépendances et des artefacts doivent être traçables.
Ces objectifs peuvent être opérationnalisés, testés et audités.
Isolation des identifiants : mise en œuvre, raisons et pièges typiques
L’isolation des identifiants signifie : pas de tokens statiques polyvalents. Séparez les identités selon la phase de la pipeline (build, package, release, deploy) et le contexte. Utilisez des tokens éphémères (TTL en minutes/heures) via OIDC, STS (Security Token Service) ou les leases de HashiCorp Vault. Les credentials éphémères limitent le blast radius en cas de compromission et simplifient la révocation.
Options techniques et usages
OIDC (OpenID Connect) est un protocole pour l’émission de tokens éphémères ; il connecte les systèmes CI aux Cloud-IAM ou à Vault sans secrets persistants. KMS/HSM (Key Management Service / Hardware Security Module) stocke les clés privées hors des runners. Vault propose des secrets dynamiques (p. ex. des credentials de base de données sur la base de leases). Chaque option comporte des exigences opérationnelles : OIDC nécessite des claims de token fiables, Vault exige une haute disponibilité et des politiques d’accès.
Beispiel: Vault-Policy für Package-Push
# Vault policy (HCL) - erlaubt Token zum Schreiben in ein internes Artefakt-Repo
path "secret/data/ci/artifacts/*" {
capabilities = ["create", "update", "read"]
}
Pourquoi cela fonctionne : Vault délivre des tokens limités dans le temps, et la policy restreint les chemins. Quand cela échoue : si les runners persistent le token Vault (p. ex. dans un cache) ou si les policies sont définies trop largement.
Signature limitée par policy via un service de signature
Les clés privées de signature ne doivent pas résider sur des runners standards. Un service de signature (service interne qui signe via KMS/HSM) reçoit les hash des artefacts, vérifie les policies (p. ex. que le build provient d’une branche protégée) puis signe. L’opération de signature nécessite des logs d’audit séparés et une authentification stricte.
Sécuriser les runners CI/CD : isolation au niveau de l’infrastructure
Choisissez l’isolation selon le risque et la rentabilité :
- Host-Runner : Rapide, mais uniquement pour des jobs entièrement dignes de confiance.
- Container-Runner : Bonne performance, mais uniquement avec rootless et des politiques de montage strictes.
- Ephemeral VM/Instance-Runner : Isolation maximale ; par job une VM ou un snapshot frais. Coûts plus élevés, sécurité maximale.
Les Ephemeral-Runner sont particulièrement recommandés pour les builds non fiables : après achèvement, l’instance est détruite, empêchant toute persistance.
Exemple : Kubernetes-Runner en tant que job éphémère
apiVersion: batch/v1
kind: Job
metadata:
name: runner-job-{{ .RunID }}
spec:
template:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
containers:
- name: builder
image: registry.internal/runner-image:stable
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
RESTartPolicy: Never
backoffLimit: 0
Pourquoi cela aide : Kubernetes permet d’utiliser Namespaces, NetworkPolicies et les contextes Pod-Security pour RESTreindre. Attention : des configurations RBAC ou de volumes incorrectes peuvent compromettre l’isolation.
Nettoyage sécurisé des workspaces : robuste et résistant aux manipulations
Un nettoyage défectueux permet la persistance. Les problèmes proviennent de handles ouverts, de systèmes de fichiers montés, d’astuces de symlinks et d’ACLs RESTrictives. Un nettoyage robuste met en œuvre plusieurs couches de protection : workspaces dédiés, normalisation des propriétaires, –one-file-system lors de la suppression et des tests avec journalisation d’audit.
Linux : Nettoyage étendu incluant la vérification des handles
#!/usr/bin/env bash
set -euo pipefail
JOB_DIR="$1"
RUNNER_UID=1001
RUNNER_GID=1001
# 1) Prozesse beenden, die in JOB_DIR arbeiten
fuser -k -TERM -m "$JOB_DIR" || true
sleep 1
fuser -k -KILL -m "$JOB_DIR" || true
# 2) Ownership und Rechte normalisieren
chown -R "${RUNNER_UID}:${RUNNER_GID}" "$JOB_DIR" 2>/dev/null || true
chmod -R u+rwX,go-rwx "$JOB_DIR" 2>/dev/null || true
# 3) Prüfen auf Mountpoints im Jobdir
mountpoints=$(findmnt -n -o TARGET --target "$JOB_DIR" || true)
if [ -n "$mountpoints" ]; then
echo "Found mounts: $mountpoints" >&2
# Option: detach mounts safely or warn and abort
fi
# 4) Löschen sicher durchführen
rm -rf --one-file-system "$JOB_DIR"
Pourquoi fuser est nécessaire : des handles de fichiers ouverts empêchent la suppression ; les processus doivent être correctement terminés. Le script peut échouer si un job a lancé des processus système que le script ne peut pas terminer — d’où l’importance du logging et des niveaux d’avertissement.
Windows : Handles, plan de redémarrage et interaction avec l’antivirus
Sur Windows, les verrous causés par des services et des AV sont courants. Complétez le nettoyage par des vérifications des handles (Sysinternals Handle/Process Explorer), des tentatives répétées et une procédure de redémarrage planifiée si la suppression est impossible. De simples tentatives répétées ne suffisent pas toujours face à des verrous persistants — documentez une procédure de rollback.
Sécurité de la chaîne de build : sources de paquets, caches et signature
Protégez la chaîne de build par l’isolation des sources de paquets, des proxys avec allow-lists, des caches contrôlés et des politiques d’artefacts immuables.
Miroirs internes et RESTriction de l’egress
Outre des allow‑lists pour les endpoints de paquets, les runners ne devraient avoir qu’un egress défini : VCS, miroir, dépôt d’artefacts, KMS/service de signature. Les Egress-ACLs réduisent les possibilités d’exfiltration / d’établissement d’une infrastructure de Command-and-Control. Testez d’abord les modifications en Monitor-Mode (seulement logging) avant de bloquer.
Renforcement du dépôt d’artefacts
Appliquez des write-policies (non-overwrite), des retention-policies et les flags require-signed-artifact si votre repo le supporte. Les logs d’audit doivent indiquer qui a publié quel artefact et quand. Règle d’exemple : „Les releases ne peuvent être publiées qu’après signature par le service de signature“.
Stratégies de cache contre l’empoisonnement
Séparez les caches par zones de confiance et par projet. Évitez les shared writable caches pour les jobs non fiables. Utilisez l’invalidation par TTL et des hash de cache consignés pour détecter l’empoisonnement.
Renforcement du réseau et de l’hôte : mesures concrètes
Traitez les Runner comme des composants d’infrastructure critiques :
- segments réseau dédiés ou VLANs
- ACLs egress définies
- pare-feu hôte et processus de gestion des correctifs
- monitoring et logs centralisés
Exemple : règle iptables simple pour l’egress (VM-Runner)
# Erlaube nur DNS, HTTP(S) zu mirror.example und signing.example
iptables -A OUTPUT -m owner --uid-owner runner -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner runner -p tcp -d mirror.example --dport 443 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner runner -p tcp -d signing.example --dport 443 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner runner -j DROP
Warum das hilft: Selbst wenn ein Job versucht, bösartige Kommunikation aufzubauen, bleibt Egress begrenzt. Achtung: DNS-over-HTTPS und andere Umgehungswege können dies unterlaufen—testen und monitoren.
Tests, audit und validation
Validez les mesures par des tests et des audits automatisés :
- Jobs d’audit réguliers qui tentent d’exécuter depuis un Runner des actions non autorisées (uniquement dans un réseau de test isolé !).
- Audits post-job : vérifier la présence de répertoires de workspace, les descripteurs ouverts, les processus actifs.
- Analyse des logs : détection d’exfiltration de tokens ou de connexions egress inhabituelles.
Exemple de script de test : validation après nettoyage
#!/usr/bin/env bash
# Prüft, ob ein Job-Verzeichnis nach Cleanup noch existiert
JOB_DIR="$1"
if [ -e "$JOB_DIR" ]; then
echo "CLEANUP FAILED: $JOB_DIR still exists" >&2
ls -la "$JOB_DIR" >&2
exit 2
fi
# Prüfe auf aktive Prozesse des Runner-User
if pgrep -u runner >/dev/null; then
echo "ACTIVE PROCESSES FOUND" >&2
ps -u runner -o pid,cmd
exit 3
fi
exit 0
Pièges typiques et dépannage
1) Secrets accidentellement dans le build-log
Cause : prints de debug ou masquage manquant. Mesures : activer le masquage des logs CI, ne pas afficher les variables sensibles en clair. Vérifiez automatiquement les logs à la recherche de motifs (API-Keys, Bearer-Tokens) avec un job scanner.
2) Conteneurs privilégiés abusés
Cause : conteneurs privilégiés ou passage du socket Docker. Mesure : builds rootless, pas de montages du socket hôte, utilisation de Buildkit/remote daemon. Test : le job tente de lancer de nouveaux conteneurs sur l’hôte (uniquement en environnement de test !).
3) Clés de signature sur les Runner
Cause : praticité plutôt que sécurité — les équipes stockent les clés localement. Mesure : centraliser les services de signature, stocker les clés uniquement dans un HSM/KMS. En cas de compromission : rotation immédiate et invalidation de toutes les clés potentiellement compromises.
Stratégie de rollback et d’urgence
Implémentez les changements par étapes :
- Mode monitoring : uniquement journalisation, pas de blocage.
- Fermeture progressive des zones egress/politiques.
- Exploitation parallèle des anciens et nouveaux pools de Runner ; bascule via feature-flag/route.
- Break-glass tokens pour les urgences, à durée courte et traçables en audit.
Important : documentez les étapes de retour arrière et testez‑les régulièrement dans un essai isolé.
Checklist pratique : mise en œuvre en 90–180 minutes
- Inventorier les tokens actifs et vérifier les droits pour chaque phase du pipeline.
- Migrer les jobs non fiables vers des pools de runners séparés ou des Ephemeral-VMs.
- Étendre les scripts de nettoyage : process-kill, chown, chmod, –one-file-system, post‑validation.
- Auditer le processus de signature et planifier la gestion des clés dans un HSM/KMS.
- Créer des Egress-ACLs en mode monitor et observer le trafic.
- Job d’audit : tenter d’exécuter depuis le runner des actions non autorisées (isolé).
Conclusion
Sécuriser les runners CI/CD implique de concilier praticité et sécurité mesurable. Priorisez la séparation des identifiants selon la phase du pipeline (avec des tokens éphémères), un nettoyage garanti des workspaces (ou des Ephemeral-Runners) et la signature via un service de signature ou un HSM/KMS. Complétez par des RESTrictions d’egress, du monitoring et des tests d’audit réguliers. Avec une introduction progressive, des phases en mode monitor et des procédures de repli testées, la sécurité RESTe gérable et opérationnellement fiable.
FAQ
Quelle est la plus grande erreur lors de la sécurisation des runners CI/CD ?
Un conteneur suffit‑il comme isolation pour des builds non fiables ?
Comment m’assurer que le nettoyage du workspace fonctionne réellement ?
Pourquoi la clé privée de signature ne doit‑elle pas résider sur le runner ?
Comment gérer la dégradation des performances due à une isolation renforcée ?
Quelles vérifications un job d’audit pour runners devrait‑il inclure ?
Sécuriser les runners CI/CD : exploitation, monitoring et intégration
Les mesures techniques ne valent que par leur exploitation. Prévoyez le monitoring, les métriques et les intégrations dès l’introduction des durcissements des runners, afin que la sécurité reste reproductible et mesurable.
Métriques importantes et alertes :
- Taux d’échec de nettoyage : proportion de jobs pour lesquels la validation post‑job a échoué. Définissez un seuil et déclenchez une alerte avant que des déficiences d“nettoyage ne deviennent persistantes.
- Vault‑Lease‑Errors et OIDC‑Token‑Failures : signalent des problèmes liés aux identifiants temporaires ou à des claims erronés.
- Connexions egress inhabituelles par pool de runners : des augmentations soudaines peuvent indiquer une exfiltration ou des tentatives de contournement.
- Demandes de signature par heure et erreurs de signature : des écarts peuvent révéler des pipelines compromis ou des erreurs de politique.
Conseils d’intégration :
- IAM/IdP : Connectez le CI en tant que client OAuth/OIDC au fournisseur d’identité existant (p. ex. AD, Okta). Ainsi l’audit et le cycle de vie des utilisateurs restent gérés de façon centralisée.
- Secrets‑Backends : Utilisez Vault/KMS de manière dynamique ; automatisez le renouvellement des leases et la rotation. Documentez les rotations d’urgence et testez le chemin de révocation des clés.
- Dépôt d’artefacts : Complétez les politiques de signature par des attestations (métadonnées de build, SBOM). Cela rend la provenance vérifiable et facilite les analyses d’incident.
Runbook et procédures de repli :
- Rédigez un runbook succinct : étapes pour isoler un pool de runners, rotation des clés, interrupteur de désactivation pour le service de signature et retour en arrière vers des runners en warm‑standby.
- Effectuez régulièrement des tests chaos dans une zone de test (échec de cleanup, blocage des sorties egress) et évaluez les processus opérationnels au regard de SLA concrets.
Conclusion : L’exploitation et l’intégration ne sont pas des après‑pensées. De bonnes métriques, la rotation automatisée ainsi que des runbooks coordonnés rendent la sécurité CI/CD robuste et maniable au quotidien.
Pour ce sujet, la sécurité de la chaîne d’approvisionnement et la protection de la chaîne de build sont également importantes. L’article situe ces aspects de manière claire et montre ce qui compte au quotidien.