Environment protection "Required reviewers" blocks a deploy in CI
A job that targets a protected environment with Required reviewers pauses until a designated reviewer approves the deployment. The job is not failing; it is intentionally held by the environment protection rule.
What this error means
The job shows "Waiting for review" / "Deployment protection rules" and does not proceed. Logs note the run is waiting for approval from required reviewers.
Waiting for approval from required reviewers ...
# job remains queued under the environment's protection rulesDiagnose it: what token do you actually have?
Permission failures in Actions are almost never about your repository settings alone. Three things combine: the default GITHUB_TOKEN permission set for the repo or organization, the permissions: block in the workflow, and whether the event is a fork pull request, which downgrades the token to read-only regardless of everything else.
- name: Show the token scopes actually granted
run: |
curl -sI -H "Authorization: Bearer $GITHUB_TOKEN" \
https://api.github.com/ | grep -i "^x-oauth-scopes\|^x-accepted"
echo "event: ${{ github.event_name }}"
echo "fork PR: ${{ github.event.pull_request.head.repo.fork }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Common causes
The environment requires manual approval
The environment lists Required reviewers, so any job targeting it waits until an approver clicks Approve.
No eligible reviewer is available
If the only reviewers are unavailable or cannot approve their own run, the job stays blocked.
How to fix it
Approve the deployment
- Open the run and find the environment awaiting review.
- Have a listed reviewer approve (or reject) the deployment.
- The job continues once approval is recorded.
# Run page > Review deployments > select environment > ApproveAdjust reviewers or rules if approvals stall
Add additional eligible reviewers, or relax the rule for non-production environments where manual approval is not needed.
# Settings > Environments > production > Required reviewersGrant the narrowest permission that works
Declaring a permissions: block switches the job from the repository default to exactly what you list, so an incomplete block is a common cause of a new failure right after someone tightened security. List every scope the job needs, not just the one that failed.
permissions:
contents: read # checkout
packages: write # push to GHCR
id-token: write # OIDC to a cloud provider
pull-requests: write # comment on or label a PR
checks: write # publish check runsHow to prevent it
- Keep an adequate set of available required reviewers.
- Reserve Required reviewers for environments that need a gate.
- Note that a held job is waiting, not failing.