Skip to main content
RunBook Academy

Git, CI/CD & GitOpsXXXI · CODEOWNERS and Ownership ControlsRequiredReviews

CODEOWNERS and required reviews — how forges turn ownership into a gate

Advanced⏱ ~22 mingit

What you'll learn

  • Trace the path from a pull request to a CODEOWNERS requirement on a protected branch
  • Configure the branch-protection setting that makes CODEOWNERS a gate on GitHub and GitLab
  • Predict the failure mode when a CODEOWNERS requirement is unsatisfiable on a PR
  • Identify why CODEOWNERS required reviews interact with status checks, not replace them

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.

The CODEOWNERS file is the source of truth for who owns a path. The branch protection rule is the source of truth for whether that ownership is required to review a PR before merge. The two are connected by a single setting that is easy to forget and catastrophic when missing: “Require review from Code Owners” on GitHub, the equivalent approval rule on GitLab.

How the wiring works

When a PR is opened against a protected branch, the forge does three things in order:

  1. Reads the CODEOWNERS file in the base ref.
  2. Determines which paths in the PR diff are owned by which entries.
  3. Consults the branch protection rule to decide whether those owners are required or merely suggested.
flowchart LR
    A[PR opened on protected branch] --> B[Forge diffs against base]
    B --> C[Forge reads CODEOWNERS in base]
    C --> D[Compute owners for each changed path]
    D --> E{Branch protection requires code-owner review?}
    E -->|yes| F[Merge blocked until owners approve]
    E -->|no| G[Owners auto-assigned but not required]

If the setting is on, the merge button is disabled until the required owners approve. If the setting is off, the owners are auto-assigned as reviewers but any approval from anyone counts.

Configuring the gate

On GitHub the setting is “Require review from Code Owners” under the branch protection rule. The companion setting “Require approval from the most recent reviewers” prevents an approver from also being the pusher of the change.

On GitLab the equivalent is a merge-request approval rule configured to require approval from the CODEOWNERS file. The rule can require all code owners to approve, any code owner to approve, or a specific number of approvals from the owner group.

ls .github/CODEOWNERS
cat .github/CODEOWNERS
git ls-files | grep CODEOWNERS

A worked example: the rule says @platform/platform-infra is required for /terraform/. A PR touches terraform/prod/iam.tf.

  • “Any owner” rule: one approval from any platform-infra member satisfies the rule.
  • “All owners” rule: every member must approve - rarely configured in production because it does not scale beyond three or four owners.
  • Multiple teams listed: the rule may require approvals from each team, or any team, depending on configuration.

Interaction with status checks

CODEOWNERS required review is a human check; it does not replace required status checks from CI. A PR that has all required CODEOWNERS approvals but failing CI is still blocked. The reverse is also true: a PR with green CI but no CODEOWNERS approval is still blocked.

flowchart LR
    A["PR ready to merge"] --> B{"Code-owner approvals?"}
    B -->|no| C["Blocked: code-owner approval missing"]
    B -->|yes| D{"Required CI checks green?"}
    D -->|no| E["Blocked: CI failing"]
    D -->|yes| F["Merge enabled"]

The separation is intentional. CODEOWNERS is the answer to “did a person who knows this code review it?”. Status checks are the answer to “did the code pass automated verification?”. A control that does both is not redundant; it is the composition of two controls that answer different questions.

Unsatisfiable requirements

A CODEOWNERS requirement is unsatisfiable when no eligible reviewer can approve: the required team has no members, the team has members but none has merge rights, or the CODEOWNERS handle is misspelled or references a deleted user. When the requirement is unsatisfiable, the PR is blocked indefinitely. The only resolutions are to add a member with merge rights or to bypass the rule (covered in the next lesson).

Production discipline

Treat the CODEOWNERS-required-review setting as part of the protected-branch contract: any change to branch protection must be a PR with two reviewers, including one from security. Verify the wiring after every CODEOWNERS change with a test PR. Quarterly audit the requirement itself; team membership drifts, and team handles that worked a year ago may now reference empty teams.

Cross-course references

  • Linux for Production Sysadmins - Part XII (RepoSecurity) covers repository trust; CODEOWNERS required review is the team-level instance of that trust.

Quiz

Knowledge check · 4 questions

  1. Q1. A team has a CODEOWNERS file and branch protection on the default branch. CI checks are green on a PR but no CODEOWNERS approval has been recorded. What blocks the merge?

  2. Q2. CODEOWNERS required review and required CI status checks are two separate gates that both must be satisfied before merge.

  3. Q3. Name the three pieces that must be wired together for CODEOWNERS to function as a merge gate.

  4. Q4. Diagnose why a PR is blocked indefinitely despite having CI green and a CODEOWNERS file.

    A team has a CODEOWNERS file mapping /terraform/ to @platform/platform-infra and branch protection requiring review from Code Owners. A PR is opened that touches only terraform/prod/main.tf. CI is green. The merge is blocked indefinitely. The team reports that the platform-infra team has three members, all of whom have approved, but the merge is still blocked.

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