How do merge request approval rules work in GitLab and how do you configure code ownership with CODEOWNERS?
Quick Answer
GitLab approval rules define how many approvals an MR needs and from whom before it can be merged. CODEOWNERS is a file that maps file paths to responsible teams or individuals, automatically requiring their approval when their owned files are modified. Together they enforce code review governance without manual oversight.
Detailed Answer
Think of merge request approvals like a document signing process in a law firm. A junior associate (developer) drafts a contract (code change) and submits it for review. The firm's policy (approval rules) requires signatures from a senior partner (tech lead approval) and the department head for the relevant practice area (CODEOWNERS-based approval). The contract cannot be filed (merged) until all required signatures are collected. The CODEOWNERS file is like the firm's org chart that maps each practice area to the responsible partner.
GitLab supports multiple approval rules on a project. Each rule specifies the number of required approvals and the eligible approvers, which can be specific users, GitLab groups, or a combination. Rules can be configured at the project level (Settings > Merge Requests > Approval rules) or defined in the merge request itself. GitLab Premium and Ultimate tiers support additional features: preventing the MR author from approving their own changes, preventing users who pushed commits from approving, requiring re-approval when new commits are pushed, and approval rules based on which files were changed. The CODEOWNERS file (placed at the root of the repository, in .gitlab/, or in docs/) uses a gitignore-like syntax to map file patterns to groups or users. When an MR modifies files covered by CODEOWNERS entries, GitLab automatically requires approval from the designated owners.
Internally, when a merge request is created or updated, GitLab evaluates all configured approval rules. For CODEOWNERS-based rules, GitLab compares the list of changed files in the MR against the patterns in the CODEOWNERS file. Each matched pattern generates an approval requirement. GitLab tracks approvals in a dedicated database table, recording which user approved, when they approved, and which commit SHA they approved. When new commits are pushed to the MR branch and the project has the require_reapproval setting enabled, all existing approvals are reset, forcing reviewers to re-examine the changes. The approval status is also surfaced in the merge request API, allowing external tools and chatbots to query whether an MR is ready to merge. Protected branches can be configured to require approval rules to be satisfied before merging, making it impossible to bypass the review process even for maintainers.
In production, an e-commerce company managing checkout-service would configure a layered approval strategy. The base rule requires two approvals from anyone in the @checkout-team group. A CODEOWNERS rule requires approval from @security-team when files in src/payment/ or src/encryption/ are modified. Another CODEOWNERS rule requires @platform-team approval for changes to the Dockerfile, .gitlab-ci.yml, or Kubernetes manifests in k8s/. An additional rule requires @database-team approval when migration files in db/migrations/ are changed. This ensures that security-sensitive payment code is always reviewed by security engineers, infrastructure changes are reviewed by the platform team, and database schema changes are reviewed by DBAs, all without manual assignment. The approval requirements appear prominently in the MR widget, showing reviewers which rules they can satisfy.
A key gotcha is the order of pattern matching in CODEOWNERS. Like .gitignore, later entries override earlier ones. If you have a broad rule like * @default-team followed by *.go @backend-team, Go files will be owned by @backend-team only, not @default-team. Another common issue is using usernames instead of group names in CODEOWNERS; if an individual leaves the company, their CODEOWNERS entries become orphaned and no one can satisfy the approval requirement, blocking all MRs that touch those files. Always use group-based ownership for resilience. Also note that CODEOWNERS approval is a GitLab Premium feature; on the Free tier, CODEOWNERS is informational only.