Enforcing Required Approvals on GitLab Merge Requests: A Practical Guide
A step‑by‑step walkthrough for setting minimum approvals, using CODEOWNERS, and verifying the merge gate in GitLab.
28 Jun 2026, 22:34 UTC

The problem: merges slip through without review
Teams that rely on informal code‑review habits often discover late that a merge request (MR) was accepted with only a cursory glance—or none at all. The result is hidden bugs, inconsistent style, and a growing debt that slows future work. GitLab solves this by letting you declare a minimum number of approvals that must be recorded before the Merge button becomes active.
Configuring approval rules
Approval rules live in Project → Settings → General → Merge request approvals. The same UI exists at the group level, so a single policy can cascade to every project underneath. The key fields are:
- Approvals required – the integer count (e.g., 2).
- Approvers – specific users, groups, or leave blank to allow any member with
Developeror higher role to count. - Code owners – when a
CODEOWNERSfile exists, GitLab automatically adds the listed owners as required approvers for the files they own.
Changes here require Maintainer or Owner permissions on the project (or group). The setting is respected by merge trains and merge‑when‑pipeline‑succeeds without extra configuration.
Worked example: project‑level rule with CODEOWNERS
Assume a service repository myorg/payments where the billing/ directory is owned by the billing-team group and the api/ directory by api-team. The goal: every MR touching billing/ needs at least one approval from billing-team, and the whole MR needs two total approvals.
- Open Project → Settings → General → Merge request approvals.
- Set Approvals required to
2. - Leave Approvers blank so any qualified developer can satisfy the generic count.
- Commit a
CODEOWNERSfile at the repository root:
# CODEOWNERS
/billing/ @myorg/billing-team
/api/ @myorg/api-team
When a developer opens an MR that modifies billing/invoice.rb, GitLab automatically adds @myorg/billing-team as a required approver in the approvals widget. The MR now shows two required approvals: one from the code‑owner group and one from any other eligible reviewer. The Merge button stays disabled until both are recorded.
Trade‑offs and limitations
- Stalled reviews – If the designated owners are on leave, the MR cannot progress. Mitigate by adding a fallback approver group or by allowing
Release Managerrole to override in emergencies. - Configuration drift – Maintaining per‑project rules leads to inconsistency. Prefer group‑level approval policies or a project template that enforces the baseline.
- Force‑push protection is separate – Approval gates do not stop a user with
Maintainerrights from force‑pushing to a protected branch. Secure the branch under Settings → Repository → Protected Branches withNo oneallowed to force push.
Verify the gate works
- Create a test MR that touches a file covered by
CODEOWNERS. - Confirm the approvals widget lists the required owner group and shows the total required count.
- Observe that the Merge button is grayed out.
- Have two distinct eligible reviewers click Approve.
- Verify the button becomes active and the merge completes (optionally via merge train).
If the button never enables, double‑check that the approvers have at least Developer role on the project and that no conflicting Reset approvals on push setting is clearing the votes.
Next steps
Roll the group‑level approval policy to all existing projects, then audit the CODEOWNERS files for coverage gaps. Schedule a quarterly review of approver availability and adjust fallback groups before they become bottlenecks. With the gate in place, every merge carries a verified review trail—no more surprise merges.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.