Tout ce que les guides précédents durcissent, permissions minimales, épinglage par SHA, provenance vérifiée, tient dans des fichiers YAML. Or ces fichiers sont du code comme les autres : qui peut les modifier peut les défaire. Ce module traite la couche que le YAML ne peut pas couvrir, celle qui décide qui a le droit de changer quoi, et quel code tiers a le droit de s'exécuter.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Situer les trois couches de contrôle : dépôt, organisation, traçabilité
- Comprendre pourquoi un workflow durci ne protège pas d'un workflow ajouté
- Ordonner le déploiement de ces contrôles, du moins coûteux au plus exigeant
- Repérer les contrôles qui dépendent de votre plan GitHub
Le durcissement du YAML a une limite structurelle
Section intitulée « Le durcissement du YAML a une limite structurelle »Prenez un dépôt exemplaire : permissions: {} partout, chaque action épinglée
par SHA, aucune interpolation dangereuse, provenance signée. Un contributeur
disposant du droit write ajoute un fichier dans .github/workflows/. Ce
fichier n'hérite d'aucune contrainte des autres : il déclare ses propres
permissions, ses propres actions, ses propres déclencheurs.
Aucune des protections écrites dans les autres workflows ne s'applique. Le durcissement est par fichier, la compromission est par dépôt.
C'est précisément le mode opératoire de GhostAction, en septembre 2025 : les attaquants n'ont exploité aucune faille de workflow. Ils ont pris le contrôle de comptes de mainteneurs, lu les workflows légitimes pour inventorier les noms des secrets, puis commité un workflow malveillant maquillé en « Github Actions Security ». 327 comptes, 817 dépôts, 3 325 secrets.
La question défensive n'est donc pas seulement « ce workflow est-il sûr ? », mais « qui peut en ajouter un, et qui le relit ? ».
Trois couches, trois portées
Section intitulée « Trois couches, trois portées »| Couche | Où elle se règle | Ce qu'elle ferme |
|---|---|---|
| Dépôt | Rulesets, CODEOWNERS | Qui peut modifier les workflows, et avec quelle revue |
| Organisation | Politiques d'actions, runner groups, secrets d'org | Quel code tiers s'exécute, sur quelle machine, avec quels secrets partagés |
| Traçabilité | Journal d'audit | Ce qui a été modifié, par qui, et quand |
Ces couches ne se remplacent pas. Un ruleset impeccable n'empêche pas d'utiliser une action tierce compromise ; une politique d'actions stricte n'empêche pas un mainteneur d'affaiblir le ruleset. Elles se complètent, et c'est leur cumul qui rend une compromission difficile plutôt qu'improbable.
L'ordre de déploiement qui tient
Section intitulée « L'ordre de déploiement qui tient »Poser les cinq contrôles d'un coup produit surtout du contournement. L'ordre ci-dessous va du moins coûteux en friction au plus exigeant, et chaque étape reste utile même si vous vous arrêtez là.
| Étape | Contrôle | Friction pour l'équipe |
|---|---|---|
| 1 | Ruleset : interdire le force push et la suppression de main | Nulle, personne ne le faisait |
| 2 | CODEOWNERS sur .github/workflows/ | Une revue par changement de pipeline |
| 3 | Ruleset : pull request obligatoire, une approbation, revue code owner | Une revue par changement, quel qu'il soit |
| 4 | Politique d'actions autorisées | Une demande quand une nouvelle action est nécessaire |
| 5 | Runner groups et cloisonnement réseau | Une infrastructure à concevoir |
Les deux premières étapes sont les plus rentables : elles ferment le chemin qu'a emprunté GhostAction, et ne coûtent presque rien tant que personne ne touche aux workflows.
Le piège du contrôle qu'on desserre
Section intitulée « Le piège du contrôle qu'on desserre »Un contrôle de gouvernance a une propriété désagréable : il gêne d'abord ceux qui l'ont posé. La tentation est alors de l'assouplir « juste pour cette fois », et c'est à ce moment précis que la protection disparaît sans que personne ne le remarque.
Deux réflexes rendent ce risque gérable :
- Sauvegarder l'état avant modification, pour que la restauration soit une commande et non un effort de mémoire ;
- Faire mesurer la conformité par un scanner, pour que l'affaiblissement laisse une trace rouge dans la CI plutôt que de passer inaperçu. Un scanner de posture qui vérifie la protection de branche signalera l'écart au prochain passage.
Ce second point est ce qui distingue une gouvernance réelle d'une gouvernance déclarée : sans mesure, la configuration dérive, et personne ne sait depuis quand.
À retenir
Section intitulée « À retenir »- Le durcissement du YAML est par fichier ; la compromission, elle, est par dépôt. Un workflow ajouté n'hérite d'aucune protection des autres.
- GhostAction n'a exploité aucune faille de workflow : les attaquants ont commité un workflow malveillant dans des dépôts dont ils avaient pris le contrôle.
- Trois couches se cumulent : le dépôt (rulesets,
CODEOWNERS), l'organisation (actions autorisées, runners, secrets) et la traçabilité. - L'ordre qui tient va du moins coûteux au plus exigeant : force push interdit, puis
CODEOWNERSsur les workflows, puis revue obligatoire, puis politique d'actions, puis cloisonnement des runners. - La gouvernance est la partie la plus conditionnée au plan : les runner groups additionnels demandent Team, les politiques d'actions n'existent qu'au niveau organisation.
- Un contrôle qu'on desserre doit être sauvegardé avant et mesuré par un scanner, sinon l'affaiblissement devient permanent sans que personne ne le sache.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- CODEOWNERS et revue des workflows : Le contrôle le plus rentable du module, celui qui ferme le chemin emprunté par GhostAction.
- Restreindre les actions autorisées : Décider quel code tiers a le droit de s'exécuter, avant même la question de l'épinglage.
- Runner groups et frontière réseau : Ce qu'un runner compromis peut atteindre, et comment le borner.