BE: Support component filtering options for Scan Result Policies
Implementation Plan
-
Update security_orchestration_policy.json JSON schema to add definition for component attribute
"components": {
"type": "array",
"description": "Specifies the components to match.",
"minItems": 1,
"uniqueItems": true,
"additionalItems": false,
"items": {
"type": "string",
"minLength": 1
}
},
"match_on_inclusion_component": {
"type": "boolean",
"description": "Specifies whether to match components on inclusion or exclusion."
},
===================================================================
diff --git a/ee/app/validators/json_schemas/security_orchestration_policy.json b/ee/app/validators/json_schemas/security_orchestration_policy.json
--- a/ee/app/validators/json_schemas/security_orchestration_policy.json (revision 6e5357b9e6289ba7857f8141e42f54b393779952)
+++ b/ee/app/validators/json_schemas/security_orchestration_policy.json (date 1694119660540)
@@ -521,6 +521,21 @@
"any",
"unsigned"
]
+ },
+ "components": {
+ "type": "array",
+ "description": "Specifies the components to match.",
+ "minItems": 1,
+ "uniqueItems": true,
+ "additionalItems": false,
+ "items": {
+ "type": "string",
+ "minLength": 1
+ }
+ },
+ "match_on_inclusion_component": {
+ "type": "boolean",
+ "description": "Specifies whether to match components on inclusion or exclusion."
}
},
"oneOf": [
-
Add components columns to scan_result_policies
table MR.
components text[] DEFAULT '{}'::text[],
match_on_inclusion_component boolean,
-
Add a method in Security::ScanResultPolicyRead
to return the components attributes.
def components
return {} unless components.present? && match_on_inclusion_component.present?
{ components_list: components, match_on_inclusion: match_on_inclusion_component }
end
-
Add a method toGitlab::Ci::Reports::LicenseScanning::Report
to get the components from the license scanning report.
def components
found_licenses.values.flat_map { |license| license.dependencies.flat_map { |dependency| "#{dependency.name} (#{dependency.version})" } }.uniq
end
get the package names using this method.
-
Update Security::SyncLicenseScanningRulesService
to consider component attributes.
Index: ee/app/services/security/sync_license_scanning_rules_service.rb
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/ee/app/services/security/sync_license_scanning_rules_service.rb b/ee/app/services/security/sync_license_scanning_rules_service.rb
--- a/ee/app/services/security/sync_license_scanning_rules_service.rb (revision d5e0068910b948fd9c921dbcbb0091b5d22e70c9)
+++ b/ee/app/services/security/sync_license_scanning_rules_service.rb (date 1695230565357)
@@ -44,7 +44,7 @@
return if license_approval_rules.empty?
violated_rules, unviolated_rules = license_approval_rules.partition do |rule|
- violates_policy?(merge_request, rule)
+ violates_policy?(merge_request, rule) || violates_components_policy(rule)
end
update_required_approvals(merge_request, violated_rules, unviolated_rules)
@@ -90,6 +90,25 @@
violates_license_policy
end
+ def violates_components_policy(rule)
+ scan_result_policy_read = rule.scan_result_policy_read
+
+ components_on_report = report.dependency_names
+
+ components_to_check = scan_result_policy_read.components[:components_list]
+
+ return false unless components_on_report && components_to_check
+
+ check_specific_components = scan_result_policy_read.components[:match_on_inclusion]
+
+ if check_specific_components # components that cannot be present on the report
+ components_to_check.any? { |component| components_on_report.include?(component) }
+ else
+ # components that can be present on the report
+ (components_on_report - components_to_check).present?
+ end
+ end
+
def licenses_to_check(target_branch_report, scan_result_policy_read)
only_newly_detected = scan_result_policy_read.license_states == [ApprovalProjectRule::NEWLY_DETECTED]
Verification steps
Edited by Marcos Rocha