Compliance violations report flags MRs auto-merged via another MR as unapproved, misattributing the violation
Summary
When an open merge request's commits are already present in the target branch because a different MR was merged first, GitLab automatically transitions the first MR to merged (see Merged as part of a different merge request, #436061 (closed), #456426).
The compliance-violation pipeline does not know about this state transition. ComplianceManagement::MergeRequests::CreateComplianceViolationsService runs MergeRequests::ComplianceViolation.process_merge_request for every merge request where merged? is true — regardless of how it became merged — and each check in MergeRequests::ComplianceViolation::VIOLATIONS (ApprovedByMergeRequestAuthor, ApprovedByCommitter, ApprovedByInsufficientUsers) evaluates only the MR's own approved_by_users:
# ee/lib/gitlab/compliance_management/violations/approved_by_insufficient_users.rb
def violation?
@merge_request.approved_by_users.count < MINIMUM_NUMBER_OF_APPROVERS
endBecause the auto-merged MR was never itself reviewed (the equivalent code was reviewed and approved on the other MR), it has 0 approvals of its own, and the compliance pipeline creates a "Fewer than two approvals" violation (severity: High) exactly as it would for a genuine policy bypass. The violation is also misattributed:
violating_user: @merge_request.metrics&.merged_by || @merge_request.merge_user,merge_user on the auto-merged MR is set to the user who merged the other MR (per UpdateMergeRequestsWorker), so a user who took no merge action on this MR is recorded as the violator.
This produces a false-positive compliance/audit finding that is functionally indistinguishable from a genuine approval-policy bypass, even though the code was reviewed, approved, and scanned before entering the protected branch — just via a different MR.
Steps to reproduce
- Create MR A and MR B against the same protected target branch, where MR B's branch contains a subset of commits also present in MR A (e.g., B was branched from A, or both contain an identical cherry-picked commit).
- Get MR A fully approved (satisfying
minimum_approvals_required_2/ 2 approvals) and merge it. Do not directly approve or merge MR B. - Observe MR B automatically transition to
mergedshortly after, because its commit(s) are now contained in the target branch. - Check Secure > Compliance center > Violations (or the
compliance_violationsdata) for the project/group.
Actual behavior
MR B appears in the compliance violations report as a "Fewer than two approvals" (and potentially "Committers approved merge request") violation, with the violating user set to whoever merged MR A — even though MR A had full, valid approvals and a passing pipeline before merging.
Expected behavior
When a merge request is auto-transitioned to merged as a consequence of another MR merging first, the compliance-violation pipeline should either:
- Not create a violation record for the auto-merged MR when the MR that actually introduced the commits satisfied the applicable approval rules, and instead associate the audit evidence with that originating MR, or
- Clearly distinguish/flag the violation as arising from an automatic state transition rather than an actual merge action, and not attribute it to a user who took no action on the affected MR.
Why this is a distinct defect from #456426 and #512551
- #456426 ("Merged system notes displayed as manually merged when it is not") is scoped to the system note / activity feed text shown for the auto-merged MR. Fixing it does not touch
MergeRequests::ComplianceViolationor any compliance/audit data — the violation record described above would still be created and misattributed even with a perfectly worded system note. - #512551 ("Improve reporting for when a merge request is merged via another MR") proposes exposing
source_commit_id/source_merge_request_idon the Resource State Events API. That's a necessary building block for attribution, but by itself doesn't change whether/howComplianceManagement::MergeRequests::CreateComplianceViolationsServicecreates or attributes a violation.
This issue tracks fixing the compliance/audit-attribution behavior specifically. It's related to both.
Business impact
Customers relying on the Compliance Violations report / MR approval policies as audit evidence (SOC 2, internal governance, etc.) see this as a false positive suggesting protected code was merged without approval, when in fact it went through a fully approved and scanned MR. This requires manual forensic investigation per occurrence and erodes confidence in the compliance tooling. Multiple Support tickets from Ultimate customers have raised this (see #456426 for linked internal references).