Add a CODEOWNERS entry for .gitlab-ci.yml, protect the target branch, and turn on required approval from code owners. Then limit who may push directly, because anyone with push permission can skip the merge request, and with it the code owner approval.
Why the pipeline file needs an owner
Whoever edits .gitlab-ci.yml decides what code runs with your runners and variables. A one line change can add a step that sends a secret elsewhere. A pipeline file deserves at least the review a production source file gets, from people who understand what runs.
How GitLab applies code owners
When a merge request changes files, GitLab compares them to the CODEOWNERS file on the target branch. Files matching no rule need no owner approval. To cover everything, add a * entry at the top, and later more specific entries override it, since the last matching entry wins. GitLab checks ./CODEOWNERS, then ./docs/CODEOWNERS, then ./.gitlab/CODEOWNERS, and uses the first it finds.
Steps
- Create a team or group that understands your delivery pipeline, for example platform and security staff.
- Add rules for the pipeline and its helpers.
- Protect the target branch and enable "Require approval from code owners."
- Set Allowed to push to no one, or a very small group, so changes go through merge requests.
- Test it: open a merge request that edits the file and confirm approval is demanded.
# CODEOWNERS
.gitlab-ci.yml @platform-team
/ci/ @platform-team
/.gitlab/ @platform-team @security-team
The group names are examples.
The gap to close
GitLab's documentation states that changes from users without Allowed to push permission must go through a merge request. The reverse is the catch: users with push permission can skip merge requests, and so skip code owner approval. If pipeline changes must always be reviewed, restrict that permission. See the protected branches setup guide and approval rules hardening.
What reviewers should look for
Train owners to read pipeline changes with a short list in mind: new script lines that call out to a network address, changed image lines, added include entries, changes to rules that skip security jobs, new variables that print or echo values, and runner tags that move a job to a different host. A change that looks like tidying can still weaken a gate, so a second pair of eyes helps.
Do not forget included files
If your pipeline pulls in other files, list them too, and pin remote includes. A pipeline that includes a file from a project you do not control is only as safe as that project. See project versus remote includes.
Try it yourself
Click through it at your own pace, or open it full screen. Look at what blocks the merge and who can override it.
Safeguard's policies and gates can add automated checks on a change request alongside human review, and a free scan is at https://gold.safeguard.sh/scan.
Quick check
Is a CODEOWNERS file enough alone?
No. The branch must be protected and owner approval must be required, or the file only shows names.
Where do I put the file?
In the repository root, docs, or .gitlab folder. GitLab uses the first one it finds.
Sources
- GitLab Docs: Code Owners, fetched 19 October 2026. The
.gitlab-ci.ymlrule is an application of the documented model, not an example from the page.
Last reviewed: 19 October 2026.