Aller au contenu
English
CI/CD & Automatisation medium

CODEOWNERS : imposer une revue sur vos workflows

Read this page in English

25 min de lecture

Un fichier CODEOWNERS déclare qui doit relire quoi. Appliqué à .github/workflows/, c'est le contrôle de gouvernance qui rapporte le plus pour le moins d'effort : il ferme le chemin d'attaque le plus direct, celui du workflow ajouté ou modifié sans relecture compétente.

  • Écrire un CODEOWNERS correct et comprendre sa règle de précédence
  • Protéger spécifiquement le répertoire des workflows
  • Activer l'exigence de revue, sans laquelle le fichier n'est qu'indicatif
  • Anticiper la limite de l'auto-approbation sur un dépôt à mainteneur unique

Une modification de .github/workflows/ ne se lit pas comme une modification de code applicatif. Elle peut accorder des permissions, atteindre des secrets, publier un artefact, ou s'exécuter sur votre infrastructure. Un relecteur qui valide une pull request applicative sans regarder le workflow qui l'accompagne laisse passer le changement le plus lourd de conséquences.

L'incident GhostAction de septembre 2025 illustre exactement ce chemin : aucune faille de workflow exploitée, seulement un workflow malveillant commité dans des dépôts dont les attaquants avaient pris le contrôle. Une revue obligatoire sur ce répertoire, par des personnes qui savent lire un permissions:, transforme cette opération silencieuse en demande visible.

CODEOWNERS se place à la racine, dans .github/, ou dans docs/. La convention la plus lisible est .github/CODEOWNERS, à côté de ce qu'il protège.

.github/CODEOWNERS
# Propriétaires par défaut de tout le dépôt
* @mon-org/mainteneurs
# La CI et sa configuration : revue par l'équipe sécurité
/.github/workflows/ @mon-org/securite @mon-org/mainteneurs
/.github/actions/ @mon-org/securite
/.github/dependabot.yml @mon-org/securite
/.github/CODEOWNERS @mon-org/securite
# La chaîne de build : même exigence
/Dockerfile @mon-org/securite
/requirements*.txt @mon-org/securite

Trois points de syntaxe suffisent à éviter les erreurs courantes :

  • La dernière règle qui correspond gagne. Contrairement à .gitignore, l'ordre est décisif : placez les règles générales en haut, les spécifiques en bas. Une ligne * placée en dernier annulerait tout le reste.
  • Un chemin qui commence par / est ancré à la racine. Sans la barre initiale, le motif correspond à n'importe quel niveau de l'arborescence.
  • Les propriétaires sont des comptes (@utilisateur), des équipes (@org/equipe) ou des adresses de courriel. Une équipe doit avoir un accès en écriture au dépôt pour être un propriétaire valide, sinon la ligne est ignorée en silence.

C'est le malentendu le plus fréquent. CODEOWNERS désigne des relecteurs et déclenche automatiquement une demande de revue. Il n'impose rien.

Pour qu'il morde, il faut activer l'exigence correspondante dans le ruleset ou la protection de branche :

Fenêtre de terminal
REPO=mon-org/mon-projet
# Vérifier que la revue code owner est bien exigée
gh api "repos/$REPO/rulesets/RULESET_ID" \
--jq '.rules[] | select(.type=="pull_request") | .parameters.require_code_owner_review'

La réponse attendue est true. Sur false, votre CODEOWNERS est une suggestion : les relecteurs sont notifiés, la fusion passe sans eux.

Vérifiez également que le fichier est syntaxiquement valide. GitHub affiche les erreurs dans l'interface, onglet Code owners des réglages du dépôt, et une ligne invalide est ignorée sans avertissement dans les pull requests. Une équipe mal orthographiée, ou sans droit d'écriture, produit exactement l'effet d'une protection absente.

Un fait de GitHub structure toute la suite : on ne peut pas approuver sa propre pull request. Aucune configuration ne lève cette règle.

Sur un dépôt où une seule personne contribue, exiger la revue code owner rend donc la fusion impossible par construction : l'auteur est le seul propriétaire, et il ne peut pas s'approuver. Trois sorties existent, à choisir en connaissance de cause.

SortieCe qu'elle coûte
Désigner un second relecteur réelUne dépendance à sa disponibilité
Inscrire le rôle administrateur dans la bypass list du rulesetLe contrôle devient déclaratif pour vous
Réserver l'exigence aux chemins sensiblesLes workflows restent protégés, le reste circule

La troisième est la plus souvent pertinente, et elle est peu connue : rien n'oblige à couvrir tout le dépôt. Un CODEOWNERS limité à .github/workflows/, au Dockerfile et aux fichiers de dépendances protège ce qui compte, tout en laissant le code applicatif suivre un circuit normal.

.github/CODEOWNERS, version ciblée
# Rien sur '*' : le code applicatif ne demande pas de revue code owner
/.github/workflows/ @mon-org/securite
/.github/CODEOWNERS @mon-org/securite
/Dockerfile @mon-org/securite

Un contrôle de gouvernance qu'on n'a jamais vu se déclencher n'est pas un contrôle, c'est une intention. Le test tient en quatre gestes :

Fenêtre de terminal
# Sur une branche de test, modifier un workflow
git switch -c test-codeowners
printf '\n# test\n' >> .github/workflows/ci.yml
git commit -am "test: vérifier la revue code owner"
git push -u origin test-codeowners
gh pr create --fill
gh pr view --json reviewRequests --jq '.reviewRequests'

La sortie doit nommer les propriétaires déclarés, et la pull request doit afficher la revue comme requise, pas seulement demandée. Supprimez la branche ensuite.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • .github/workflows/ est le répertoire dont une modification a le plus de conséquences : permissions, secrets, publication, infrastructure.
  • GhostAction n'a exploité aucune faille de workflow, seulement l'absence de revue sur l'ajout d'un fichier de workflow.
  • Dans CODEOWNERS, la dernière règle qui correspond gagne : les motifs généraux vont en haut, les spécifiques en bas.
  • Une équipe propriétaire doit avoir un accès en écriture, sinon la ligne est ignorée en silence.
  • Couvrez le fichier CODEOWNERS lui-même, faute de quoi n'importe qui peut se déclarer propriétaire de ce qu'il devait faire relire.
  • Le fichier seul ne bloque rien : l'exigence require_code_owner_review doit être active dans le ruleset.
  • On ne peut pas approuver sa propre pull request : sur un dépôt à mainteneur unique, prévoyez un second relecteur, une bypass list, ou une couverture limitée aux chemins sensibles.
  • Runner groups et frontière réseau : Le contrôle qui borne ce qu'une exécution compromise atteint, quand la revue a laissé passer.
  • GitHub CLI (gh) : L'outil qui permet de vérifier en une commande que la revue est réellement exigée, et pas seulement demandée.
  • ActionLint : Le contrôle automatique qui allège la revue humaine en écartant d'emblée les erreurs de syntaxe.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn