Aller au contenu
CI/CD & Automatisation medium

GitLab CI : branches protégées, environnements et approbations

14 min de lecture

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.

À 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

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

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

  1. Accéder aux paramètres

    Settings → Repository → Protected branches.

  2. Protéger main

    ParamètreValeur recommandéeJustification
    BranchmainBranche de production
    Allowed to mergeMaintainersSeuls les maintainers mergent vers main
    Allowed to push and mergeNo onePersonne ne push directement
    Allowed to force pushNonUn force push réécrit l’historique
  3. Vérifier la protection

    Fenêtre de terminal
    # Via l'API GitLab
    curl --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.

Vous pouvez protéger plusieurs branches avec un wildcard :

Fenêtre de terminal
# 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 :

PatternUsage
mainBranche de production
release/*Branches de release
hotfix/*Correctifs urgents
*-stableBranches LTS

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 groupe
project_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}'
done

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

  1. Accéder aux paramètres

    Settings → Repository → Protected tags.

  2. Protéger le pattern de tags

    ParamètreValeur recommandée
    Tag patternv*
    Allowed to createMaintainers
  3. 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}]
    }
    ]

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.

  1. Déclarer l’environnement dans le pipeline

    .gitlab-ci.yml
    deploy-production:
    stage: deploy
    script:
    - kubectl apply -f manifests/
    environment:
    name: production
    url: https://app.example.com
    rules:
    - if: $CI_COMMIT_BRANCH == "main"
    resource_group: production
  2. Protéger l’environnement

    Settings → CI/CD → Environments → production → Edit → Protected environment.

    ParamètreValeur recommandée
    Allowed to deployMaintainers
    Required approvals1 (minimum)
    ApproversUtilisateurs ou groupes spécifiques
  3. Vérifier le comportement

    Poussez un commit sur main. Le pipeline doit atteindre le job deploy-production, afficher le statut blocked et attendre l’approbation dans l’interface.

Pour les environnements critiques, vous pouvez exiger plusieurs approbateurs et séparer les rôles :

Politique d'approbation recommandée
# staging : déploiement automatique, pas d'approbation
# pre-production : 1 approbation (lead technique)
# production : 2 approbations (lead technique + SRE)

Configurez via l’API :

Fenêtre de terminal
# Mettre à jour les approbations requises
curl --request PUT \
--header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_environments/production" \
--data "required_approval_count=2"

GitLab attribue un tier à chaque environnement qui détermine son ordre d’affichage et ses comportements par défaut :

TierEnvironnements typiquesAuto-stop par défaut
productionproductionNon
stagingstaging, pre-prodNon
testingtest, qaOui (24h)
developmentdev, review/*Oui (24h)
otherOui (24h)
.gitlab-ci.yml
deploy-staging:
environment:
name: staging
deployment_tier: staging

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.

  1. Via l’interface

    Settings → CI/CD → Deploy freezes → Add deploy freeze.

    ParamètreExemple
    Freeze start0 18 * * 5 (vendredi 18h)
    Freeze end0 9 * * 1 (lundi 9h)
    TimezoneEurope/Paris
  2. 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"
  3. 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"
PériodeCron startCron endUsage
Week-end0 18 * * 50 9 * * 1Pas de déploiement le week-end
Nuit0 20 * * *0 7 * * *Pas de déploiement la nuit
Black Friday0 0 25 11 *0 0 2 12 *Gel e-commerce fin novembre
Fin de trimestre0 0 28 3,6,9,12 *0 0 2 4,7,10,1 *Gel comptable

Les push rules ajoutent des vérifications au moment du push, avant que le pipeline ne se déclenche :

Settings → Repository → Push rules.

RègleValeur recommandéeEffet
Reject unsigned commitsExige 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)10Empêche les gros fichiers
Fenêtre de terminal
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"
ContrôleCommande de vérificationAttendu
main protégéecurl .../protected_branchespush_access_levels: [{access_level: 0}]
Force push interditidemallow_force_push: false
Tags v* protégéscurl .../protected_tagscreate_access_levels: [{access_level: 40}]
Env production protégéUI → EnvironmentsBadge “protected” visible
Approbation requiseUI → Environment settings≥ 1 required approval
Freeze week-end actifcurl .../freeze_periodsPériode vendredi-lundi
Push rules activescurl .../push_ruleRègles configurées
SymptômeCause probableCorrection
Developer peut push sur mainmain non protégéeSettings → Repository → Protected branches → ajouter main
Pipeline deploy sans approbationEnvironnement non protégéSettings → CI/CD → Environments → Edit → cocher Protected
Variable protégée non injectéePipeline 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 DeveloperTags non protégésSettings → Repository → Protected tags → ajouter v*
Deploy pendant un freezeJob sans règle $CI_DEPLOY_FREEZEAjouter rules: - if: $CI_DEPLOY_FREEZE / when: never au job
403 Forbidden sur l’API protected_branchesToken sans scope apiRecré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

Le contrôle de déploiement dans GitLab repose sur quatre couches complémentaires :

  1. 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.
  2. 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.
  3. Environnements protégés : la porte de production. Le pipeline se met en pause, un humain valide, le déploiement continue. C’est la différence entre “ça s’est déployé” et “on a décidé de déployer”.
  4. 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.
  5. Push rules : la dernière ligne. Commits signés, conventions de nommage, taille de fichiers — ces vérifications bloquent les erreurs avant qu’elles n’atteignent le pipeline.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

10 questions
5 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 site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn