How do deployment protection rules with required reviewers work in GitHub, and how do you implement a multi-stage approval workflow for production deployments?
Quick Answer
Deployment protection rules gate environment deployments behind required reviewers, wait timers, and custom protection rules via webhooks. Workflows pause execution when hitting a protected environment, creating an approval request that designated reviewers must approve before the job proceeds.
Detailed Answer
Think of deployment protection rules like the launch sequence for a rocket. You do not press one button and hope for the best. Instead, there is a staged approval chain: the flight director verifies the trajectory (staging approval), the safety officer confirms abort systems (wait timer), and the mission commander gives final authorization (production approval). Each gate must be cleared before proceeding, and any authority can halt the launch.
Deployment protection rules are configured at the environment level in repository settings. An environment in GitHub is a named deployment target (like staging, production, or canary) that can have associated protection rules, secrets, and variables. The three built-in protection rules are: required reviewers (up to six individuals or teams who must approve), wait timer (a delay of up to 43,200 minutes or 30 days), and branch restrictions (limiting which branches can deploy to this environment). When a workflow job references a protected environment via the 'environment' key, GitHub pauses the job before it starts and creates a deployment review request.
Under the hood, when a workflow run reaches a job targeting a protected environment, GitHub checks the environment's protection rules. If required reviewers are configured, GitHub sends notifications to the designated reviewers and the workflow enters a 'waiting' state. The job will not start—no runner is allocated and no code executes—until an authorized reviewer approves the deployment through the GitHub web UI, mobile app, or API. Reviewers can approve or reject with a comment, and the approval is valid only for that specific run. If rejected, the job fails. The wait timer runs in parallel with reviewer approval: if both are configured, the job starts only after both conditions are satisfied.
For the payments-api production deployment pipeline, a mature multi-stage setup uses three environments: staging (auto-deploy from main), canary (requires one reviewer from the on-call team), and production (requires two reviewers from the platform-leads team plus a 15-minute wait timer). Custom deployment protection rules, available on GitHub Enterprise, extend this by sending a webhook to an external service—for example, a Datadog integration that checks error rates and latency before approving a canary-to-production promotion. The external service calls back to the GitHub API to approve or reject the deployment within the 30-day timeout window.
A key gotcha is the reviewer-as-deployer antipattern: by default, the person who triggered the workflow can also approve the deployment if they are listed as a required reviewer. To enforce separation of duties, you must configure 'Prevent self-review' in the environment settings (available since 2024). Another common issue is reviewer fatigue in high-frequency deployment pipelines—if your team deploys 20 times per day, required reviewers become a bottleneck. Mitigate this with tiered environments where only production requires human approval while lower environments use automated checks via custom deployment protection rules. Also note that environment protection rules only apply to public repositories and private repositories on GitHub Pro, Team, or Enterprise plans—free private repositories cannot use them.