Stop deleting merged MRs merge request approval rules when deleting a scan policy
Summary
When testing the new approval rules work I noticed that when we delete a security rule we also delete all the approval rules related to it, regardless of if the merge request is merged or not. This is a problem because we should keep the approval rules post merge for compliance reasons https://gitlab.com/gitlab-org/gitlab/-/blob/fa6287ba9f7feaba94127a8ef9a494600ce0a067/ee/app/models/concerns/security/scan_result_policy.rb#L34
Steps to reproduce
Example Project
What is the current bug behavior?
When Scan Result Policy is updated or deleted MR approval rules are deleted for merged MRs.
What is the expected correct behavior?
When Scan Result Policy is updated or deleted MR approval rules should not be deleted for merged MRs.
Relevant logs and/or screenshots
Output of checks
Results of GitLab environment info
Expand for output related to GitLab environment info
(For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:env:info`) (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
Results of GitLab application Check
Expand for output related to the GitLab application check
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:check SANITIZE=true
)(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true
)(we will only investigate if the tests are passing)
Possible fixes
-
MR1: in https://gitlab.com/gitlab-org/gitlab/-/blob/fa6287ba9f7feaba94127a8ef9a494600ce0a067/ee/app/models/concerns/security/scan_result_policy.rb#L34 modify query to delete them for unmerged MRs only:
def delete_scan_finding_rules
delete_in_batches(approval_merge_request_rules.for_unmerged_merge_requests)
delete_in_batches(approval_project_rules)
end
-
ApprovalMergeRequestRule
has foreign key onscan_result_policy_id
. We delete and recreateScanResultPolicyRead
whenever policy is updated, so deleting them would removeApprovalMergeRequestRule
too. Soscan_result_policy_id
should be nullified inapproval_merge_request_rules
for merged MRs.
Verification steps
- Create a new project
- Make sure the project has at least one other member with developer access
- Add a
.gitlab-ci.yml
file with the content
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
- Add an empty
Gemfile.lock
file - Go to Secure > Policies.
- Click on New Policy.
- Select Scan result policy.
- Change to yaml mode and copy the yaml content below, adjusting the user_approvers_ids as needed:
type: scan_result_policy
name: Deny new MIT licensed dependencies
description:
enabled: true
actions:
- type: require_approval
approvals_required: 1
user_approvers_ids:
- 49
rules:
- type: license_finding
match_on_inclusion: true
license_types:
- MIT
license_states:
- newly_detected
branch_type: protected
-
Click on Configure with a merge request
-
Merge the new MR to add the new policy.
-
Create a new MR
-
Check the approval rules in the database. Adjust the
target_project_id
andiid
according to your project and MR:
SELECT id, name, scan_result_policy_id FROM approval_merge_request_rules WHERE merge_request_id = (SELECT id FROM merge_requests WHERE target_project_id = 1 AND iid = 1);
Check the id of approval_merge_request_rules
linked to a scan_result_policy
.
id | name | scan_result_policy_id
-----------+------------------------------------+-----------------------
1 | Deny new MIT licensed dependencies | 17
-
Merge the MR
-
Make sure the MR is marked as merged in the database. The state_id should 3(merged)
SELECT state_id FROM merge_requests WHERE target_project_id = 1 AND iid = 1;
state_id
----------
3
- Go to Secure > Policies.
- Update the policy description
- Verify the approvals for the merged MR was not deleted and the previous linked
scan_result_policy
was nullified.
id | name | scan_result_policy_id
-----------+------------------------------------+-----------------------
1 | Deny new MIT licensed dependencies |