Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

CODEOWNERS : imposer une revue sur vos workflows

Par mis à jour le

Améliorer cette page

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.

  • Rédiger 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.

  • .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.

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

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn