Require/remove approvals earlier when Scan Result Policy is enforced based on pre-existing vulnerabilities
Why are we doing this work
We want to be able to require/remove approvals when we are checking for pre-existing vulnerabilities. Some customers have configured their pipelines to run security scans in schedule pipelines or with scheduled scan execution policies. We want to give them opportunity to block MR that violates their Scan Result Policies based on pre-existing findings. This issue addresses this problem.
Relevant links
Non-functional requirements
-
Documentation: -
Feature flag: Add feature flag to be able to enable/disable this behavior (default: false
) -
Performance: -
Testing: - [ ]
Implementation plan
-
backend add new scope scope :without_newly_detected_vulnerability_state, -> { where.not("'newly_detected' = ANY (vulnerability_states)") }
to/ee/app/models/concerns/approval_rule_like.rb
to get approval rules withoutnewly_detected
state invulnerability_states
column, -
backend in /ee/app/services/ci/sync_reports_to_approval_rules_service.rb
addremove_required_approvals_for_scan_finding_with_preexising_findings
method to remove required approvals for scan findings with pre-existing finding:def remove_required_approvals_for_scan_finding_with_preexising_findings(merge_requests) merge_requests.each do |merge_request| base_reports = merge_request.latest_pipeline_for_target_branch&.security_reports scan_finding_rules = merge_request.approval_rules.scan_finding.without_newly_detected_vulnerability_state selected_rules = scan_finding_rules.reject do |rule| violates_default_policy?(rule, base_reports) end scan_finding_rules.remove_required_approved(selected_rules) end end
-
backend in /ee/app/services/ci/sync_reports_to_approval_rules_service.rb
updatesync_scan_finding
method to initiateremove_required_approvals_for_scan_finding_with_preexising_findings(pipeline.merge_requests_as_head_pipeline.opened)
before checking if reports in pipeline are empty or if pipeline is completed, -
backend in /ee/lib/ee/gitlab/ci/reports/security/reports.rb
addpreexisting_findings_count
method to count findings that are preexisting on target branch:def preexisting_findings_count(target_reports, severity_levels, vulnerability_states, report_types) pipeline_uuids = target_reports&.unsafe_findings_uuids(severity_levels, report_types).to_a count_by_uuid(pipeline_uuids, vulnerability_states) end
-
backend in /ee/lib/ee/gitlab/ci/reports/security/reports.rb
overrideviolates_default_policy_against?
method to include checking if pre-existing vulnerabilities are causing scan result policy to require approval:override :violates_default_policy_against? def violates_default_policy_against?(target_reports, vulnerabilities_allowed, severity_levels, vulnerability_states, report_types = []) return true if !vulnerability_states.include?(ApprovalProjectRule::NEWLY_DETECTED) && preexisting_findings_count(target_reports, severity_levels, vulnerability_states, report_types) > vulnerabilities_allowed super end
-
backend feature flag Add feature flag to be able to enable/disable this feature quickly,
Verification steps
-
Create new project -
Add .gitlab-ci.yml
file that includes detached pipeline:container_scanning: image: "busybox:latest" stage: test allow_failure: true artifacts: reports: container_scanning: gl-container-scanning-report.json paths: [gl-container-scanning-report.json] dependencies: [] script: - wget -O gl-container-scanning-report.json https://gitlab.com/-/snippets/2438327/raw/main/gl-container-scanning-report-1-critical.json?inline=false rules: - if: $RUN_MANUALY other_job: image: busybox:latest stage: test script: - echo "This is other branch"
-
Add Scan Result Policy (go to Security & Compliance -> Policies
), clickNew Policy
, selectScan Result Policies
and add new policy and merge created MR:name: Enforce check when there is at least 1 critical description: '' enabled: true actions: - type: require_approval approvals_required: 1 group_approvers_ids: - # add your group ID rules: - type: scan_finding branches: [] scanners: [] vulnerabilities_allowed: 0 severity_levels: - critical vulnerability_states: - detected
-
Run pipeline manually and set RUN_MANUALY
variable to"true"
-
Add new MR with some change, unrelated to .gitlab-ci.yml
file: -
Verify if approvals in the MR are required
Edited by Alan (Maciej) Paruszewski