Generate approval notification when no scanners are present in the pipeline
## Why are we doing this work Currently we generate an approval notification in the form of a bot comment when there are scanners in the pipeline and the results are violating defined policies. We would like to create a notification also when there are no scanners in the pipeline, but policies enforce approvals. In addition to that, we should also cover a case when there is no pipeline configuration at all, as policies can still block MRs in these cases. Example: ![CleanShot_2023-07-11_at_15.57.20_2x](/uploads/2281e4e3c1495cba25537931fa018724/CleanShot_2023-07-11_at_15.57.20_2x.png) ## Implementation Plan * ~backend TODO: Add a feature flag ```diff diff --git a/ee/app/services/security/scan_result_policies/update_approvals_service.rb b/ee/app/services/security/scan_result_policies/update_approvals_service.rb index 7bbfe342940c..da3e04a63469 100644 --- a/ee/app/services/security/scan_result_policies/update_approvals_service.rb +++ b/ee/app/services/security/scan_result_policies/update_approvals_service.rb @@ -13,13 +13,22 @@ def initialize(merge_request:, pipeline:) end def execute + return if pipeline.pending? + approval_rules = merge_request.approval_rules.scan_finding return if approval_rules.empty? - violated_rules, unviolated_rules = partition_rules(approval_rules) + actual_scans = pipeline.security_scans.pluck(:scan_type) # rubocop: disable CodeReuse/ActiveRecord + + unenforceable_rules, enforceable_rules = approval_rules.partition do |approval_rule| + (approval_rule.scanners - actual_scans).any? + end + + violated_rules, unviolated_rules = partition_rules(enforceable_rules) ApprovalMergeRequestRule.remove_required_approved(unviolated_rules) if unviolated_rules.any? - generate_policy_bot_comment(violated_rules.any?) + + generate_policy_bot_comment(unenforceable_rules.any? || violated_rules.any?) end private diff --git a/ee/app/workers/security/scan_result_policies/sync_findings_to_approval_rules_worker.rb b/ee/app/workers/security/scan_result_policies/sync_findings_to_approval_rules_worker.rb index aacb1a630b6f..21694cb65a4b 100644 --- a/ee/app/workers/security/scan_result_policies/sync_findings_to_approval_rules_worker.rb +++ b/ee/app/workers/security/scan_result_policies/sync_findings_to_approval_rules_worker.rb @@ -15,7 +15,7 @@ class SyncFindingsToApprovalRulesWorker def perform(pipeline_id) pipeline = ::Ci::Pipeline.find_by_id(pipeline_id) - return unless pipeline && pipeline.can_store_security_reports? + return unless pipeline&.project&.can_store_security_reports? Security::ScanResultPolicies::SyncFindingsToApprovalRulesService.new(pipeline).execute end ``` ## Verification steps 1. Enable feature flag `security_policies_unenforceable_rules_notification` 1. Go to Secure -> Policies and create a new scan result policy. Sample YAML: ```yaml type: scan_result_policy name: Sec & Lic description: '' enabled: true rules: - type: scan_finding scanners: [] vulnerabilities_allowed: 0 severity_levels: [] vulnerability_states: [] branch_type: protected - type: license_finding match_on_inclusion: true license_types: - BSD 3-Clause "New" or "Revised" License license_states: - newly_detected branch_type: protected actions: - type: require_approval approvals_required: 1 role_approvers: - developer approval_settings: block_unprotecting_branches: true prevent_pushing_and_force_pushing: true ``` #### With no pipelines 1. In a project where there is no `.gitlab-ci.yml`, create any MR (e.g. update README) 2. Observe required approvals for `Sec & Lic` 3. Observe a policy bot comment being created 4. Change the target branch to a non-protected one (you can go to Code -> Branches and create a new branch from `main`) 5. The policy bot comment should be updated to say the violations have been resolved 6. Create a new MR targeting a non-protected branch from the beginning -> there should be no policy bot comment. Change the target branch to `main` and the bot comment should appear. #### With missing scanners 7. Create a `.gitlab-ci.yml` file and don't include dependency scanning. Sample YAML: ```yaml include: - template: Jobs/Secret-Detection.gitlab-ci.yml # - template: Jobs/Dependency-Scanning.gitlab-ci.yml build-job: script: - echo "Compiling the code..." - echo "Compile complete." ``` 8. Create MR and verify that bot comment is created and approvals should be still required after pipeline finishes #### With all scanners present 9. Update `.gitlab-ci.yml` again and include also the commented-out dependency scanning template. Add empty `requirements.txt` file in the repo. 10. Create another MR. There should be no policy bot comment and no required approvals after pipeline finishes. ## Relevant links - https://gitlab.com/groups/gitlab-org/-/epics/10617#note_1461481878
issue