Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8e2765a
docs(docs): add new scan tool documentation in docusaurus
Sep 5, 2025
0708309
feat(config_local): add example of kiuwan configuration to remote con…
Sep 5, 2025
ceb7c12
feat(engine_core): add parameters to kiuwan scan tool
Sep 5, 2025
900773d
feat(engine_core): add engine code finding class
Sep 5, 2025
2eb8949
feat(engine_core): add config to break_build to manage flow with engi…
Sep 5, 2025
426719e
feat(engine_core): add custom variable to manage application type
Sep 5, 2025
1512403
feat(engine_core): add config to send vuls of kiuwan scan to defectdojo
Sep 5, 2025
0f8b843
feat(engine_core): add config of customs variables to github actions
Sep 5, 2025
3a1566f
feat(engine_core): add logic to display findings found by kiuwan anal…
Sep 5, 2025
760ca5b
feat(engine_core): add custom variable to runtime_local
Sep 5, 2025
3bb1ed1
test(engine_core): update test to used new kiuwan logic
Sep 5, 2025
aa9ed8c
test(engine_core): update test of break build due to new kiuwan logic
Sep 5, 2025
8db1630
test(engine_dast): fix test nuclei
Sep 5, 2025
b55aa11
test(engine_dast): fix test nuclei
Sep 5, 2025
2054348
feat(engince_code): add logic to manage kiuwan instance creation
Sep 5, 2025
d5b7049
refactor(engine_code): add docstrings and type hint in abc class
Sep 5, 2025
6b6f99a
refactor(engince_code): refactor code_scan and add logic to manage fl…
Sep 5, 2025
d0213f8
feat(engince_code): change class use by bearer_deserealizator
Sep 5, 2025
7c0e8bd
test(engine_code): update code scan test due new tool kiuwan
Sep 5, 2025
682c464
refactor(engine_secret): refactor code to manage windows path in a su…
Sep 5, 2025
0843c1c
feat(engine_utilities): add new variable to manage kiuwan scan tool i…
Sep 5, 2025
0868578
feat(engine_utilities): add new variable to manage kiuwan scan tool i…
Sep 5, 2025
48b2db1
feat(engine_code): add logic of kiuwan scan tool, analysis and manag…
Sep 5, 2025
6c63d8e
test(engine_code): add test of kiuwan scan tool
Sep 5, 2025
9abf5bc
fix(engine_code): fix getting config tool and exclusions log
Sep 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/Docusaurus/docs/life_cycle/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,14 @@ For more information about structure remote config visit [Structure Remote Confi
<td>Free</td>
</tr>
<tr>
<td>ENGINE_CODE</td>
<td rowspan="2">ENGINE_CODE</td>
<td><a href="https://docs.bearer.com/quickstart/">BEARER</a></td>
<td>Free</td>
</tr>
<tr>
<td><a href="https://support.kiuwan.com/hc/en-us">KIUWAN</a></td>
<td>Paid</td>
</tr>
</table>

### Scan running - (CLI) - Flags
Expand Down
2 changes: 1 addition & 1 deletion docs/Docusaurus/docs/life_cycle/remote_config_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Configuration of the driven adapters in the main layer and management of on/off
},
"ENGINE_CODE": {
"ENABLED": true,
"TOOL": "BEARER"
"TOOL": "BEARER|KIUWAN"
},
"ENGINE_RISK": {
"ENABLED": false
Expand Down
21 changes: 18 additions & 3 deletions docs/Docusaurus/docs/modules/engine_sast/engine_code.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The `engine_code` module is responsible for orchestrating Static Application Sec

## Main Responsibilities

- **SAST Orchestration:** Executes SAST tools (e.g., Bearer) on source code and pull requests.
- **SAST Orchestration:** Executes SAST tools (e.g., Bearer, Kiuwan) on source code and pull requests.
- **Configuration Management:** Loads and processes scan configurations and exclusions from remote repositories.
- **Pull Request Analysis:** Identifies and filters files changed in pull requests for targeted scanning.
- **Exclusions Management:** Applies exclusion rules based on configuration and DevSecOps policy.
Expand All @@ -17,7 +17,7 @@ The `engine_code` module is responsible for orchestrating Static Application Sec
- `runner_engine_code.py`: Main entry point for SAST scan orchestration.
- `entry_point_tool.py`: Initializes the SAST engine and triggers the scan process.
- `code_scan.py`: Core use case for executing the scan, handling configuration, exclusions, and result aggregation.
- **Adapters:** Integrations for SAST tools (Bearer) and Git operations.
- **Adapters:** Integrations for SAST tools (Bearer, Kiuwan) and Git operations.

## Supported Tools and Features

Expand All @@ -26,6 +26,11 @@ The `engine_code` module is responsible for orchestrating Static Application Sec
- **Configurable Exclusions:** Supports exclusion of files/folders and custom ignore patterns.
- **Thresholds and Policies:** Handles custom thresholds and build-breaking policies.

- **Kiuwan:** Aditional SAST tool for scanning source code for security issues and compliances.
- **Pull Request Scanning:** Supports scanning files changed in pull requests and files in a "folder_path" directory.
- **Configurable Exclusions:** Supports exclusion of files/folders and custom ignore patterns.
- **Thresholds and Policies:** Handles custom thresholds and build-breaking policies.

## Example Usage

The SAST engine is typically invoked as part of the overall DevSecOps pipeline, after code changes are detected:
Expand All @@ -40,11 +45,21 @@ devsecops-engine-tools \
--folder_path path/to/source
```

```sh
devsecops-engine-tools \
--platform_devops azure \
--remote_config_source azure \
--remote_config_repo my-org/devsecops-config \
--module engine_code \
--tool kiuwan \
--folder_path path/to/source
```

## Extensibility

- New SAST tools or exclusion policies can be added by extending the adapters and use cases.
- Supports integration with various version control and CI/CD platforms.

## Testing

- Unit tests are provided in the `test/` directory, covering orchestration logic, configuration parsing, and exclusion handling.
- Unit tests are provided in the `test/` directory, covering orchestration logic, configuration parsing, and exclusion handling.
2 changes: 1 addition & 1 deletion example_remote_config_local/engine_core/ConfigTool.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
},
"ENGINE_CODE": {
"ENABLED": true,
"TOOL": "BEARER"
"TOOL": "BEARER|KIUWAN"
},
"ENGINE_RISK": {
"ENABLED": false
Expand Down
64 changes: 46 additions & 18 deletions example_remote_config_local/engine_sast/engine_code/ConfigTool.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,50 @@
{
"IGNORE_SEARCH_PATTERN": [
".git"
],
"EXCLUDE_FOLDER": [],
"MESSAGE_INFO_ENGINE_CODE": "engine_code run successfully",
"THRESHOLD": {
"VULNERABILITY": {
"Critical": 999,
"High": 999,
"Medium": 999,
"Low": 999
},
"COMPLIANCE": {
"Critical": 0
}
"IGNORE_SEARCH_PATTERN": [
".git"
],
"EXCLUDE_FOLDER": [],
"MESSAGE_INFO_ENGINE_CODE": "test message",
"THRESHOLD": {
"VULNERABILITY": {
"Critical": 999,
"High": 999,
"Medium": 999,
"Low": 999
},
"BEARER": {
"NUMBER_THREADS": 4
"COMPLIANCE": {
"Critical": 999
}
},
"TARGET_BRANCHES": [
"trunk",
"develop"
],
"BEARER": {
"NUMBER_THREADS": 4
},
"KIUWAN": {
"SERVER": {
"BASE_URL": "https://api.kiuwan.com",
"USER": "user",
"DOMAIN_ID": "12345678910111213141516171819"
},
"TARGET_BRANCHES": ["trunk", "develop"]
"MODELOS": {
"Maven": "Reglas Java",
"Gradle": "Reglas Java",
"Npm": "Reglas Node",
"Python": "Reglas Python",
"Angular": "Reglas Angular",
".Net": "ReglasNet",
"PHP": "PHP Symfony",
"General": "CQM",
"OWASP": "OWASP-benchmark"
},
"SEVERITY": {
"Very High": "critical",
"High": "high",
"Normal": "medium",
"Low": "low",
"Very Low": "low"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
"severity": "Low",
"hu": "0000000"
}
],
"KIUWAN": [
{
"id": "test_id",
"where": "all",
"create_date": "18112023",
"expired_date": "18032024",
"severity": "Low",
"hu": "0000000"
}
]
},
"Repository_Test": {
Expand All @@ -22,5 +32,17 @@
"hu": "0000000"
}
]
},
"Repository_Test_2": {
"KIUWAN": [
{
"id": "35278412059",
"where": "all",
"create_date": "01082025",
"expired_date": "10082025",
"severity": "high",
"hu": "0000000"
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from devsecops_engine_tools.engine_utilities import settings
from devsecops_engine_tools.version import version


logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()


Expand Down Expand Up @@ -109,6 +108,7 @@ def get_inputs_from_cli(args):
"trivy",
"xray",
"dependency_check",
"kiuwan",
],
type=str,
required=False,
Expand Down Expand Up @@ -199,6 +199,12 @@ def get_inputs_from_cli(args):
required=False,
help="Token for downloading external checks from engine_iac or engine_secret if is necessary. Ej: github_token:token, github_app:private_key, ssh:privatekey:pass",
)
parser.add_argument(
"--token_engine_code",
type=str,
required=False,
help="Password for connecting with the kiuwan platform. In order to get a kiuwan pass, go to the platform and select the pass of the account selected for the engine."
)
parser.add_argument(
"--xray_mode",
choices=["scan", "audit","build-scan"],
Expand Down Expand Up @@ -226,13 +232,20 @@ def get_inputs_from_cli(args):
default="false",
help="Enable or disable context creation. Applies to engine_iac, engine_container and engine_dependencies. Default is false."
)
parser.add_argument(
"-repo",
"--repo_name",
type=str,
required=False,
help="Repository name, used when the repository name should not be taken from environment variable. Apply to kiuwan"
)

TOOLS = {
"engine_iac": ["checkov", "kics", "kubescape"],
"engine_secret": ["trufflehog", "gitleaks"],
"engine_container": ["prisma", "trivy"],
"engine_dependencies": ["xray", "dependency_check", "trivy"],
"engine_code": ["bearer"],
"engine_code": ["bearer", "kiuwan"],
"engine_dast": ["nuclei"],
"engine_risk": None,
}
Expand Down Expand Up @@ -264,10 +277,12 @@ def get_inputs_from_cli(args):
"token_engine_container": args.token_engine_container,
"token_engine_dependencies": args.token_engine_dependencies,
"token_external_checks": args.token_external_checks,
"token_engine_code": args.token_engine_code,
"xray_mode": args.xray_mode,
"image_to_scan": args.image_to_scan,
"dast_file_path": args.dast_file_path,
"context": args.context
"context": args.context,
"repo_name": args.repo_name
}


Expand Down Expand Up @@ -317,4 +332,4 @@ def application_core():


if __name__ == "__main__":
application_core()
application_core()
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,12 @@ class Finding:
module: str
category: Category
requirements: str
tool: str
tool: str

@dataclass
class EngineCodeFinding(Finding):
analysis_url: str
analysis_code: str
label: str
application_business_value: str
defect_type: str
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ def process(self, findings_list: "list[Finding]", input_core: InputCore, args: a

findings_excluded, findings_without_exclusions = self._filter_findings(findings_list, exclusions)
scan_result["findings_excluded"] = [self._map_finding_excluded(item) for item in findings_excluded]

vulnerabilities = [v for v in findings_without_exclusions if v.category == Category.VULNERABILITY]
compliances = [v for v in findings_without_exclusions if v.category == Category.COMPLIANCE]

vulnerability_counts = self._count_severities(vulnerabilities)
compliance_counts = self._count_severities(compliances)

self._handle_vulnerabilities(vulnerability_counts, vulnerabilities, threshold, warning_release, scan_result)
self._handle_vulnerabilities(vulnerability_counts, vulnerabilities, threshold, warning_release, scan_result, args)
self._handle_cve_policy(vulnerabilities, threshold)
self._handle_compliances(compliance_counts, compliances, threshold, warning_release, scan_result)
self._handle_compliances(compliance_counts, compliances, threshold, warning_release, scan_result, args)
self._handle_exclusions(findings_excluded, exclusions)
else:
print(devops_platform_gateway.message("succeeded", "There are no findings"))
Expand Down Expand Up @@ -109,7 +109,7 @@ def _map_finding_excluded(self, item):
return {
"id": item.id,
"severity": item.severity,
"category": item.category.value,
"category": item.category,
}

def _count_severities(self, findings_list):
Expand All @@ -125,7 +125,7 @@ def _count_severities(self, findings_list):
counts[severity] += 1
return counts

def _handle_vulnerabilities(self, counts, vulnerabilities_list, threshold, warning_release, scan_result):
def _handle_vulnerabilities(self, counts, vulnerabilities_list, threshold, warning_release, scan_result, args):
devops_platform_gateway = self.devops_platform_gateway
printer_table_gateway = self.printer_table_gateway
print()
Expand All @@ -142,6 +142,8 @@ def _handle_vulnerabilities(self, counts, vulnerabilities_list, threshold, warni
counts["low"] >= threshold.vulnerability.low):

print("Below are all vulnerabilities detected.")
if vulnerabilities_list and args.get("tool", None) == "kiuwan":
print(f"Analysis url: {vulnerabilities_list[0].analysis_url}")
printer_table_gateway.print_table_findings(vulnerabilities_list)
print(devops_platform_gateway.message(
"error",
Expand Down Expand Up @@ -194,13 +196,15 @@ def _handle_cve_policy(self, vulnerabilities_list: "list[Finding]", threshold):
))
print(devops_platform_gateway.result_pipeline("failed"))

def _handle_compliances(self, counts, compliances_list, threshold, warning_release, scan_result):
def _handle_compliances(self, counts, compliances_list, threshold, warning_release, scan_result, args):
devops_platform_gateway = self.devops_platform_gateway
printer_table_gateway = self.printer_table_gateway
print()

if compliances_list:
print("Below are all compliances issues detected.")
if compliances_list and args.get("tool", None) == "kiuwan":
print(f"Analysis url: {compliances_list[0].analysis_url}")
printer_table_gateway.print_table_findings(compliances_list)
status = "succeeded"
if counts["critical"] >= threshold.compliance.critical:
Expand Down Expand Up @@ -251,4 +255,4 @@ def _handle_exclusions(self, findings_excluded_list, exclusions):
printer_table_gateway.print_table_exclusions(exclusions_list)

for reason, total in Counter(x["reason"] for x in exclusions_list).items():
print("{0} findings count: {1}".format(reason, total))
print("{0} findings count: {1}".format(reason, total))
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ReleaseVariables,
AgentVariables,
VMVariables,
ApplicationVariables,
)
from devsecops_engine_tools.engine_utilities.azuredevops.infrastructure.azure_devops_api import (
AzureDevopsApi,
Expand Down Expand Up @@ -117,8 +118,9 @@ def get_variable(self, variable):
"vm_product_type_name": VMVariables.Vm_Product_Type_Name,
"vm_product_name": VMVariables.Vm_Product_Name,
"vm_product_description": VMVariables.Vm_Product_Description,
"build_task": ApplicationVariables.Application_Build_Task,
}
try:
return variable_map.get(variable).value()
except ValueError:
return None
return None
Loading
Loading