Repository default branch requires at least 2 approvals for code changes
GitHub repository default branch enforces required reviews with a minimum of 2 approving reviews before a pull request can be merged.
Assesses whether an approval threshold of at least 2 is configured for code changes targeting the default branch. This protection can be enforced through classic branch protection or repository rulesets.
Risk
Without multi-review approval on the default branch, a single actor can merge changes, degrading integrity and accountability. This enables:
- supply-chain tampering or backdoors
- introduction of exploitable bugs
- bypass of change control via compromised accounts
Run this check with Prowler
Run in Prowler Cloudprowler github --checks repository_default_branch_requires_multiple_approvalsRecommendation
Enforce the four-eyes principle by requiring at least 2 approvals for merges to the default branch.
Strengthen with separation of duties using code owner reviews, dismiss stale approvals, apply protections to admins, and pair with required status checks for defense in depth.
Remediation
CLI
gh api -X PUT repos/<OWNER>/<REPO>/branches/<DEFAULT_BRANCH>/protection -F required_status_checks=null -F enforce_admins=false -F restrictions=null -F required_pull_request_reviews.required_approving_review_count=2Terraform
resource "github_branch_protection" "<example_resource_name>" {
repository_id = "<example_resource_name>"
pattern = "<DEFAULT_BRANCH>"
required_pull_request_reviews {
required_approving_review_count = 2 # Enforces at least 2 approvals before merging into the default branch
}
}Other
Check Code
from typing import List
from prowler.lib.check.models import Check, CheckReportGithub
from prowler.providers.github.services.repository.repository_client import (
repository_client,
)
class repository_default_branch_requires_multiple_approvals(Check):
"""Check if a repository enforces at least 2 approvals for code changes
This class verifies whether each repository enforces at least 2 approvals for code changes.
"""
def execute(self) -> List[CheckReportGithub]:
"""Execute the Github Repository code changes enforce multi approval requirement check
Iterates over each repository and checks if the repository enforces at least 2 approvals for code changes.
Returns:
List[CheckReportGithub]: A list of reports for each repository
"""
findings = []
for repo in repository_client.repositories.values():
if repo.default_branch.approval_count is not None:
report = CheckReportGithub(metadata=self.metadata(), resource=repo)
report.status = "FAIL"
report.status_extended = f"Repository {repo.name} does not enforce at least 2 approvals for code changes."
if repo.default_branch.approval_count_source == "ruleset_not_active":
report.status_extended = f"Repository {repo.name} has at least 2 approvals configured in a ruleset, but the ruleset is not active."
if repo.default_branch.approval_count >= 2:
report.status = "PASS"
report.status_extended = f"Repository {repo.name} does enforce at least 2 approvals for code changes."
findings.append(report)
return findingsReferences
- https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/approving-a-pull-request-with-required-reviews
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-pull-request-reviews-before-merging
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets