GitHub branch protection¶
Purpose: provide a self-service checklist for turning repository-local agent rules into enforced GitHub settings.
Audience: maintainers and repository administrators.
Recommended ruleset¶
dpone currently uses solo-maintainer governance mode: the repository has one human owner, so GitHub cannot count that same owner as both pull-request author and approving reviewer. GitHub rejects self-approval by design. In this mode, CODEOWNERS remains an ownership map, but branch protection must not require a CODEOWNER approval that only the PR author can provide.
The machine-readable policy is
.agents/policy/github-branch-protection.yml. Validate it with:
Compare the policy to live GitHub settings with:
uv run python tools/agent_policy/github_settings_drift.py \
--policy .agents/policy/github-branch-protection.yml \
--repo PaulKov/dpone
The scheduled Agent Governance Drift workflow runs the same comparison and
uploads agent-governance-drift-summary.json as the primary audit receipt. The
ruleset endpoint is publicly readable, but GitHub's classic branch-protection
endpoint requires an Administration read token. Configure
DPONE_GOVERNANCE_GITHUB_TOKEN as a repository secret to make that part a hard
live check; without it the workflow records classic branch protection and the
overall summary as UNVERIFIED instead of calling missing evidence a pass.
Create or update a ruleset named protect-master.
Target:
- branch:
master
Bypass:
- allow only repository administrators;
- do not grant agent, automation, or broad team bypass unless an incident runbook requires it.
Pull request requirements:
- require a pull request before merging;
- require
0approving reviews whilemode: solo_maintaineris active; - do not require review from Code Owners while
mode: solo_maintaineris active; - dismiss stale approvals when new commits are pushed;
- require conversation resolution before merge;
- block force pushes;
- block branch deletion.
Status checks:
- require checks to pass before merge;
- require branches to be up to date before merge when GitHub allows it without excessive queue churn;
- require these checks:
Quality checks (3.11);Quality checks (3.12);PostgreSQL XMin integration;Airflow 2.10.5 / py3.11;Airflow 2.10.5 / py3.12;Airflow 2.11.0 / py3.11;Airflow 2.11.0 / py3.12;Airflow 3.2.0 / py3.11;Airflow 3.2.0 / py3.12;Airflow 3.3.0 / py3.11;Airflow 3.3.0 / py3.12;Build GitHub Pages documentation;Analyze Python;CodeQL;TruffleHog verified secrets;Dependency Review;Agent PR receipt.
Required workflows must report a check on every pull request. GitHub leaves
checks pending when an entire workflow is skipped by pull_request path filters,
which blocks merge for required checks. Use always-on pull request triggers with
job-level no-op or conditional steps for expensive scoped checks instead.
Dependency review is enforced by .github/workflows/dependency-review.yml with
actions/dependency-review-action and fail-on-severity: high, so high or
critical dependency advisories introduced by a PR block merge before release
evidence is built.
Merge methods:
- allow merge commits for traceable PR integration history;
- allow squash only if release notes and evidence still preserve individual task context;
- do not allow direct pushes to
master.
Owner attestation replaces impossible self-approval in solo-maintainer mode. The
PR must link the approved spec, issue, ADR, docs path, or N/A: reason; record
validation evidence statuses; state the owner decision; list required GitHub
checks on the reviewed head commit; and call out whether admin bypass was used.
Normal merges must not use admin bypass. Agent PR receipt enforces those
fields for PRs touching the agent control surface and uploads
agent_pr_receipt.json; non-agent PRs report N/A so the required check stays
fast and deterministic without turning missing agent evidence into a pass. For
agent-control PRs the receipt also verifies live required checks and the
agent-governance-gate artifact against the reviewed head SHA before returning
PASS. The governance artifact must expose an artifact id, workflow run id,
SHA-256 digest, and positive size from GitHub Actions artifact metadata; a
stale, expired, digestless, or sizeless artifact fails closed. The receipt also
downloads the artifact zip, computes the local downloaded archive SHA-256 and
byte length, requires both to match GitHub artifact metadata, and validates
exactly one agent_governance_gate.json inside it. That JSON must have schema
version 1, status: PASS, control_surface_changed: true, changed paths
matching the PR changed paths, and
changed_control_surface_red_team: PASS; stale or invalid content fails closed.
The receipt also verifies the GitHub Artifact Attestation for the extracted
governance JSON subject and requires the expected dpone CI signer workflow,
GitHub OIDC issuer, SLSA provenance predicate, and GitHub-hosted runner
provenance. Missing or failing attestation evidence fails closed even when the
artifact is visible in the GitHub Actions UI.
The passing receipt includes structured
traceability fields so audits can read the approved source, validation
statuses, non-pass reasons, and owner attestation state without scraping PR
Markdown. It also includes an evidence_chain object so audits can follow the
reviewed head commit to required checks, the governance artifact digest, the
local archive fingerprint, governance content summary, and compact attestation
summary without re-querying GitHub.
When dpone gains a second trusted maintainer, switch to multi-reviewer mode:
set required_approving_review_count: 1, set require_code_owner_review: true,
update .agents/policy/github-branch-protection.yml, and run the agent
governance gate.
CODEOWNERS coverage¶
The following paths must remain owner-owned through CODEOWNERS:
AGENTS.md, nestedAGENTS.md,.codex/**,.agents/**;docs/agent-*.md,docs/github-branch-protection.md;tools/agent_policy/**,evals/agent/**;.github/workflows/**,.github/CODEOWNERS, PR and issue templates;- public contracts, architecture docs, dependency files, and release surfaces
already listed in
.github/CODEOWNERS.
Verification after setup¶
After saving ruleset changes:
- Open a documentation-only test PR against
master. - Confirm it cannot merge before required checks complete.
- Confirm CODEOWNER review is not a merge requirement while solo-maintainer mode is active.
- Push a new commit and confirm required status checks rerun on the new head.
- Confirm a skipped Pages deploy does not block PR merge when the docs build check passes.
- Open or inspect a non-Airflow PR and confirm the Airflow compatibility checks report success via their no-op path instead of staying pending.
- Open or inspect a dependency-changing PR and confirm
Dependency Reviewreports a required check. - Open or inspect an agent-control PR, leave owner attestation unchecked, leave
Approved specification or issueblank, or leave validation evidence statuses blank, and confirmAgent PR receiptfails. Then check the owner attestation on the reviewed head commit, referenceagent_governance_gate.json, record validation statuses with reasons forSKIP,N/A, orUNVERIFIED, and confirm the receipt reruns toPASSonly after live required checks are successful and theagent-governance-gateartifact exists for the same head SHA with matchingagent_governance_gate.jsoncontent and a verified GitHub Artifact Attestation for that JSON subject. Reproduce PR-body grammar problems locally before rerunning GitHub CI:
uv run python tools/agent_policy/pr_body.py check \
--phase draft \
--body-file test_artifacts/agent-policy/pr-body.md \
--changed-paths-file test_artifacts/agent-policy/pr-changed-paths.txt
uv run python tools/agent_policy/pr_body.py check \
--phase final \
--body-file test_artifacts/agent-policy/pr-body.md \
--changed-paths-file test_artifacts/agent-policy/pr-changed-paths.txt
draft preflight catches source and validation-table grammar. final
preflight also checks the owner-attestation and governance-receipt reference
text. GitHub still validates live required checks plus artifact digest and
downloaded archive fingerprint metadata through Agent PR receipt.
Confirm the uploaded agent-pr-receipt artifact contains
agent_pr_receipt.json with a structured traceability object,
an evidence_chain object with required-check metadata and the
agent-governance-gate artifact id, workflow run id, reviewed head SHA, and
SHA-256 digest plus local archive SHA-256, local archive size, content
status, changed paths, key governance check statuses, and compact attestation
status,
agent_audit_manifest.json with compact traceability and evidence-chain
fields, and is configured with retention-days: 90.
9. Run Agent Governance Drift and confirm
agent-governance-drift-summary.json has overall_status: passed. Confirm
classic branch protection is passed when
DPONE_GOVERNANCE_GITHUB_TOKEN is configured, or explicitly unverified
otherwise.
Record the result in the PR or release evidence as:
Branch protection: PASS
Ruleset: protect-master
Required checks: Quality checks (3.11), Quality checks (3.12), PostgreSQL XMin integration, Airflow matrix, docs build, CodeQL, TruffleHog, Dependency Review, Agent PR receipt
CODEOWNER review: disabled in solo-maintainer mode
Owner attestation: present
Traceability source: <issue/spec/ADR/docs path or N/A: reason>
PR receipt: agent_pr_receipt.json with live required-check and artifact evidence
PR receipt traceability: source, statuses, non-pass reasons, owner attestation
PR receipt evidence chain: head SHA, required checks, governance artifact id, run id, digest, local archive SHA-256, local archive size, content status, content changed paths
PR audit manifest: agent_audit_manifest.json with compact traceability and evidence-chain fields
Governance artifact retention: 90 days
Direct push to master: blocked
Settings drift summary: PASS or UNVERIFIED with reason
Settings drift artifact: agent-governance-drift-summary.json
Verified at: <ISO-8601 timestamp>
Operations notes¶
- If a required check name changes, update this page, the ruleset, and the PR template in one PR.
- If GitHub settings drift from
.agents/policy/github-branch-protection.yml, either restore the live setting or update the policy and evidence in the same PR. Use per-component receipts for diagnosis, but useagent-governance-drift-summary.jsonas the final status artifact. - If a check is flaky, fix or quarantine the underlying check. Do not remove a release-critical required check just to merge faster.
- Emergency bypass must use the
Admin bypass / break-glassissue template and leave owner, reason, affected PR/commit/tag, completed evidence, residual risk, rollback plan, and follow-up review deadline. Link the issue from the PR, release, or incident evidence. A bypass is not a substitute for normal feature review; it is a time-boxed audit record for a higher-risk emergency.
Related pages: