Vous signez vos images Docker, vous scannez vos dépendances, vous générez des
attestations SLSA. Mais qui peut modifier votre code source ? Si n’importe
qui peut pousser directement sur main, toute votre sécurité en aval est
contournable.
Ce guide explique comment verrouiller l’accès à votre code pour que chaque modification passe par une validation explicite avant d’atteindre la branche principale.
Pourquoi la gouvernance du code source est critique
Section intitulée « Pourquoi la gouvernance du code source est critique »Le problème par défaut
Section intitulée « Le problème par défaut »Sur GitHub et GitLab, sans configuration particulière :
- Tout collaborateur peut pousser sur
main— Un développeur (ou un compte compromis) peut modifier le code de production sans validation - Personne n’est obligé de valider — Même si quelqu’un ouvre une PR, elle peut être mergée sans approbation
- Les workflows CI/CD sont modifiables — Un attaquant peut ajouter une étape qui exfiltre vos secrets vers un serveur externe
- Pas de trace de qui a approuvé quoi — En cas d’incident, impossible de reconstituer la chaîne de décision
Les conséquences concrètes
Section intitulée « Les conséquences concrètes »Un compte compromis ou un insider malveillant peut :
- Injecter une backdoor dans le code applicatif
- Modifier un workflow CI pour voler des secrets (tokens, clés API)
- Altérer le Dockerfile pour inclure un malware dans l’image
- Changer les dépendances vers des packages malveillants
Sans gouvernance, ces modifications passent directement en production.
La solution : 3 mécanismes complémentaires
Section intitulée « La solution : 3 mécanismes complémentaires »La sécurisation du code source repose sur trois mécanismes qui fonctionnent ensemble :
| Mécanisme | Rôle | Sans lui |
|---|---|---|
| Branch Protection | Bloque les push directs, exige des PR validées | N’importe qui peut modifier main |
| CODEOWNERS | Désigne qui doit approuver chaque zone du code | N’importe quel collaborateur peut approuver |
| CONTRIBUTING.md | Documente les règles pour les contributeurs | Règles floues, erreurs de bonne foi |
Étape 1 : Activer Branch Protection
Section intitulée « Étape 1 : Activer Branch Protection »La protection de branche est le gardien automatique de votre dépôt. Elle
empêche les modifications directes sur main et impose un processus de
validation via Pull Request.
Ce que Branch Protection contrôle
Section intitulée « Ce que Branch Protection contrôle »| Protection | Ce qu’elle empêche |
|---|---|
| Require PR before merging | Push direct sur la branche protégée |
| Required approvals | Merge sans validation humaine |
| Require Code Owner review | Merge sans l’accord des responsables désignés |
| Require status checks | Merge avec une CI en échec |
| Block force pushes | Réécriture de l’historique Git |
| Do not allow bypassing | Contournement par les admins |
Configuration sur GitHub
Section intitulée « Configuration sur GitHub »-
Accéder aux paramètres de branche
Dans votre dépôt, allez dans Settings → Branches → Add branch ruleset (nouvelle interface) ou Add rule (ancienne interface).
-
Nommer et cibler la règle
- Ruleset name :
Protect main branch - Enforcement status : Active
- Target branches : Cliquez “Add target” → “Include by pattern” →
main
Vous pouvez ajouter d’autres branches :
release/*,develop, etc. - Ruleset name :
-
Activer les protections essentielles
Dans la section “Rules”, cochez :
-
✅ Require a pull request before merging
- Required approvals : 1 (ou 2 pour les projets critiques)
- ✅ Dismiss stale pull request approvals when new commits are pushed
- ✅ Require review from Code Owners
-
✅ Require status checks to pass before merging
- ✅ Require branches to be up to date before merging
- Ajoutez vos checks CI (tests, lint, build…)
-
✅ Block force pushes
-
-
Empêcher le contournement par les admins
En haut de la page, dans “Bypass list”, assurez-vous que personne n’est listé, ou cochez Do not allow bypassing the above settings.
Sans cette option, un admin peut merger sans respecter les règles — ce qui annule tout l’intérêt de la protection.
-
Sauvegarder
Cliquez Create pour activer la règle.
Configuration sur GitLab
Section intitulée « Configuration sur GitLab »-
Accéder aux paramètres de branche
Dans votre projet, allez dans Settings → Repository → Protected branches.
-
Ajouter la protection sur
main- Branch :
main - Allowed to merge : Maintainers (ou un rôle spécifique)
- Allowed to push and merge : No one
- Allowed to force push : Non coché
- Branch :
-
Activer l’approbation par Code Owners
Cochez Require approval from code owners si vous avez un fichier CODEOWNERS.
-
Configurer les règles de Merge Request
Dans Settings → Merge requests :
- Merge method : Merge commit ou Squash commits
- Squash commits when merging : Selon votre préférence
- Merge checks :
- ✅ Pipelines must succeed
- ✅ All discussions must be resolved
-
Configurer les règles d’approbation
Dans Settings → Merge requests → Approval rules :
- Créez une règle “Default” avec Approvals required: 1
- Ajoutez les utilisateurs ou groupes éligibles
Vérifier que la protection fonctionne
Section intitulée « Vérifier que la protection fonctionne »Testez que vous ne pouvez plus pousser directement :
# Tentative de push direct sur maingit checkout mainecho "# Test de sécurité" >> README.mdgit add README.mdgit commit -m "test: direct push should fail"git push origin mainRésultat attendu :
remote: error: GH006: Protected branch update failed for refs/heads/main.remote: error: Changes must be made through a pull request.Si le push réussit, vérifiez votre configuration Branch Protection.
Étape 2 : Créer un fichier CODEOWNERS
Section intitulée « Étape 2 : Créer un fichier CODEOWNERS »Branch Protection exige “1 approbation”, mais par qui ? Par défaut, n’importe quel collaborateur avec accès en écriture peut approuver. Un attaquant avec deux comptes (ou un complice) pourrait s’auto-approuver.
CODEOWNERS résout ce problème en désignant explicitement qui doit valider chaque partie du code. GitHub et GitLab assignent automatiquement ces personnes comme reviewers sur les Pull Requests.
Comment fonctionne CODEOWNERS
Section intitulée « Comment fonctionne CODEOWNERS »Quand quelqu’un ouvre une PR :
- GitHub/GitLab analyse les fichiers modifiés
- Il consulte le fichier CODEOWNERS pour trouver les responsables
- Il assigne automatiquement ces personnes comme reviewers
- Si “Require Code Owner review” est activé, leur approbation est obligatoire
Analogie : c’est comme avoir des chefs de département. Le responsable sécurité valide les changements de sécurité, le responsable ops valide l’infrastructure. Personne ne peut modifier seul un domaine critique.
Créer le fichier CODEOWNERS
Section intitulée « Créer le fichier CODEOWNERS »Créez le fichier .github/CODEOWNERS (GitHub) ou CODEOWNERS à la racine
(GitLab) :
# ============================================================# CODEOWNERS — Définit les responsables par zone de code# ============================================================# Chaque modification dans une zone listée nécessite l'approbation# d'au moins un CODEOWNER de cette zone.## IMPORTANT : la dernière règle qui matche un fichier gagne.# Mettez les règles générales en premier, les spécifiques après.# ============================================================
# --- Propriétaire global (fallback) ---# S'applique à tous les fichiers qui ne matchent pas une règle plus spécifique* @votre-username
# --- Workflows CI/CD (CRITIQUE) ---# Les workflows peuvent accéder aux secrets et exfiltrer des données.# Exigez une revue par l'équipe sécurité pour toute modification..github/workflows/ @votre-username @security-team.github/actions/ @votre-username @security-team.gitlab-ci.yml @votre-username @security-team
# --- Configuration infrastructure ---# Ces fichiers définissent comment l'application est déployée.# Un Dockerfile malveillant peut compromettre toute l'image.Dockerfile @votre-username @ops-teamdocker-compose*.yml @votre-username @ops-teamhelm/ @votre-username @ops-teamk8s/ @votre-username @ops-teamterraform/ @votre-username @ops-team
# --- Dépendances (risque supply chain) ---# Les fichiers de dépendances sont un vecteur d'attaque majeur.# Dependency confusion, typosquatting, packages compromis...package.json @votre-username @security-teampackage-lock.json @votre-username @security-teamrequirements.txt @votre-username @security-teamrequirements*.txt @votre-username @security-teamPipfile @votre-username @security-teamPipfile.lock @votre-username @security-teamgo.mod @votre-username @security-teamgo.sum @votre-username @security-teamCargo.toml @votre-username @security-teamCargo.lock @votre-username @security-team
# --- Code applicatif ---# Le code source principal, sous la responsabilité du tech lead.src/ @votre-username @tech-leadapp/ @votre-username @tech-leadlib/ @votre-username @tech-lead
# --- Tests ---tests/ @votre-username @qa-leadtest/ @votre-username @qa-leadspec/ @votre-username @qa-lead
# --- Documentation ---docs/ @votre-username*.md @votre-usernameSyntaxe CODEOWNERS détaillée
Section intitulée « Syntaxe CODEOWNERS détaillée »| Pattern | Signification | Exemple |
|---|---|---|
* | Tous les fichiers (fallback) | * @admin |
*.js | Tous les fichiers avec cette extension | *.py @python-team |
/docs/ | Dossier docs/ à la racine uniquement | /src/ @core-team |
docs/ | Tout dossier docs/ n’importe où | tests/ @qa |
@user | Utilisateur GitHub/GitLab | @alice |
@org/team | Équipe dans une organisation | @acme/security |
Vérifier que CODEOWNERS fonctionne
Section intitulée « Vérifier que CODEOWNERS fonctionne »Bon maintenant, testons que CODEOWNERS assigne bien les reviewers automatiquement.
-
Créez une branche de test
Fenêtre de terminal git checkout -b test/codeowners -
Modifiez un fichier dans une zone protégée
Fenêtre de terminal echo "# Test" >> .github/workflows/ci.ymlgit add .github/workflows/ci.ymlgit commit -m "test: verify CODEOWNERS"git push origin test/codeowners -
Ouvrez une Pull Request
Dans GitHub/GitLab, créez une PR de
test/codeownersversmain. -
Vérifiez les reviewers assignés
Les CODEOWNERS de
.github/workflows/doivent apparaître automatiquement comme reviewers requis. -
Testez le blocage
Essayez de merger sans leur approbation — GitHub doit afficher “Review required from code owners”.
Étape 3 : Documenter les règles (CONTRIBUTING.md)
Section intitulée « Étape 3 : Documenter les règles (CONTRIBUTING.md) »CODEOWNERS définit qui approuve. CONTRIBUTING.md explique comment contribuer correctement. C’est le mode d’emploi pour les contributeurs.
Pourquoi documenter les règles ?
Section intitulée « Pourquoi documenter les règles ? »Sans documentation claire :
- Les contributeurs font des erreurs de bonne foi (mauvais format de commit, PR mal structurée)
- Les reviewers passent du temps à expliquer les mêmes règles
- En cas d’incident, vous ne pouvez pas prouver que les règles existaient
Un CONTRIBUTING.md bien rédigé :
- Réduit les frictions pour les nouveaux contributeurs
- Accélère les revues de code
- Sert de preuve d’audit que les processus étaient documentés
Template CONTRIBUTING.md complet
Section intitulée « Template CONTRIBUTING.md complet »Créez CONTRIBUTING.md à la racine de votre dépôt :
# Guide de contribution
Ce projet applique des règles strictes pour garantir la qualité et la sécuritédu code. Toute contribution doit respecter ce guide.
## Processus de contribution
### 1. Créer une branche
Créez une branche depuis `main` avec un nom descriptif :
- `feature/description-courte` — Nouvelles fonctionnalités- `fix/description-courte` — Corrections de bugs- `security/description-courte` — Correctifs de sécurité- `docs/description-courte` — Documentation- `refactor/description-courte` — Refactoring sans changement fonctionnel
```bashgit checkout maingit pull origin maingit checkout -b feature/add-user-authentication```
### 2. Faire vos modifications
- Commitez régulièrement avec des messages clairs- Suivez les conventions de code du projet- Ajoutez des tests pour les nouvelles fonctionnalités
### 3. Ouvrir une Pull Request
- **Titre** : Description concise du changement- **Description** : Expliquez le "pourquoi", pas juste le "quoi"- **Issues liées** : Utilisez `Fixes #123` ou `Closes #456`- **Tests** : Indiquez comment tester votre modification
### 4. Processus de revue
- Au minimum **1 approbation** est requise pour merger- Les zones sensibles (voir ci-dessous) nécessitent l'approbation des **CODEOWNERS** désignés- La CI doit être **verte** (tous les checks passent)- Répondez aux commentaires des reviewers
## Zones sensibles
Ces fichiers/dossiers ont un impact critique sur la sécurité ou lefonctionnement du projet. Ils nécessitent une attention particulière etl'approbation d'un responsable spécifique.
| Zone | Risque | CODEOWNER ||------|--------|-----------|| `.github/workflows/` | Accès aux secrets CI/CD | @security-team || `Dockerfile` | Image de production compromise | @ops-team || `requirements*.txt` | Attaque supply chain | @security-team || `package*.json` | Attaque supply chain | @security-team || `helm/`, `k8s/` | Configuration de déploiement | @ops-team |
## Ce qui est interdit
- ❌ Push direct sur `main` — Toujours passer par une PR- ❌ Merge sans approbation des CODEOWNERS requis- ❌ Désactivation des checks CI pour forcer un merge- ❌ Force push sur les branches protégées- ❌ Merge avec des tests en échec
## Conventions de commit
Nous utilisons [Conventional Commits](https://www.conventionalcommits.org/) :
```type(scope): description courte
Corps optionnel avec plus de détails.
Fixes #123```
Types autorisés :- `feat` : Nouvelle fonctionnalité- `fix` : Correction de bug- `docs` : Documentation- `style` : Formatage (pas de changement de code)- `refactor` : Refactoring- `test` : Ajout/modification de tests- `chore` : Maintenance, dépendances
## Signaler une vulnérabilité
**Ne créez pas d'issue publique pour les failles de sécurité.**
- Utilisez [GitHub Security Advisory](../../security/advisories/new)- Ou contactez security@votre-domaine.fr
Nous nous engageons à :- Accuser réception sous 48h- Fournir une estimation du délai de correction sous 7 jours- Vous créditer (si vous le souhaitez) dans les notes de versionOù placer CONTRIBUTING.md ?
Section intitulée « Où placer CONTRIBUTING.md ? »GitHub reconnaît automatiquement ces emplacements :
CONTRIBUTING.md(racine) — Recommandé.github/CONTRIBUTING.mddocs/CONTRIBUTING.md
Placez-le à la racine pour une visibilité maximale.
Récapitulatif : configurer en 30 minutes
Section intitulée « Récapitulatif : configurer en 30 minutes »-
Activer Branch Protection (10 min)
- PR obligatoire pour merger sur
main - Au moins 1 approbation requise
- Require Code Owner review activé
- Status checks (CI) obligatoires
- Block force pushes
- Do not allow bypassing (même pour les admins)
- PR obligatoire pour merger sur
-
Créer le fichier CODEOWNERS (10 min)
- Définir un owner par défaut (
* @vous) - Protéger les zones critiques : workflows, Dockerfile, dépendances
- Assigner les équipes appropriées
- Définir un owner par défaut (
-
Créer CONTRIBUTING.md (10 min)
- Documenter le processus de contribution
- Lister les zones sensibles et leurs responsables
- Expliquer ce qui est interdit
Checklist de conformité
Section intitulée « Checklist de conformité »Configuration minimale (recommandée pour tout projet)
Section intitulée « Configuration minimale (recommandée pour tout projet) »- Branch Protection activée sur
main - Pull Request obligatoire pour merger
- Au moins 1 approbation requise
- Status checks (CI) obligatoires
- Force push bloqué
Configuration standard (recommandée)
Section intitulée « Configuration standard (recommandée) »- Tout ci-dessus +
- Fichier CODEOWNERS présent et actif
- “Require review from Code Owners” activé
- CONTRIBUTING.md documenté
- “Do not allow bypassing” activé
Configuration haute sécurité
Section intitulée « Configuration haute sécurité »- Tout ci-dessus +
- 2 approbations de personnes différentes
- Commits signés obligatoires (GPG ou Gitsign)
- SECURITY.md pour signaler les vulnérabilités
- Audit log des modifications activé
Erreurs courantes et solutions
Section intitulée « Erreurs courantes et solutions »| Erreur | Conséquence | Solution |
|---|---|---|
| CODEOWNERS sans Branch Protection | Les règles CODEOWNERS sont ignorables | Activer “Require review from Code Owners” dans Branch Protection |
| Admins exemptés des règles | Les admins peuvent contourner toutes les protections | Cocher “Do not allow bypassing the above settings” |
Pattern * en dernier | Écrase toutes les règles spécifiques | Mettre * en premier, règles spécifiques après |
| Pas de fallback owner | Certains fichiers n’ont pas de reviewer | Ajouter * @default-owner comme première règle |
| CONTRIBUTING trop long | Personne ne le lit | Garder l’essentiel, lier vers une doc détaillée si besoin |
| Équipe CODEOWNER inexistante | Erreur silencieuse, revue non requise | Vérifier que les équipes @org/team existent |
Lien avec SLSA Source Track
Section intitulée « Lien avec SLSA Source Track »SLSA (Supply chain Levels for Software Artifacts) définit des niveaux de maturité pour la sécurité du code source :
| Niveau | Exigences | Attaques bloquées |
|---|---|---|
| L1 | Code versionné (Git) | Perte de traçabilité |
| L2 | + Branch Protection + Historique immuable | Push direct, force push |
| L3 | + CODEOWNERS + 1 revue obligatoire | Insider seul, compte compromis |
| L4 | + 2 revues de personnes différentes | Collusion, attaque coordonnée |
La configuration décrite dans ce guide vous amène au niveau Source L3 — suffisant pour la grande majorité des projets.
Pour atteindre L4 (haute sécurité), vous devez :
- Exiger 2 approbations de personnes différentes
- Activer les commits signés obligatoires
- Implémenter un audit trail complet