Repository default branch requires linear history
GitHub repository default branch enforces Require linear history, blocking merge commits and allowing only squash or rebase merges. This protection can be enforced through classic branch protection or repository rulesets.
Risk
Without a linear history, commit provenance is harder to verify, weakening integrity and accountability.
Merge commits can obscure diffs entering the default branch, hindering audits and rollbacks, enabling unnoticed malicious or unreviewed code, and delaying incident response.
Run this check with Prowler
Run in Prowler Cloudprowler github --checks repository_default_branch_requires_linear_historyRecommendation
Enable Require linear history on the default branch and allow only squash or rebase merges.
Reinforce with branch protection: require pull requests and reviews, status checks, and signed commits. Limit bypass to trusted roles (least privilege) to preserve traceability and defense in depth.
Remediation
CLI
curl -X PUT -H "Authorization: Bearer <TOKEN>" -H "Accept: application/vnd.github+json" -H "Content-Type: application/json" https://api.github.com/repos/<OWNER>/<REPO>/branches/<DEFAULT_BRANCH>/protection -d '{"required_status_checks":null,"enforce_admins":false,"required_pull_request_reviews":null,"restrictions":null,"required_linear_history":true}'Terraform
resource "github_branch_protection" "<example_resource_name>" {
repository_id = "<example_repository_id>"
pattern = "<DEFAULT_BRANCH>"
require_linear_history = true # Critical: enforces linear history on 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_linear_history(Check):
"""Check if a repository requires linear history on default branch
This class verifies whether each repository requires linear history on the default branch.
"""
def execute(self) -> List[CheckReportGithub]:
"""Execute the Github Repository Merging Requires Linear History check
Iterates over all repositories and checks if they require linear history on the default branch.
Returns:
List[CheckReportGithub]: A list of reports for each repository
"""
findings = []
for repo in repository_client.repositories.values():
if repo.default_branch.required_linear_history is not None:
report = CheckReportGithub(metadata=self.metadata(), resource=repo)
report.status = "FAIL"
report.status_extended = f"Repository {repo.name} does not require linear history on default branch ({repo.default_branch.name})."
if (
repo.default_branch.required_linear_history_source
== "ruleset_not_active"
):
report.status_extended = f"Repository {repo.name} has linear history configured in a ruleset on default branch ({repo.default_branch.name}), but the ruleset is not active."
if repo.default_branch.required_linear_history:
report.status = "PASS"
report.status_extended = f"Repository {repo.name} does require linear history on default branch ({repo.default_branch.name})."
findings.append(report)
return findingsReferences
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-linear-history
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets