From f34063573003695f3f9c971b2c3797f1a991da51 Mon Sep 17 00:00:00 2001 From: Santiago Arboleda A Date: Wed, 20 May 2026 17:02:43 -0500 Subject: [PATCH 1/3] feat: enhance exclusion handling with pattern search support in IacScan --- .../engine_sast/engine_iac/Exclusions.json | 19 +++ .../src/domain/usecases/iac_scan.py | 20 ++-- .../test/domain/usecases/test_iac_scan.py | 108 ++++++++++++++++++ 3 files changed, 140 insertions(+), 7 deletions(-) mode change 100644 => 100755 example_remote_config_local/engine_sast/engine_iac/Exclusions.json mode change 100644 => 100755 tools/devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/iac_scan.py mode change 100644 => 100755 tools/devsecops_engine_tools/engine_sast/engine_iac/test/domain/usecases/test_iac_scan.py diff --git a/example_remote_config_local/engine_sast/engine_iac/Exclusions.json b/example_remote_config_local/engine_sast/engine_iac/Exclusions.json old mode 100644 new mode 100755 index 782b421a5..9fdad603c --- a/example_remote_config_local/engine_sast/engine_iac/Exclusions.json +++ b/example_remote_config_local/engine_sast/engine_iac/Exclusions.json @@ -27,5 +27,24 @@ "hu": "4338704" } ] + }, + "BY_PATTERN_SEARCH": { + ".*_Repository_Test": { + "SKIP_TOOL": { + "create_date": "24012024", + "expired_date": "30012024", + "hu": "3423213" + }, + "CHECKOV": [ + { + "id": "CKV_K8S_24", + "where": "all", + "create_date": "18112023", + "expired_date": "18032024", + "severity": "HIGH", + "hu": "4338704" + } + ] + } } } \ No newline at end of file diff --git a/tools/devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/iac_scan.py b/tools/devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/iac_scan.py old mode 100644 new mode 100755 index 71716f5b7..030a39850 --- a/tools/devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/iac_scan.py +++ b/tools/devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/iac_scan.py @@ -111,13 +111,19 @@ def _complete_config_tool(self, data_file_tool, exclusions, tool, dict_args): if config_tool.exclusions.get("All") is not None: config_tool.exclusions_all = config_tool.exclusions.get("All").get(tool) - if config_tool.exclusions.get(config_tool.scope_pipeline) is not None: - config_tool.exclusions_scope = config_tool.exclusions.get( - config_tool.scope_pipeline - ).get(tool) - skip_tool = bool( - config_tool.exclusions.get(config_tool.scope_pipeline).get("SKIP_TOOL") - ) + + exclusions_scope = config_tool.exclusions.get(config_tool.scope_pipeline) + if exclusions_scope is None: + for pattern, values in config_tool.exclusions.get( + "BY_PATTERN_SEARCH", {} + ).items(): + if re.match(pattern, config_tool.scope_pipeline, re.IGNORECASE): + exclusions_scope = values + break + + if exclusions_scope is not None: + config_tool.exclusions_scope = exclusions_scope.get(tool) + skip_tool = bool(exclusions_scope.get("SKIP_TOOL")) if dict_args["folder_path"]: if ( diff --git a/tools/devsecops_engine_tools/engine_sast/engine_iac/test/domain/usecases/test_iac_scan.py b/tools/devsecops_engine_tools/engine_sast/engine_iac/test/domain/usecases/test_iac_scan.py old mode 100644 new mode 100755 index b83d9135d..edd886b72 --- a/tools/devsecops_engine_tools/engine_sast/engine_iac/test/domain/usecases/test_iac_scan.py +++ b/tools/devsecops_engine_tools/engine_sast/engine_iac/test/domain/usecases/test_iac_scan.py @@ -92,6 +92,7 @@ def test_process_skip_search_folder(self): "folder_path": "example_folder", "environment": "test", "platform": "eks", + "token_external_checks": "token", } secret_tool = "example_secret" tool = "CHECKOV" @@ -173,3 +174,110 @@ def test_process_skip_search_folder(self): # Assert the expected return values self.assertEqual(findings_list, []) self.assertIsNotNone(input_core) + + def test_process_skip_search_folder_by_pattern_search(self): + dict_args = { + "remote_config_repo": "example_repo", + "remote_config_branch": "", + "folder_path": "example_folder", + "environment": "test", + "platform": "eks", + "token_external_checks": "token", + } + secret_tool = "example_secret" + tool = "CHECKOV" + + self.remote_config_source_gateway.get_remote_config.side_effect = [ + { + "SEARCH_PATTERN": ["AW", "NU"], + "IGNORE_SEARCH_PATTERN": "(.*_test)", + "EXCLUSIONS_PATH": "Exclusions.json", + "MESSAGE_INFO_ENGINE_IAC": "message test", + "UPDATE_SERVICE_WITH_FILE_NAME_CFT": "false", + "THRESHOLD": { + "VULNERABILITY": { + "Critical": 10, + "High": 3, + "Medium": 20, + "Low": 30, + }, + "COMPLIANCE": {"Critical": 4}, + "PRIORITY": { + "Very Critical": 1, + "Critical": 3, + "High": 5, + "Medium Low": 15, + }, + }, + "CHECKOV": { + "VERSION": "2.3.296", + "USE_EXTERNAL_CHECKS_GIT": "True", + "EXTERNAL_CHECKS_GIT": "rules", + "EXTERNAL_GIT_SSH_HOST": "github", + "EXTERNAL_GIT_PUBLIC_KEY_FINGERPRINT": "fingerprint", + "USE_EXTERNAL_CHECKS_DIR": "False", + "EXTERNAL_DIR_OWNER": "test", + "EXTERNAL_DIR_REPOSITORY": "repository", + "RULES": "", + }, + }, + { + "All": { + "CHECKOV": [ + { + "id": "CKV_K8S_8", + "where": "all", + "create_date": "18112023", + "expired_date": "18032024", + "severity": "HIGH", + "hu": "4338704", + } + ] + }, + "BY_PATTERN_SEARCH": { + ".*example_pipeline": { + "THRESHOLD": { + "VULNERABILITY": { + "Critical": 1, + "High": 2, + "Medium": 3, + "Low": 4, + }, + "COMPLIANCE": {"Critical": 1}, + "PRIORITY": { + "Very Critical": 1, + "Critical": 1, + "High": 1, + "Medium Low": 1, + }, + }, + "SKIP_TOOL": { + "create_date": "24012024", + "expired_date": "30012024", + "hu": "3423213", + }, + "CHECKOV": [ + { + "id": "CKV_K8S_9", + "where": "deployment-configmap.yaml", + "create_date": "18112023", + "expired_date": "18032024", + "severity": "HIGH", + "hu": "4338704", + } + ], + } + }, + }, + ] + + self.devops_platform_gateway.get_variable.return_value = "example_pipeline" + self.tool_gateway.run_tool.return_value = ([], None) + + findings_list, input_core = self.iac_scan.process(dict_args, secret_tool, tool, "qa") + + self.assertEqual(findings_list, []) + self.assertEqual(len(input_core.totalized_exclusions), 2) + self.assertEqual(input_core.totalized_exclusions[0].id, "CKV_K8S_8") + self.assertEqual(input_core.totalized_exclusions[1].id, "CKV_K8S_9") + self.tool_gateway.run_tool.assert_not_called() From 2ba821b5dab3940cc14d7f070353b831a0608dc7 Mon Sep 17 00:00:00 2001 From: Santiago Arboleda A Date: Thu, 21 May 2026 10:00:18 -0500 Subject: [PATCH 2/3] feat: add threshold configuration for vulnerability and compliance in BY_PATTERN_SEARCH --- .../engine_sast/engine_iac/Exclusions.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/example_remote_config_local/engine_sast/engine_iac/Exclusions.json b/example_remote_config_local/engine_sast/engine_iac/Exclusions.json index 9fdad603c..b98924bb1 100755 --- a/example_remote_config_local/engine_sast/engine_iac/Exclusions.json +++ b/example_remote_config_local/engine_sast/engine_iac/Exclusions.json @@ -30,6 +30,23 @@ }, "BY_PATTERN_SEARCH": { ".*_Repository_Test": { + "THRESHOLD": { + "VULNERABILITY": { + "Critical": 1, + "High": 4, + "Medium": 10, + "Low": 15 + }, + "COMPLIANCE": { + "Critical": 1 + }, + "PRIORITY": { + "Very Critical": 1, + "Critical": 4, + "High": 10, + "Medium Low": 15 + } + }, "SKIP_TOOL": { "create_date": "24012024", "expired_date": "30012024", From 474228266f4db6ad9ad574ec99d7547572abfeb5 Mon Sep 17 00:00:00 2001 From: Santiago Arboleda A Date: Thu, 21 May 2026 10:07:21 -0500 Subject: [PATCH 3/3] feat: add BY_PATTERN_SEARCH configuration for regex-based exclusions and threshold overrides --- .../docs/modules/engine_sast/engine_iac.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) mode change 100644 => 100755 docs/Docusaurus/docs/modules/engine_sast/engine_iac.md diff --git a/docs/Docusaurus/docs/modules/engine_sast/engine_iac.md b/docs/Docusaurus/docs/modules/engine_sast/engine_iac.md old mode 100644 new mode 100755 index 3b298ce5d..90438dd44 --- a/docs/Docusaurus/docs/modules/engine_sast/engine_iac.md +++ b/docs/Docusaurus/docs/modules/engine_sast/engine_iac.md @@ -294,6 +294,42 @@ Defines exclusion rules for repositories and specific security checks. "hu": "4338704" } ] + }, + "BY_PATTERN_SEARCH": { + ".*_Repository_Test": { + "THRESHOLD": { + "VULNERABILITY": { + "Critical": 1, + "High": 4, + "Medium": 10, + "Low": 15 + }, + "COMPLIANCE": { + "Critical": 1 + }, + "PRIORITY": { + "Very Critical": 1, + "Critical": 4, + "High": 10, + "Medium Low": 15 + } + }, + "SKIP_TOOL": { + "create_date": "24012024", + "expired_date": "30012024", + "hu": "3423213" + }, + "CHECKOV": [ + { + "id": "CKV_K8S_24", + "where": "all", + "create_date": "18112023", + "expired_date": "18032024", + "severity": "HIGH", + "hu": "4338704" + } + ] + } } } ``` @@ -301,7 +337,9 @@ Defines exclusion rules for repositories and specific security checks. #### Exclusion Types - **All**: Global exclusions applied to all repositories - **Repository-specific**: Exclusions for specific repositories +- **BY_PATTERN_SEARCH**: Regex-based exclusions for matching multiple pipeline names - **SKIP_TOOL**: Complete tool bypass for a repository +- **THRESHOLD**: Optional threshold override by repository or pattern (VULNERABILITY, COMPLIANCE, PRIORITY) - **Rule-specific**: Exclusions for specific security rules with: - `id`: Security rule identifier - `where`: File or location scope ("all" for global)