Introducing Rampart: Branch Protection Rules Across All Your Repos
I have too many GitHub repos with no branch protection at all. Most of them are personal projects where it doesn’t matter much, but a few have collaborators, are depended on by other projects, or are public-facing enough that I’d really prefer nobody (including me) force-pushes to main by accident.
The GitHub UI makes it easy to set branch protection for one repo. But doing it consistently across thirty repos is tedious. And keeping them consistent over time - when new repos get created, when you decide to change a rule, when you want to check that nothing has drifted - is the kind of thing that only works if it’s automated.
So I built rampart.
What It Does
Rampart is a CLI tool that audits and enforces GitHub branch protection rules across all repos for a user or organization. You define your desired rules in a YAML config file, and rampart tells you which repos are compliant and which aren’t. If you want, it’ll fix the non-compliant ones too.
The workflow is simple:
# Generate a config with sensible defaults
rampart init
# Check all your repos
rampart audit --owner wdm0006
# Fix the ones that don't match
rampart apply --owner wdm0006
The audit command exits non-zero when any repos are non-compliant, so you can run it in CI as a drift detector.
The Config
rampart.yaml defines the branch you want to protect and the rules to enforce:
branch: main
rules:
require_pull_request: true
required_approvals: 1
dismiss_stale_reviews: true
require_code_owner_reviews: false
require_status_checks: false
strict_status_checks: true
required_checks: []
enforce_admins: true
allow_force_pushes: false
allow_deletions: false
required_linear_history: false
required_conversation_resolution: false
The defaults are opinionated toward “protect main from accidents without being annoying”: require a PR with one approval, enforce rules for admins too, don’t allow force pushes or deletions. Status checks are off by default because not every repo has CI configured.
How Audit Works
When you run rampart audit, it:
- Lists all non-fork, non-archived repos for the owner
- Fetches the current branch protection rules for each
- Compares each rule against your config
- Shows pass/fail per repo with details on what’s different
Auditing 24 repos against rampart.yaml (branch: main)
✓ pygeohash
✓ elote
✗ keeks
enforce_admins: want true, got false
allow_force_pushes: want false, got true
✓ vanity
- old-project (skipped: insufficient permissions)
Results: 21 compliant, 2 non-compliant, 1 skipped out of 24 repos
Repos where you don’t have admin access get skipped with a note rather than failing the whole run. Repos with no protection configured at all show up as non-compliant with every rule diffed against the zero state.
Apply and Dry Run
Once you know what’s out of compliance, rampart apply fixes it:
# Preview what would change
rampart apply --owner wdm0006 --dry-run
# Actually apply
rampart apply --owner wdm0006
You can also target a single repo or exclude specific ones:
rampart apply --owner wdm0006 --repo keeks
rampart audit --owner wdm0006 --exclude legacy-thing --exclude experiment
Implementation
Rampart follows the same pattern as vanity: a Go CLI that wraps the gh CLI for all GitHub API calls. No SDK, no OAuth setup, no token management. If gh auth login works, rampart works.
It’s installable via Homebrew:
brew install wdm0006/tap/rampart
Or grab a binary from the releases page, or go install:
go install github.com/wdm0006/rampart/cmd/rampart@latest
Why Not Terraform?
If you manage GitHub repos at scale, you might already use Terraform with the GitHub provider. That works well for organizations with dedicated infrastructure teams. Rampart is for the rest of us - individual maintainers and small teams who want a quick way to check and enforce a baseline without setting up state files and plan/apply cycles.
The YAML config is the entire state. There’s no drift to reconcile. You run audit, see the diff, and decide whether to apply.
Check out the repo: github.com/wdm0006/rampart
Stay in the loop
Get notified when I publish new posts. No spam, unsubscribe anytime.