Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXXXIII · GitOps RBACRepositoryLayer

Repository permissions — the merge is the deploy

Advanced⏱ ~23 mingit

What you'll learn

  • Treat write access to a GitOps repository as equivalent to deploy access to its clusters
  • Configure branch protection and path ownership so the merge gate matches the blast radius of the path
  • Enumerate the non-human identities that can write to a GitOps repository and what each can reach
  • Recognise the limits of the repository layer and what it cannot enforce

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

In a push pipeline, a merge starts a job and the job holds the credentials. In a pull-based GitOps estate there is no job: the controller is already running, already authenticated, and already watching. The merge itself is the change. That shifts the entire authorisation question upstream, into a system that most organisations administer as a developer-productivity tool rather than as a production access-control plane.

The merge is the deploy

Everything downstream of the merge is automatic and unattended. There is no second human, no approval prompt, and usually no delay beyond the reconcile interval. So the correct mental model for repository access is not “who can propose a change” but “who can change what is running”.

flowchart LR
    A["Write access to GitOps repo"] --> B["Merge to tracked branch"]
    B --> C["Controller polls or receives webhook"]
    C --> D["Desired state changes"]
    D --> E["Cluster changes, unattended"]
    F["Automation identity"] --> B
    G["Repository admin bypass"] --> B

Two of the arrows into the merge node are the ones teams forget. An automation identity — an image-update bot, a promotion workflow, a dependency updater — writes to the same branch without a human. A repository administrator can usually bypass protection rules on their own repository. Both routes reach production, and neither appears in a review of the human reviewer list.

Designing the gate against the blast radius

A single protection rule over the whole repository gives the sandbox overlay the same gate as the production overlay. That is either too slow for the sandbox or too weak for production, and in practice it is both. The fix is to make the gate a function of the path.

# CODEOWNERS
/clusters/sandbox/       @platform-team
/clusters/staging/       @platform-team @app-team-leads
/clusters/production/    @platform-team @sre-oncall
/clusters/*/rbac/        @security-team
/infrastructure/         @platform-team @security-team

The rules that make this work in production:

  • Required review counts scale with the environment. One reviewer for sandbox, two for production, and a distinct owner group for any path that contains RBAC, admission policy, or network policy.
  • Required status checks are non-negotiable on protected paths. A manifest lint, a policy test, and a dry-run render are the only mechanical evidence that the merge will not break reconciliation.
  • Linear history and no force push. A GitOps repository whose history can be rewritten is a repository whose audit trail can be rewritten, and the controller will happily reconcile the rewritten head.
  • Stale approval dismissal. An approval on a three-commit-old diff is an approval of a different change.

What the repository layer cannot do

The merge gate is powerful and narrow. It cannot:

  • Stop content arriving from outside the repository. A Helm chart from a remote registry, a Kustomize remote base, or an ApplicationSet generator that reads another repository all inject desired state that no reviewer of this repository ever saw.
  • Constrain where a manifest lands. Nothing in a pull request prevents a namespace field from naming a namespace the author has no business touching. Only the controller scope does that.
  • Limit the verbs used to apply it. A reviewed manifest is applied with the controller identity, whatever that identity holds.
  • Survive its own administrators. Protection rules are configuration in the hosting platform, and whoever administers that platform can change them without a pull request.

Auditing the layer

The three questions worth asking every quarter, in order:

  1. Which principals can merge to each reconciled path, human and otherwise?
  2. Which of those merges can happen without any human approval at all?
  3. For each reconciled path, which cluster and namespace does it reach, and with which controller identity?

If the answers cannot be produced from configuration in under an hour, the layer is not being administered — it is being assumed.

Production discipline

  1. Treat repository admin as a production role. It confers the ability to remove the gate, which is the same as the ability to deploy.
  2. No direct pushes to a reconciled branch, ever, including from automation. Automation opens pull requests; a merge policy decides whether they auto-merge, and against which paths.
  3. One CODEOWNERS entry per blast radius. The security team owns RBAC paths, the platform team owns infrastructure paths, and application teams own their own overlays only.
  4. Verify signatures at the controller where the tooling supports it. Branch protection is enforced by the host; signature verification is enforced by the thing that actually applies.

Cross-course references

  • Git, CI/CD & GitOps for Infrastructure Engineers - Part XXXI (CODEOWNERS) and Part XXXII (ProtectedBranches) cover the mechanics this lesson applies to a GitOps repository, and Part XXXIII (Signing) covers the signature side.
  • Linux for Production Sysadmins - Part LXXIII (Change) covers change control for systems where the change gate is human rather than mechanical.
  • Ansible for Production Sysadmins - Part XXXVII (RepoArch) covers repository layout choices that determine what a path-scoped ownership rule can express.

Quiz

Knowledge check · 4 questions

  1. Q1. Which principal is most often missing from a GitOps repository access review?

  2. Q2. Branch protection on the GitOps repository prevents desired state from arriving out of an unreviewed source.

  3. Q3. List the branch-protection settings a production GitOps path should carry, and say what each prevents.

  4. Q4. Assess whether the repository layer is doing the job the team believes it is doing.

    A team reports that production deploys require two approvals. Their GitOps repository holds sandbox, staging and production overlays under one directory tree with a single protection rule on the default branch requiring two reviewers from a group of eleven engineers. A promotion workflow holds a machine token with push rights and merges its own pull requests automatically once tests pass. The Argo CD instance reconciles all three overlays with one application controller ServiceAccount.

Passing score: 75%. Answers are checked in this browser.