Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ Please follow our [Getting Started Guide](https://bancolombia.github.io/devsecop

# How can I help?

Review the issues, we hear new ideas. Read more [Contributing](https://github.com/bancolombia/devsecops-engine-tools/blob/trunk/docs/CONTRIBUTING.md)
Review the issues, we hear new ideas. Read more [Contributing](https://github.com/bancolombia/devsecops-engine-tools/blob/trunk/docs/CONTRIBUTING.md)
4 changes: 4 additions & 0 deletions docs/Docusaurus/docs/life_cycle/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ For more information about structure remote config visit [Structure Remote Confi
<tr>
<td><a href="https://www.kics.io/">KICS</a></td>
<td>Free</td>
</tr>
<tr>
<td><a href="https://www.conftest.dev/">CONFTEST</a></td>
<td>Free</td>
</tr>
<tr>
<td>ENGINE_DAST</td>
Expand Down
2 changes: 1 addition & 1 deletion docs/Docusaurus/docs/modules/engine_core.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ Configuration of the driven adapters in the main layer and management of on/off
},
"ENGINE_IAC": {
"ENABLED": true,
"TOOL": "CHECKOV|KUBESCAPE|KICS",
"TOOL": "CHECKOV|KUBESCAPE|KICS|CONFTEST",
"PRIORITY": "STANDARD|DISCREET"
},
"ENGINE_CONTAINER": {
Expand Down
57 changes: 55 additions & 2 deletions docs/Docusaurus/docs/modules/engine_sast/engine_iac.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,42 @@ Main configuration file that defines scanning behavior, tool versions, and secur
},
"KUBESCAPE": {
"VERSION": "3.0.11"
},
"CONFTEST": {
"VERSION": "0.56.0",
"POLICY_PATH": "policy",
"USE_EXTERNAL_CHECKS_DIR": false,
"EXTERNAL_DIR_OWNER": "",
"EXTERNAL_DIR_REPOSITORY": "",
"EXTERNAL_DIR_POLICIES_PATH": "policy",
"APP_ID_GITHUB": "",
"INSTALLATION_ID_GITHUB": "",
"DEFAULT_SEVERITY": "high",
"DEFAULT_CATEGORY": "vulnerability",
"RULES": {
"RULES_N8N": {
"CONF_N8N_BC_1": {
"severity": "Critical",
"category": "Vulnerability"
},
"CONF_N8N_BC_2": {
"severity": "Medium",
"category": "Vulnerability"
},
"CONF_N8N_BC_3": {
"severity": "High",
"category": "Vulnerability"
},
"CONF_N8N_BC_4": {
"severity": "Low",
"category": "Compliance"
},
"CONF_N8N_BC_5": {
"severity": "Critical",
"category": "Vulnerability"
}
}
}
}
}
```
Expand Down Expand Up @@ -232,6 +268,21 @@ Main configuration file that defines scanning behavior, tool versions, and secur
##### Kubescape Tool Configuration
- **VERSION**: Kubescape version to use (e.g., `"3.0.11"`)

##### Conftest Tool Configuration
- **VERSION**: Conftest version to download (e.g., `"0.56.0"`)
- **POLICY_PATH**: Local path to the directory containing `.rego` policy files (default `"policy"`)
- **External Policy Configuration** (via GitHub App):
- `USE_EXTERNAL_CHECKS_DIR`: Download policies from a GitHub repository (`true`/`false`)
- `EXTERNAL_DIR_OWNER`: GitHub organisation or user owning the policy repository
- `EXTERNAL_DIR_REPOSITORY`: Repository name containing the policies
- `EXTERNAL_DIR_POLICIES_PATH`: Path inside the repository where policies are stored
- `APP_ID_GITHUB`: GitHub App ID used for authentication
- `INSTALLATION_ID_GITHUB`: GitHub App installation ID
- **Default Values**:
- `DEFAULT_SEVERITY`: Fallback severity when a rule has no entry in `RULES` (e.g., `"high"`)
- `DEFAULT_CATEGORY`: Fallback category when a rule has no entry in `RULES` (e.g., `"vulnerability"`)
- **RULES**: Rule metadata keyed by platform group then rule ID (see [Security Rules Configuration](#security-rules-configuration) below)

##### Security Rules Configuration
Each tool contains rule sets organized by technology:

Expand All @@ -256,6 +307,7 @@ Each tool contains rule sets organized by technology:
- **RULES_OPENAPI**: API security rules for OpenAPI specifications
- **RULES_SERVERLESS**: Serverless rules for AWS Lambda specifications
- **RULES_BICEP**: Azure Bicep security rules for Azure Cloud infrastructure
- **RULES_N8N**: n8n workflow security rules (authentication, transport security, dangerous nodes, error handling, hardcoded credentials)

In the RULES section of each platform (RULES_DOCKER, RULES_K8S, RULES_CLOUDFORMATION, etc.), the body is empty. Example “RULES_DOCKER” {}, the tool executes all rules associated with it.

Expand Down Expand Up @@ -350,7 +402,7 @@ Defines exclusion rules for repositories and specific security checks.

## Main Responsibilities

- **IaC Security Orchestration:** Executes IaC security tools (Checkov, KICS, Kubescape) on infrastructure code
- **IaC Security Orchestration:** Executes IaC security tools (Checkov, KICS, Kubescape, Conftest) on infrastructure code
- **Configuration Management:** Loads and processes scan configurations and exclusions from remote repositories
- **Folder and File Discovery:** Identifies relevant folders/files for scanning based on patterns and configuration
- **Exclusions Management:** Applies exclusion rules based on configuration and DevSecOps policy
Expand All @@ -363,13 +415,14 @@ Defines exclusion rules for repositories and specific security checks.
- `runner_iac_scan.py`: Main entry point for IaC scan orchestration
- `entry_point_tool.py`: Initializes the IaC engine and triggers the scan process
- `iac_scan.py`: Core use case for executing the scan, handling configuration, exclusions, and result aggregation
- **Adapters:** Integrations for IaC security tools (Checkov, KICS, Kubescape)
- **Adapters:** Integrations for IaC security tools (Checkov, KICS, Kubescape, Conftest)

## Supported Tools and Features

- **Checkov:** Scans Terraform, CloudFormation, Kubernetes, Docker, and more for security misconfigurations
- **KICS:** Scans IaC files for vulnerabilities and compliance issues with OpenAPI support
- **Kubescape:** Focused on Kubernetes security scanning with RBAC analysis
- **Conftest:** Policy-as-code scanning using OPA/Rego policies; supports namespace-based platform filtering and GitHub-hosted policy repositories
- **Configurable Exclusions:** Supports exclusion of files/folders and custom ignore patterns with expiration dates
- **Thresholds and Policies:** Handles custom thresholds and build-breaking policies for vulnerabilities and compliance
- **Multi-platform Support:** Cross-platform binary distribution for Linux, macOS, and Windows
Expand Down
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 @@ -189,7 +189,7 @@
},
"ENGINE_IAC": {
"ENABLED": true,
"TOOL": "CHECKOV|KUBESCAPE|KICS",
"TOOL": "CHECKOV|KUBESCAPE|KICS|CONFTEST",
"PRIORITY": "STANDARD|DISCREET"
},
"ENGINE_CONTAINER": {
Expand Down
41 changes: 41 additions & 0 deletions example_remote_config_local/engine_sast/engine_iac/ConfigTool.json
Original file line number Diff line number Diff line change
Expand Up @@ -809,5 +809,46 @@
}
}
}
},
"CONFTEST": {
"VERSION": "0.56.0",
"POLICY_PATH": "policy",
"USE_EXTERNAL_CHECKS_DIR": false,
"EXTERNAL_DIR_OWNER": "",
"EXTERNAL_DIR_REPOSITORY": "",
"EXTERNAL_DIR_POLICIES_PATH": "policy",
"APP_ID_GITHUB": "",
"INSTALLATION_ID_GITHUB": "",
"DEFAULT_SEVERITY": "high",
"DEFAULT_CATEGORY": "vulnerability",
"RULES": {
"RULES_N8N": {
"CONF_N8N_BC_1": {
"checkID": "CONF_N8N_BC_1 Webhook node exposes an unauthenticated endpoint",
"severity": "Critical",
"category": "Vulnerability"
},
"CONF_N8N_BC_2": {
"checkID": "CONF_N8N_BC_2 HTTP Request node uses insecure HTTP",
"severity": "Medium",
"category": "Vulnerability"
},
"CONF_N8N_BC_3": {
"checkID": "CONF_N8N_BC_3 Execute Command node can introduce command-injection risks",
"severity": "High",
"category": "Vulnerability"
},
"CONF_N8N_BC_4": {
"checkID": "CONF_N8N_BC_4 Active workflow has no error-handling node",
"severity": "Low",
"category": "Compliance"
},
"CONF_N8N_BC_5": {
"checkID": "CONF_N8N_BC_5 Credential hardcoded in node parameter",
"severity": "Critical",
"category": "Vulnerability"
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def get_inputs_from_cli(args):
"checkov",
"kics",
"kubescape",
"conftest",
"trufflehog",
"gitleaks",
"prisma",
Expand Down Expand Up @@ -156,7 +157,7 @@ def get_inputs_from_cli(args):
parser.add_argument(
"-p",
"--platform",
type=parse_choices({"all", "docker", "k8s", "cloudformation", "openapi", "terraform", "serverless", "bicep"}),
type=parse_choices({"all", "docker", "k8s", "cloudformation", "openapi", "terraform", "serverless", "bicep", "n8n"}),
required=False,
default="all",
help="Platform to scan, applies only to the engine_iac tool and it is possible to select several {all, docker, k8s, cloudformation, openapi, terraform}",
Expand Down Expand Up @@ -262,7 +263,7 @@ def get_inputs_from_cli(args):
)

TOOLS = {
"engine_iac": ["checkov", "kics", "kubescape"],
"engine_iac": ["checkov", "kics", "kubescape", "conftest"],
"engine_secret": ["trufflehog", "gitleaks", "all_tools"],
"engine_container": ["prisma", "trivy"],
"engine_dependencies": ["xray", "dependency_check", "trivy"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):

scan_type_mapping = {
"CHECKOV": "Checkov Scan",
"CONFTEST": "Conftest Scan",
"PRISMA": "Twistlock Image Scan",
"XRAY": "JFrog Xray On Demand Binary Scan",
"TRUFFLEHOG": "Trufflehog Scan",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from devsecops_engine_tools.engine_sast.engine_iac.src.infrastructure.driven_adapters.kics.kics_tool import (
KicsTool
)
from devsecops_engine_tools.engine_sast.engine_iac.src.infrastructure.driven_adapters.conftest.conftest_tool import (
ConftestTool
)


def runner_engine_iac(dict_args, tool, secret_tool, devops_platform_gateway, remote_config_source_gateway, env):
Expand All @@ -20,7 +23,8 @@ def runner_engine_iac(dict_args, tool, secret_tool, devops_platform_gateway, rem
tools = {
"CHECKOV": CheckovTool(),
"KUBESCAPE": KubescapeTool(),
"KICS": KicsTool()
"KICS": KicsTool(),
"CONFTEST": ConftestTool(),
}

if tool in tools:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from devsecops_engine_tools.engine_core.src.domain.model.finding import (
Category,
Finding,
)
from datetime import datetime
from dataclasses import dataclass


@dataclass
class ConftestDeserealizator:
@classmethod
def get_list_finding(
cls, results_scan_list: list, default_severity: str, default_category: str, rules_config: dict = None
) -> "list[Finding]":
rules_lookup = {}
for rule_group in (rules_config or {}).values():
for rule_id, rule_data in rule_group.items():
rules_lookup[rule_id] = rule_data

list_open_findings = []

for file_result in results_scan_list:
filename = file_result.get("filename", "unknown")

for failure in file_result.get("failures", []) or []:
msg = failure.get("msg", "unknown")
metadata = failure.get("metadata", {}) or {}
query = metadata.get("query", "unknown")
node_type = metadata.get("node_type", "unknown")
node_id = metadata.get("node_id", "unknown")
where = f"{filename}: {node_type}.{node_id}"

rule_id = metadata.get("id", "")
rule_meta = rules_lookup.get(rule_id, {})

severity = rule_meta.get("severity", default_severity).lower()
category_str = rule_meta.get("category", default_category).lower()

finding_open = Finding(
id=rule_id or query,
cvss=None,
where=where,
description=msg,
severity=severity,
identification_date=datetime.now().strftime("%d%m%Y"),
published_date_cve=None,
module="engine_iac",
category=Category(category_str),
requirements=rule_meta.get("url"),
tool="Conftest",
)
list_open_findings.append(finding_open)

return list_open_findings
Loading
Loading