Protection rules make a job wait before it may use an environment. Required reviewers (up to six users or teams; one approval suffices) must approve, and a wait timer (1 to 43,200 minutes) delays the start. On the Free, Pro and Team plans both work only in public repositories. BookNest's owner reviews production:
gh api -X PUT repos/{owner}/{repo}/environments/production --input - \
--jq '[.protection_rules[].type]' <<'EOF'
{"wait_timer": 1, "prevent_self_review": false,
"reviewers": [{"type": "User", "id": 15277380}],
"deployment_branch_policy": {"protected_branches": false, "custom_branch_policies": true}}
EOF["required_reviewers","wait_timer","branch_policy"]
The id comes from gh 29 api user --jq .id; prevent_self_review: true would stop whoever started a run from approving it, which a one-person project cannot use. After gh workflow run deploy.yml, production stopped:

The pending-deployments API reported "current_user_can_approve":true, yet approving through it failed:
gh api -X POST repos/{owner}/{repo}/actions/runs/36134299193/pending_deployments \
-F 'environment_ids[]=22740887481' -f state=approved -f comment='Staging looks good'{"message":"Resource not accessible by personal access token",...,"status":"403"}gh: Resource
not
accessible by personal access token (HTTP 403)The token lacks Deployments write permission, so approval is not run here: the reviewer clicks Review deployments, comments, and approves or rejects. The run was cancelled; waiting is not billed. The wait timer did run: the approvals API lists it as approved by github-actions[bot] with the comment 1 minute wait timer, and on staging in a later run the timer started at 12:28:52 and the job at 12:29:54.