Le déploiement en production doit être un acte délibéré, validé et traçable, pas un effet de bord d'un git push. GitLab propose quatre mécanismes de contrôle : branches protégées, tags protégés, environnements protégés et deployment freezes. Ce guide vous montre comment configurer chaque couche pour que seules les bonnes personnes puissent déployer le bon code au bon moment.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »À la fin de ce guide, vous saurez :
- Protéger une branche pour contrôler qui peut push et merge
- Protéger les tags pour sécuriser les releases
- Créer un environnement protégé avec approbation obligatoire
- Configurer un deployment freeze pour bloquer les déploiements planifiés
- Appliquer des push rules pour renforcer les conventions
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »Les mécanismes de protection de branches et d'environnements sont nécessaires dès que :
- Votre pipeline déploie automatiquement vers un environnement (staging, production)
- Plusieurs développeurs contribuent au même projet et les MR ne sont pas systématiquement revues
- Vous devez prouver à un auditeur que le déploiement en production suit un processus de validation
- Des périodes de gel de déploiement (release freeze, vacances, événements commerciaux) doivent être respectées
- Vous publiez des releases via des tags et devez empêcher la création de tags par n'importe qui
Branches protégées
Section intitulée « Branches protégées »Protéger une branche dissocie deux droits que GitLab accorde ensemble par défaut : le droit de pousser et le droit de merger. La configuration cible refuse le push à tout le monde, y compris aux Owners, et réserve le merge aux Maintainers ; toute modification passe alors obligatoirement par une merge request. La protection agit aussi sur les variables CI protégées, qui ne sont injectées que dans les pipelines s'exécutant sur une branche ou un tag protégé.
Le problème par défaut
Section intitulée « Le problème par défaut »Sur un projet GitLab, un Maintainer peut pousser directement sur main sans passer par une MR. Un Developer peut merger une MR sans approbation. Il n'y a aucune barrière entre le code écrit et le code déployé.
Configurer une branche protégée
Section intitulée « Configurer une branche protégée »La protection se pose au niveau projet et prend effet immédiatement, sans redémarrer quoi que ce soit. Interdire le force push est le réglage le plus important : sans lui, un historique réécrit fait disparaître des commits déjà revus.
-
Accéder aux paramètres
Settings → Repository → Protected branches.
-
Protéger
mainParamètre Valeur recommandée Justification Branch mainBranche de production Allowed to merge Maintainers Seuls les maintainers mergent vers main Allowed to push and merge No one Personne ne push directement Allowed to force push Non Un force push réécrit l'historique -
Vérifier la protection
Fenêtre de terminal # Via l'API GitLabcurl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_branches"Résultat attendu :
[{"name": "main","push_access_levels": [{"access_level": 0}],"merge_access_levels": [{"access_level": 40}],"allow_force_push": false}]access_level: 0= No one,40= Maintainers.
Protéger par pattern
Section intitulée « Protéger par pattern »Vous pouvez protéger plusieurs branches avec un wildcard :
# Protéger toutes les branches release/*curl --request POST \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_branches" \ --data "name=release/*&push_access_level=0&merge_access_level=40"Patterns courants :
| Pattern | Usage |
|---|---|
main | Branche de production |
release/* | Branches de release |
hotfix/* | Correctifs urgents |
*-stable | Branches LTS |
Via l'API : automatiser la protection
Section intitulée « Via l'API : automatiser la protection »Pour appliquer la même politique sur tous les projets d'un groupe :
#!/usr/bin/env bash# protect-branches.sh : appliquer la politique de branches sur un groupe
GROUP_ID="${1:?Usage: $0 <group_id>}"
# Récupérer tous les projets du groupeproject_ids=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/groups/$GROUP_ID/projects?per_page=100" \ | jq -r '.[].id')
for pid in $project_ids; do echo "Protection de main pour le projet $pid" curl -s --request POST \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$pid/protected_branches" \ --data "name=main&push_access_level=0&merge_access_level=40&allow_force_push=false" \ | jq '{name, push_access_levels, merge_access_levels}'doneTags protégés
Section intitulée « Tags protégés »Les tags se protègent séparément des branches, avec un seul droit à accorder : celui de créer un tag correspondant au motif. Un tag protégé devient également immuable pour la suppression par les profils non autorisés, ce qui évite qu'une release soit retirée puis republiée sur un autre commit avec le même numéro de version.
Pourquoi protéger les tags
Section intitulée « Pourquoi protéger les tags »Un tag déclenche souvent un pipeline de release. Si n'importe quel Developer peut créer un tag v2.0.0, il peut déclencher un build et un déploiement non autorisé.
Configurer des tags protégés
Section intitulée « Configurer des tags protégés »Le motif v* couvre l'ensemble de la convention vX.Y.Z en une seule règle et s'applique aux tags futurs, pas seulement à ceux qui existent déjà.
-
Accéder aux paramètres
Settings → Repository → Protected tags.
-
Protéger le pattern de tags
Paramètre Valeur recommandée Tag pattern v*Allowed to create Maintainers -
Vérifier via l'API
Fenêtre de terminal curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_tags"Résultat attendu :
[{"name": "v*","create_access_levels": [{"access_level": 40}]}]
Environnements protégés
Section intitulée « Environnements protégés »La protection d'environnement déplace le contrôle du dépôt vers la cible de déploiement : peu importe la branche d'origine, c'est l'accès à production qui est restreint. Elle complète les branches protégées sans les remplacer, et c'est le seul mécanisme des quatre qui introduit une validation humaine au milieu d'un pipeline en cours.
Le mécanisme
Section intitulée « Le mécanisme »Un environnement protégé requiert une approbation explicite avant que le déploiement ne s'exécute. Le pipeline atteint le job de déploiement, puis se met en pause jusqu'à ce qu'un approbateur valide.
Configurer un environnement protégé
Section intitulée « Configurer un environnement protégé »L'environnement doit exister avant de pouvoir être protégé, et GitLab ne le crée qu'au premier passage d'un job portant une clé environment:. La configuration se fait donc en deux temps : déclarer l'environnement dans le pipeline, puis le protéger dans l'interface.
-
Déclarer l'environnement dans le pipeline
.gitlab-ci.yml deploy-production:stage: deployscript:- kubectl apply -f manifests/environment:name: productionurl: https://app.example.comrules:- if: $CI_COMMIT_BRANCH == "main"resource_group: production -
Protéger l'environnement
Settings → CI/CD → Environments → production → Edit → Protected environment.
Paramètre Valeur recommandée Allowed to deploy Maintainers Required approvals 1 (minimum) Approvers Utilisateurs ou groupes spécifiques -
Vérifier le comportement
Poussez un commit sur
main. Le pipeline doit atteindre le jobdeploy-production, afficher le statut blocked et attendre l'approbation dans l'interface.
Approbation multi-niveaux
Section intitulée « Approbation multi-niveaux »Pour les environnements critiques, vous pouvez exiger plusieurs approbateurs et séparer les rôles :
# staging : déploiement automatique, pas d'approbation# pre-production : 1 approbation (lead technique)# production : 2 approbations (lead technique + SRE)Configurez via l'API :
# Mettre à jour les approbations requisescurl --request PUT \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_environments/production" \ --data "required_approval_count=2"Tier d'environnement
Section intitulée « Tier d'environnement »GitLab attribue un tier à chaque environnement qui détermine son ordre d'affichage et ses comportements par défaut :
| Tier | Environnements typiques | Auto-stop par défaut |
|---|---|---|
| production | production | Non |
| staging | staging, pre-prod | Non |
| testing | test, qa | Oui (24h) |
| development | dev, review/* | Oui (24h) |
| other | Tout le reste | Oui (24h) |
deploy-staging: environment: name: staging deployment_tier: stagingDeployment freezes
Section intitulée « Deployment freezes »Le gel de déploiement ajoute une contrainte temporelle aux trois précédentes : les périodes se déclarent en expressions cron avec un fuseau horaire explicite, ce qui les rend auditables et évite la convention orale « on ne déploie pas le vendredi ». Attention à une subtilité : pendant la fenêtre, GitLab expose la variable $CI_DEPLOY_FREEZE, que vos jobs de déploiement doivent tester pour ne pas s'exécuter.
Le mécanisme
Section intitulée « Le mécanisme »Un deployment freeze bloque tous les déploiements vers un environnement pendant une période définie. Les pipelines continuent de s'exécuter, mais les jobs de déploiement sont bloqués.
Configurer un freeze
Section intitulée « Configurer un freeze »Une période de gel se décrit par deux expressions cron, début et fin, plus un fuseau horaire : sans lui, GitLab interprète les heures en UTC et le gel décale d'une ou deux heures selon la saison.
-
Via l'interface
Settings → CI/CD → Deploy freezes → Add deploy freeze.
Paramètre Exemple Freeze start 0 18 * * 5(vendredi 18h)Freeze end 0 9 * * 1(lundi 9h)Timezone Europe/Paris -
Via l'API
Fenêtre de terminal curl --request POST \--header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/freeze_periods" \--data "freeze_start=0 18 * * 5&freeze_end=0 9 * * 1&cron_timezone=Europe/Paris" -
Vérifier les périodes actives
Fenêtre de terminal curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/freeze_periods"
Patterns de freeze courants
Section intitulée « Patterns de freeze courants »Ces quatre motifs couvrent les cas les plus fréquents. Rien n'empêche d'en déclarer plusieurs sur un même projet : un gel hebdomadaire et un gel commercial ponctuel se cumulent sans se gêner.
| Période | Cron start | Cron end | Usage |
|---|---|---|---|
| Week-end | 0 18 * * 5 | 0 9 * * 1 | Pas de déploiement le week-end |
| Nuit | 0 20 * * * | 0 7 * * * | Pas de déploiement la nuit |
| Black Friday | 0 0 25 11 * | 0 0 2 12 * | Gel e-commerce fin novembre |
| Fin de trimestre | 0 0 28 3,6,9,12 * | 0 0 2 4,7,10,1 * | Gel comptable |
Push rules
Section intitulée « Push rules »Les push rules s'exécutent côté serveur GitLab, avant l'enregistrement des commits : un push refusé ne laisse aucune trace dans le dépôt et ne déclenche aucun pipeline. Elles s'appliquent à toutes les branches du projet, protégées ou non, ce qui en fait le complément naturel des sections précédentes. La plupart d'entre elles relèvent des éditions payantes.
Compléter la protection des branches
Section intitulée « Compléter la protection des branches »Les push rules ajoutent des vérifications au moment du push, avant que le pipeline ne se déclenche :
Settings → Repository → Push rules.
| Règle | Valeur recommandée | Effet |
|---|---|---|
| Reject unsigned commits | ✅ | Exige des commits signés GPG |
| Commit message regex | ^(feat|fix|docs|chore|refactor|test)(\(.+\))?: .+ | Force Conventional Commits |
| Branch name regex | ^(main|release\/.*|feature\/.*|hotfix\/.*)$ | Limite les noms de branches |
| File name regex (deny) | \.(exe|dll|msi|pkg)$ | Bloque les binaires |
| Maximum file size (MB) | 10 | Empêche les gros fichiers |
Via l'API
Section intitulée « Via l'API »L'endpoint push_rule s'utilise en PUT sur un projet existant. Les expressions régulières doivent être encodées en URL : %2B remplace le + du motif, sinon curl l'envoie comme un espace et la règle rejette tous les messages de commit.
curl --request PUT \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/push_rule" \ --data "reject_unsigned_commits=true" \ --data "commit_message_regex=^(feat|fix|docs|chore|refactor|test)(\(.%2B\))?: .%2B" \ --data "max_file_size=10"Checklist de protection
Section intitulée « Checklist de protection »Une protection configurée dans l'interface se vérifie toujours par l'API : c'est la seule façon de prouver l'état réel, et le seul moyen de contrôler des dizaines de projets sans les ouvrir un par un. Les commandes ci-dessous supposent les variables GITLAB_TOKEN, GITLAB_URL et PROJECT_ID positionnées, avec un jeton portant le scope api.
| Contrôle | Commande de vérification | Attendu |
|---|---|---|
main protégée | curl .../protected_branches | push_access_levels: [{access_level: 0}] |
| Force push interdit | idem | allow_force_push: false |
Tags v* protégés | curl .../protected_tags | create_access_levels: [{access_level: 40}] |
| Env production protégé | UI → Environments | Badge "protected" visible |
| Approbation requise | UI → Environment settings | ≥ 1 required approval |
| Freeze week-end actif | curl .../freeze_periods | Période vendredi-lundi |
| Push rules actives | curl .../push_rule | Règles configurées |
Dépannage
Section intitulée « Dépannage »La cause la plus fréquente des incidents listés ici est un décalage entre ce qui est protégé et ce qui est réellement utilisé : une branche master protégée alors que le projet pousse sur main, ou un environnement nommé prod dans le pipeline et production dans les paramètres. Comparez toujours la valeur exacte, la correspondance est sensible à la casse.
| Symptôme | Cause probable | Correction |
|---|---|---|
Developer peut push sur main | main non protégée | Settings → Repository → Protected branches → ajouter main |
| Pipeline deploy sans approbation | Environnement non protégé | Settings → CI/CD → Environments → Edit → cocher Protected |
| Variable protégée non injectée | Pipeline sur branche/tag non protégé | Vérifier que la branche ou le tag est dans la liste des éléments protégés |
Tag v1.0.0 créé par un Developer | Tags non protégés | Settings → Repository → Protected tags → ajouter v* |
| Deploy pendant un freeze | Job sans règle $CI_DEPLOY_FREEZE | Ajouter rules: - if: $CI_DEPLOY_FREEZE / when: never au job |
403 Forbidden sur l'API protected_branches | Token sans scope api | Recréer le token avec le scope api et le role Maintainer |
| Push rejeté : "commit not signed" | reject_unsigned_commits activé sans GPG configuré | Configurer GPG sur le poste développeur ou désactiver temporairement la règle |
À retenir
Section intitulée « À retenir »Le contrôle de déploiement dans GitLab repose sur quatre couches complémentaires :
- Branches protégées : le verrou de base. Personne ne push directement sur
main, seuls les Maintainers mergent. Sans ça, tout le reste est contournable. - Tags protégés : le contrôle des releases. Si vos pipelines de release se déclenchent sur tag, protégez le pattern
v*pour que seuls les Maintainers puissent taguer. - Environnements protégés : le contrôle humain avant production. Le pipeline se met en pause sur le job de déploiement, un approbateur valide, le job reprend. C'est la différence entre "ça s'est déployé" et "on a décidé de déployer".
- Deployment freezes : le contrôle temporel. Les périodes sensibles (week-end, gel commercial, maintenance) sont protégées par configuration, pas par une convention orale.
- Push rules : le contrôle le plus précoce. Commits signés, conventions de nommage, taille de fichiers, ces vérifications s'exécutent côté serveur au moment du
git pushet rejettent le push avant qu'aucun pipeline ne démarre.
Les paramètres et niveaux d'accès de GitLab évoluent d'une version à l'autre : vérifiez ces pages officielles si un réglage ne correspond pas à votre instance.
- Protected branches, GitLab Docs
- Protected tags, GitLab Docs
- Protected environments, GitLab Docs
- Deployment safety, Deployment freeze, GitLab Docs
- Push rules, GitLab Docs
- CI/CD variables, Protected variables, GitLab Docs
Testez vos connaissances
Section intitulée « Testez vos connaissances »Dix questions sur les niveaux d'accès, la portée réelle de chaque protection et le comportement des variables protégées.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
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
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications