Enforcing Code Quality with GitLab Merge Request Approvals
Learn how GitLab Merge Request approvals enforce review policies, block merges until required sign‑offs are recorded, and how to configure, verify, and tune them for safety and velocity.
19 Sept 2025, 01:21 UTC

The problem: unreviewed code slipping into main branches
Many teams rely on merge requests (MRs) as a gate before code reaches main, but without an enforced review policy a developer can accidentally merge changes that haven’t been seen by the right people. This leads to bugs, security gaps, or compliance violations that are costly to fix later.
Thesis: GitLab’s built‑in Merge Request approvals provide a lightweight, configurable gate that blocks merges until the required reviewers have signed off, improving safety without adding external tooling.
How approvals work in GitLab
Approval rules are defined at the project or group level (Settings → General → Merge request approvals). You specify:
- The number of approvals required.
- Which users, groups, or roles can satisfy those approvals (e.g.,
Senior Engineers,Security Team). - Optional integration with
CODEOWNERSto auto‑assign reviewers based on file paths.
When an MR is opened, the Approvals widget shows the current count. The merge button stays disabled until the threshold is met. The same state is exposed via the API (GET /projects/:id/merge_requests/:mr_i/approvals) for CI pipelines or external dashboards.
Worked example: backend service requiring senior and security sign‑off
Suppose a project backend-service needs:
- Two approvals from members of the
senior-engineersgroup. - One approval from the
security-teamgroup.
To configure this:
- Navigate to Project → Settings → General → Merge request approvals.
- Set Number of required approvals to
3. - Under Approvers, add the
senior-engineersgroup twice (GitLab lets you add the same group multiple times to count toward the threshold) and thesecurity-teamgroup once. - Save changes.
When a developer opens an MR:
- The widget displays
0/3 approvals. - After a senior engineer approves, it shows
1/3. - After the second senior engineer and the security reviewer approve, it shows
3/3and the Merge button becomes active.
If the developer rebases or force‑pushes the MR, GitLab resets the approvals by default (unless the project disables Reset approvals on push). The widget will again show 0/3, prompting a re‑review.
Trade‑off: safety vs. velocity
Approval gates reduce the chance of unreviewed code reaching production, but they can create bottlenecks:
- If approvers are unavailable (e.g., during an incident), MRs stall, increasing lead time.
- Overly strict rules may encourage workarounds like bypassing the merge button via
git pushdirectly tomain(which should be protected).
Mitigations include:
- Defining fallback approvers or using
Approver groupswith enough members to cover absences. - Enabling Time‑based auto‑approval (available in GitLab Premium) for low‑risk changes after a configurable period.
- Monitoring approval metrics via the API to detect chronic delays.
Actionable closing: verify and adjust your approval policy
To ensure your configuration works as expected:
- Check the UI: Open any MR and confirm the approvals widget reflects the rule you set.
- Validate via API (requires a personal access token with
apiscope):
The JSON response includescurl --header "PRIVATE-TOKEN: " \ "https://gitlab.example.com/api/v4/projects//merge_requests//approvals"approved_byarrays andapprovals_required. Compare the counts. - Test the merge block: Try to merge before reaching the threshold; the button should be disabled and the API will return
405 Method Not Allowedon the merge endpoint. - Rollback if needed: To revert to a previous rule, return to Settings → General → Merge request approvals, adjust the numbers or groups, and save. Alternatively, use the API:
(Replace placeholders with actual IDs.)curl --request PUT --header "PRIVATE-TOKEN: " \ --data "approvals_required=2" \ --data "approver_group_ids[]=" \ --data "approver_group_ids[]=" \ "https://gitlab.example.com/api/v4/projects//merge_request_approvals"
By regularly reviewing the approval widget, API state, and team velocity metrics, you can keep the gate effective without becoming a blocker.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.