Layer 3 — Rulesets & Merge Gates
This layer ties Layer 2 and Layer 2b to merge protection: pull requests cannot merge unless the required audit workflows run and pass. Start in Evaluate (audit) mode, then switch to Active after the rollout window.
Configure via the UI
Section titled “Configure via the UI”- Organization → Settings → Rulesets → New ruleset → New branch ruleset (or the enterprise-level equivalent under Policies → Repository).
- Name:
default-branch-protection. - Enforcement status: start in Evaluate (audit mode); flip to Active after the rollout window.
- Bypass list: owners only, used sparingly.
- Target: all repositories, default branch.
- Rules — enable:
- Restrict deletions
- Require linear history
- Require a pull request before merging (1 approval, dismiss stale approvals on push, require Code Owner review if applicable)
- Require status checks to pass — add the zizmor check
- Block force pushes
- Require workflows to run — add both
platform-org/security-workflows/.github/workflows/zizmor-audit.yml@<SHA>andplatform-org/security-workflows/.github/workflows/dcg-scan.yml@<SHA>
- Save.
Configure via the API
Section titled “Configure via the API”For repeatable, version-controlled provisioning, POST to the rulesets endpoint:
gh api \ --method POST \ -H "Accept: application/vnd.github+json" \ /orgs/<org>/rulesets \ --input - <<'JSON'{ "name": "default-branch-protection", "target": "branch", "enforcement": "evaluate", "conditions": { "ref_name": { "include": ["~DEFAULT_BRANCH"], "exclude": [] } }, "rules": [ { "type": "deletion" }, { "type": "non_fast_forward" }, { "type": "required_linear_history" }, { "type": "pull_request", "parameters": { "required_approving_review_count": 1, "dismiss_stale_reviews_on_push": true, "require_code_owner_review": false, "require_last_push_approval": true, "required_review_thread_resolution": true } }, { "type": "workflows", "parameters": { "workflows": [ { "repository_id": <REPO_ID_OF_SECURITY_WORKFLOWS_REPO>, "path": ".github/workflows/zizmor-audit.yml", "ref": "refs/heads/main" }, { "repository_id": <REPO_ID_OF_SECURITY_WORKFLOWS_REPO>, "path": ".github/workflows/dcg-scan.yml", "ref": "refs/heads/main" } ] } } ]}JSONGet the repository ID with:
gh api /repos/platform-org/security-workflows --jq .idAfter the evaluate window
Section titled “After the evaluate window”Review insights at Rulesets → [ruleset] → Insights. Fix repos that would have been
blocked, then PATCH the ruleset to "enforcement": "active".
Fork and contributor PRs
Section titled “Fork and contributor PRs”Required workflows still run on fork PRs, but secrets are unavailable. Make sure the audit path does not depend on secrets, so external contributions are still gated.