There's a threshold every growing engineering organization crosses without noticing. Below it, GitHub governance is a human activity: someone sets up branch protection when a repo is created, remembers to turn on secret scanning, adds the right teams. Above it, that same activity quietly becomes impossible. Nobody configured the last forty repos consistently because nobody could. Branch protection is on for some and off for others. Secret scanning is enabled where someone remembered and missing where they didn't. Three repos have a CODEOWNERS file, the rest don't. None of this was a decision — it's just what happens when configuration depends on memory and there are more repos than anyone can hold in their head.
We see this constantly, because it's usually the state a codebase is in when an organization comes to us to migrate or consolidate onto GitHub Enterprise. Hundreds of repos, each a small snowflake, no two governed quite the same way. The fix isn't a heroic weekend of clicking through settings — that's a snapshot that starts drifting the moment you finish. The fix is to make configuration itself into code, stored centrally and enforced continuously. The tool we use for that is Safe Settings.
Why the obvious fixes don't hold
Before the config-as-code approach, most teams have already tried the alternatives and watched them fail:
- Click-ops. Configuring repos by hand in the GitHub UI. It doesn't scale past a couple of dozen repos, and even where it's done, it drifts — someone changes a setting to unblock themselves and never changes it back.
- One-time scripts. A script that loops over every repo and sets branch protection via the API. Better, but it's still a snapshot. It's correct the day you run it and wrong a month later, because nothing stops a repo from drifting after the script has finished.
- Org-level settings alone. GitHub's organization settings are useful but blunt. They apply to everything or nothing, and real organizations need a baseline that most repos follow plus deliberate exceptions for the ones that are genuinely different. Org settings can't express "this policy everywhere, except these fifteen repos, which need this variant."
Each of these fails for the same underlying reason: governance is treated as an action you take once rather than a state you maintain. At scale, the only thing that holds is continuous enforcement.
What Safe Settings actually does
Safe Settings is a GitHub App — open-source, originally from GitHub — that stores your repository and organization configuration as YAML in a central, restricted repository, and then continuously reconciles every repo in the org against it. You describe the desired state in code; Safe Settings makes reality match, and keeps it matching. If someone changes a governed setting by hand, it's put back. If a new repo is created, it inherits the baseline automatically, without anyone lifting a finger.
The important shift is conceptual. Your repo configuration stops being a property of each individual repo that someone has to remember to set, and becomes a single, versioned, reviewable definition that lives in one place. Changing governance for the whole org becomes a pull request. Auditing governance becomes reading a file. Onboarding a new repo becomes doing nothing at all, because the baseline is already applied.
The moment configuration is code, drift stops being inevitable and starts being a diff someone has to approve.
The layered model is the whole point
The reason Safe Settings works for real organizations — and not just tidy ones — is that its configuration is hierarchical. You define an org-wide baseline that every repo inherits, then layer overrides for suborganizations, teams, or individual repos on top. The baseline gives you uniformity; the overrides give you the controlled exceptions that real life requires.

This is what lets a large, structured organization keep its structure instead of flattening it. GitHub's custom repository properties and topics become targeting labels: a policy can apply to every repo tagged as a production service, or every repo belonging to a particular product line, without listing them one by one. A repo that legitimately needs a different merge strategy or an extra required check gets exactly that, declared explicitly, visible to everyone, and still governed. Nothing is a hand-tuned exception hiding in someone's memory — the exceptions are code too.
What goes in the baseline
The specifics vary by organization, but a governance baseline we'd typically enforce across every repo includes:
- Branch protection on the default branch — pull requests required, a minimum number of reviews, required status checks, and no force-pushing or deleting
main. - Code ownership —
CODEOWNERSin place so the right people are automatically requested for review on the code they own. - Security features on by default — secret scanning with push protection so credentials can't be committed, Dependabot for dependency alerts and updates, and the rest of GitHub's advanced security surface turned on rather than left to chance.
- Required workflows and CI — the checks that must pass before anything merges, applied uniformly instead of copied unevenly from repo to repo.
- Teams, permissions, and labels — consistent access and a consistent taxonomy, so who-can-do-what and how-work-is-tracked don't depend on which repo you happen to be in.
The point isn't the specific list — it's that every repo has the same protections without anyone maintaining them repo by repo, and that changing the standard is a single edit that propagates everywhere.
Rolling it out without breaking anyone's week
Turning on enforcement across hundreds of live repos is exactly the kind of change that can go badly if you do it abruptly. The approach that works is gradual and reversible. We start by bringing the current desired state into config and running it in a dry-run posture, so we can see what would change before anything does. That surfaces the real drift — the repos missing protections, the inconsistent checks — as a reviewable list rather than a surprise.
From there, we reconcile in controlled steps, layering in the legitimate per-team and per-repo exceptions as we find them, so that when enforcement goes fully live, it doesn't trip over the exceptions that were there for good reasons. The result is a baseline that tightens governance without stopping delivery — teams keep shipping, they just ship inside guardrails that are now consistent and enforced. This is the same methodology we use when consolidating repos during a GitHub Enterprise migration, where the governance baseline gets established as part of the move rather than bolted on afterward.
What it looks like at scale
We put this into practice for a client migrating hundreds of repositories onto GitHub, where the challenge wasn't just moving the code — it was preserving a real organizational hierarchy without giving up the velocity GitHub is supposed to provide. A multi-tier Safe Settings model did exactly that: an enforced governance baseline across every repo, custom properties preserving the existing structure, security features and CI standardized org-wide, and the whole migration completed without downtime and within Canadian data-residency requirements. The governance didn't slow the teams down; it's what let the organization operate hundreds of repos as one coherent, auditable platform instead of hundreds of independent snowflakes.
That's the outcome worth aiming for. Not a one-time clean-up that decays, but a standing guarantee: every repo, current and future, protected the same way; every exception explicit and reviewed; and an auditor's questions answered by pointing at a file instead of spelunking through settings.
Governance at scale has to be code
If you're running more repositories than any one person can keep in their head, hand-maintained governance has already failed — you just may not have measured the drift yet. The way out isn't more discipline or more click-ops; it's making the configuration itself into code and letting it enforce itself. Safe Settings is how you make hundreds of repos behave like one well-run one: consistent, secure by default, auditable, and still fast to work in.
Deop migrates and governs GitHub Enterprise at scale — establishing enforced, config-as-code governance baselines across hundreds of repositories. See how we did it for a codebase of hundreds of repos or explore our services.
