In the previous nine sessions Patrick Steger and I built a GitLab DevSecOps pipeline that runs SAST, secret detection, software composition analysis, container scanning and DAST. Useful — but only if it actually catches issues before they reach the default branch. In Part 10 we close that loop: we wire the pipeline into Merge Requests so every change is scanned, the deltas against the default branch are visible, and approvals are required when new high or critical vulnerabilities appear.
Why Merge Requests Are the Real Gate#
Up to now we always committed straight to the default branch in our demos. That is fine for showing a tool, but it is not how anyone runs a real project. In real projects you have a branching strategy: you work on a feature branch and you eventually merge it back to the default branch. The question is what happens at that merge point.
GitLab’s answer is that the Merge Request itself is a security gate. It runs the full pipeline on the working branch, compares the security findings of that pipeline against the default branch, and reports the deltas — what is new, what disappeared. On top of that, you can define approvers for new critical or high vulnerabilities. Without their sign-off the merge is blocked.
The Workflow End to End#
The flow is the same one most teams already know, with security findings folded in:
- Create a feature branch for the issue or feature.
- Open a Merge Request right away — it does not have to be “ready.”
- Commit changes. The pipeline runs on every push and reports new security findings on the Merge Request.
- Review the code with the product owner and other developers. Discuss findings with developers and security experts.
- If a finding is a false positive, request approval to merge anyway.
- Merge, then delete the branch.
The point of opening the MR early is the same as in any modern team: discussion happens during development, not after.
What the MR Actually Looks Like in GitLab#
In the demo we open a prepared Merge Request with two changes: a Java class that introduces an insecure MessageDigest using MD5, and a Spring Boot upgrade from 2.7.2 to 2.7.4. Both are deliberate — one to trigger SAST, one to exercise SCA on changed dependencies.
Scrolling down to the Security Scanning section, the new findings are listed inline. Click the SAST finding “Inadequate encryption strength” and GitLab jumps to the exact line of code where MD5 is used. That is what a delta should look like — not a 200-page report, but “here is what this MR added.”
When everything is green and reviewed, the Merge button at the bottom does the work. The pipeline then re-runs on the default branch, because the default branch now has new code.
Configuring the Behaviour#
The interesting settings live under Settings → Merge Requests. Two areas matter for DevSecOps.
Merge checks. Enable “Pipelines must succeed”. This is exactly what it sounds like: a red pipeline blocks merging. We strongly recommend turning this on. It is the single line of defence between “the tools found something” and “the something is in main”.
Merge Request approvals. Further down, you define approval rules. We had a license-check rule with Patrick and me as approvers. Below that come the security approvals — the powerful piece. You define rules around new vulnerabilities: which severity, who must approve, how many approvals. If your organisation has a security department, give them the security approver role. They then see exactly what new risk a Merge Request brings in and can accept it, decline it, or ask questions before it lands in the default branch.
The configuration is extensive — almost overwhelming the first time you see it. The good news is that you only need a few rules to start: pipeline must succeed, plus security approval for new high and critical vulnerabilities.
Recap#
The Merge Request is where the GitLab DevSecOps pipeline stops being a passive scanner and becomes a gate. The pipeline runs on the feature branch, the security findings are diffed against the default branch and shown inline, and defined approvers must sign off when serious new vulnerabilities appear. With that wired up, the team gets fast feedback during development, security experts see only the changes that matter to them, and nothing critical lands in main without a deliberate human decision.
The next session is about scheduled pipelines — making sure that code already in production keeps getting checked, even when nobody is committing.
Key Takeaways#
The Merge Request is the gate, not the pipeline. A green pipeline on the default branch only tells you about the past. The gate is the MR pipeline diffed against main, with approvals enforced on the diff.
Open Merge Requests early. They are a discussion tool, not a final-submit form. Early MRs mean early reviews, early security feedback and fewer surprises right before the merge.
Show deltas, not totals. GitLab presents new versus existing findings on the Merge Request. Reviewers focus on what this change introduced, which is exactly what they can act on.
Turn on “Pipelines must succeed”. It is one checkbox in Settings → Merge Requests and it is the difference between “the scanner ran” and “the scanner blocked the merge”. Skip it and everything else is theatre.
Use security approval rules with intent. Configure them by severity (start with high and critical) and route them to the people who can actually make the call — typically a small security group, not every developer.
False positives need a documented escape hatch. A finding will eventually be wrong. The approval flow gives you a clean path: discuss it, get the approver to sign off, merge — without disabling the rule for everyone else.
