Skip to content
Français
CI/CD & Automatisation medium

GitHub deployment protection rules

30 min de lecture

Read this page in French

An environment with no rule is just a label. It is the protection rules that turn it into a boundary: requiring a human approval, imposing a delay before execution, restricting the branches allowed to deploy, or delegating the decision to a third-party system. This page details all four, with their stated limits and the exact behaviour of secrets during the wait.

What you will learn

  • Require an approval and know who can grant it, and who cannot
  • Use the wait timer as a cancellation window, without paying for the minutes
  • Restrict the branches and tags allowed to deploy to a target
  • Wire in a custom rule driven by an observability or ITSM tool
  • Understand why secrets do not leak while an approval is pending

The four available rules

RuleWhat it controlsLimit
Required reviewersWho authorises the deploymentUp to 6 people or teams
Wait timerHow long to wait before starting1 to 43,200 minutes (30 days)
Deployment branches and tagsWhere the deployment may start from3 possible policies
Custom deployment protection rulesA decision delegated to a third party6 active rules at most

They stack. A serious production environment typically combines three of them: a human approval, a restriction to protected branches, and sometimes a custom rule checking that no incident is ongoing.

Required approval: the main guardrail

The Required reviewers rule pauses the job and waits for an authorised person to validate it. You designate up to six users or teams, and a single approval is enough to unblock the job. So it is not a quorum: it is a list of authorised people, any one of whom can open the door.

One detail matters a great deal in practice: when self-approval is disabled in the settings, the person who triggered the deployment cannot approve it themselves. That is what separates a real four-eyes control from a tick box.

What happens during the wait

This is the most important point on this page, and the most often ignored:

A job cannot access the environment secrets until one of the required reviewers has approved it.

In other words, the wait is not a cosmetic pause in front of an already armed job. Until the approval is granted, the runner has never seen the production token. A compromised workflow reaching the deployment step would obtain nothing more than an approval request visible to the whole team.

jobs:
deploy-production:
needs: deploy-staging
runs-on: ubuntu-24.04
environment:
name: production # an environment with required reviewers
url: https://my-app.example.com
steps:
- name: Deploy to production
run: ./deploy.sh
env:
# This secret is only delivered after the human approval
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Wait timer: the cancellation window

The wait timer delays the start of the job by 1 to 43,200 minutes, that is up to 30 days. Its virtue is not slowing things down but opening a cancellation window: if a problem appears just after the merge, you have time to stop the run before it touches production.

One billing point worth knowing, because it answers the most frequent objection: the waiting time is not billed. You do not pay runner minutes while the timer runs, since the job has not started yet.

In practice, five to fifteen minutes is enough for a useful window. Beyond that, you no longer get a safety measure but a queue, and the team will get used to working around the mechanism.

Allowed branches and tags

The third rule answers a simple question: where are you allowed to deploy to this target from? Three policies are offered:

PolicyEffectTypical usage
No restrictionAny branch or tag can deployA disposable test environment
Protected branches onlyOnly branches covered by a protection ruleSimple production
Selected branches and tagsExplicit name patterns (main, release/*, v*)Production with release branches

Without this rule, any feature branch can, through a manually triggered workflow, target the production environment and consume its secrets. The restriction closes that door before execution: the job fails immediately, without ever obtaining the secrets.

Custom rules: delegating the decision

The fourth rule, custom deployment protection rules, delegates the authorisation to a third-party service through a GitHub App. The deployment stays pending until that service answers. GitHub lists Datadog, Honeycomb and ServiceNow among the available integrations, and an environment accepts six active rules at most.

The point is not to add a click, but to automate a criterion humans evaluate badly or too late:

  • observability refuses the deployment when the error rate of the running version exceeds a threshold, or when an error budget is already spent;
  • ITSM refuses the deployment outside an approved change window, or while a major incident is open.

That is the maturity level above human approval: the question "are we allowed to deploy right now?" stops depending on one person's alertness on a Friday evening.

A realistic progression

Applying all four rules at once to an existing repository mostly produces workarounds. The order that lasts goes from the least costly to the most demanding:

StepRule appliedWhat it costs the team
1Allowed branches on productionNothing, nobody deployed from elsewhere
2Secrets moved to environment levelOne migration, once
3Required approval on productionOne click per production release
4A 10-minute wait timerTen minutes, recoverable as a cancellation
5A custom rule tied to incidentsAn integration to maintain

The first two steps are not negotiable: they are free in friction and close the two most used paths. The following ones are discussed with the team, because they are paid in time.

Key points

  • Four rules protect an environment: approval, wait timer, allowed branches and custom rules.
  • The approval accepts up to six reviewers or teams, and a single approval unblocks the job; the initiator cannot self-approve when the option is disabled.
  • Environment secrets are not delivered before the approval: the wait is a real barrier, not a pause in front of an already armed job.
  • The wait timer runs from 1 to 43,200 minutes and is not billed.
  • The branch policy stops a feature branch from targeting production, but it does not replace protecting the branch itself.
  • Custom rules (six at most) delegate the decision to observability or ITSM, and automate the "can we deploy right now?" question.

Next steps

Is this site useful to you?

Fewer than 1% of readers support this site.

I maintain more than 700 free guides, with no ads and no tracking. Any support, even a symbolic one, helps cover hosting and keeps these resources free. Thank you for the help.

The form does not show? Open Ko-fi in a new tab.

Subscribe and follow my DevSecOps work on LinkedIn