The scan command in ThothCTL provides comprehensive security scanning capabilities for Infrastructure as Code (IaC) resources. It integrates multiple industry-standard security scanning tools to help identify vulnerabilities, misconfigurations, and compliance issues in your infrastructure code.
The scan command helps DevSecOps teams and developers to:
Currently, ThothCTL supports the following scan subcommands:
iac - Scan Infrastructure as Code resources (Terraform, OpenTofu)# Scan IaC resources using default settings (Checkov)
thothctl scan iac
# Scan with specific tools
thothctl scan iac -t checkov -t trivy -t opa
# Fail pipeline on violations
thothctl scan iac -t checkov -t opa --enforcement hard
# JSON output for CI/CD
thothctl scan iac -t checkov --output json
# SARIF output for GitHub Code Scanning
thothctl scan iac -t checkov --output sarif
| Option | Description |
|---|---|
-t, --tools |
Specify scanning tools: checkov, trivy, kics, terraform-compliance, opa |
--enforcement [soft\|hard] |
Exit 0 (soft) or exit 1 on violations (hard) |
--output [text\|json\|sarif] |
Output format (default: text) |
--reports-dir |
Directory to store scan reports |
--post-to-pr |
Post scan summary to pull request |
--verbose |
Enable verbose output |
Every scan automatically produces:
| Output | Description |
|---|---|
scan_report.html |
Unified multi-tool HTML report with severity, findings, and trend |
scan_summary.md |
Markdown summary |
| Terminal tables | Pass/fail per tool + severity breakdown + trend comparison |
Optional outputs via --output flag:
| Flag | File | Use Case |
|---|---|---|
--output json |
scan_report.json |
CI/CD pipeline consumption |
--output sarif |
scan_results.sarif |
GitHub Code Scanning, IDE integration |
ThothCTL automatically tracks scan results in ~/.thothcf/scan_history.db (SQLite). On each scan, it compares against the previous run for the same directory and shows improvement or regression.
| Tool | Type | Requires |
|---|---|---|
| Checkov | Static analysis with built-in rules | checkov binary |
| Trivy | Vulnerability and misconfiguration detection | trivy binary |
| KICS | Static analysis via Docker | Docker |
| Terraform-compliance | BDD-style compliance testing against tfplan.json | terraform-compliance (pip) |
| OPA/Conftest | Custom policy evaluation with Rego | conftest and/or opa binary |
Each tool has its own strengths. Combine built-in rule scanners (Checkov, Trivy) with custom policy tools (OPA, Terraform-compliance) for comprehensive coverage.
Organization Policy Repo: Set THOTH_ORG_POLICY env var to point all policy tools (OPA, terraform-compliance, project structure rules) to a single centralized governance repository.
The OPA/Conftest scanner supports two evaluation modes:
| Mode | Input | Command | Best For |
|---|---|---|---|
| conftest (default) | Static HCL files | conftest test |
Naming conventions, tagging, structure rules |
| opa exec | tfplan.json |
opa exec |
Plan-based validation (resource counts, blast radius, drift) |
THOTH_ORG_POLICY env var — centralizes policy source for OPA, terraform-compliance, and project structure rulesimport rego.v1 and the contains/if keywords# Scan with OPA using conftest mode (static HCL)
thothctl scan iac -t opa
# Scan with OPA using plan-based evaluation
thothctl scan iac -t opa --opa-mode exec
# Use a Git-hosted policy repo
export THOTH_ORG_POLICY=https://github.com/myorg/infra-policies.git
thothctl scan iac -t opa
package terraform.policies
import rego.v1
deny contains msg if {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not resource.change.after.tags.Environment
msg := sprintf("S3 bucket %q missing 'Environment' tag", [resource.address])
}
warn contains msg if {
resource := input.resource_changes[_]
resource.type == "aws_instance"
resource.change.after.instance_type == "t2.micro"
msg := sprintf("Instance %q uses t2.micro — consider t3.micro for better perf/cost", [resource.address])
}
OPA/Conftest now supports automatic conversion of YAML data files (.yaml/.yml) to JSON for policy parameterization. This allows you to externalize policy parameters — such as allowed regions, required tags, and thresholds — from your Rego code into maintainable YAML configuration files.
.rego policies (e.g., policy/config.yaml)--data flagExternalize policy parameters that change across teams or environments without modifying Rego logic:
Define your parameters in YAML:
# policy/config.yaml
allowed_regions:
- us-east-1
- eu-west-1
required_tags:
- Environment
- Owner
Reference them in your Rego policy via data.config:
# policy/regions.rego
package main
import data.config
deny[msg] {
# uses config.allowed_regions from YAML
resource := input.resource.aws_instance[name]
not resource.provider_region in config.allowed_regions
msg := sprintf("Instance '%s' deployed in non-allowed region", [name])
}
deny[msg] {
resource := input.resource.aws_instance[name]
missing := {tag | tag := config.required_tags[_]; not resource.tags[tag]}
count(missing) > 0
msg := sprintf("Instance '%s' missing required tags: %v", [name, missing])
}
policy/
├── config.yaml # Externalized parameters (auto-converted to JSON)
├── regions.rego # Policy using data.config.allowed_regions
├── tagging.rego # Policy using data.config.required_tags
└── ...
No additional CLI flags are needed — ThothCTL detects YAML files in the policy directory automatically.
When --enforcement hard is specified, ThothCTL gates the pipeline based on scan findings:
thothctl scan iac -t checkov -t opa --enforcement hard
deny rules trigger enforcement — warn rules are informational and do not cause a non-zero exit1 is returned when any deny-level violations exist (hard mode)0 is always returned in soft mode regardless of findings┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Non-Compliance Findings (Top 15) ┃
┡━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Tool │ Severity │ Finding │
├───────────────┼──────────┼────────────────────────────────────┤
│ checkov │ HIGH │ CKV_AWS_18: S3 access logging │
│ opa │ CRITICAL │ Missing encryption at rest │
│ ... │ ... │ ... │
└───────────────┴──────────┴────────────────────────────────────┘
Per-tool violations: checkov=5, opa=3, trivy=1
❌ Enforcement HARD: 9 deny-level violations found.
Fix the findings above or add suppressions to proceed.
All scanning tools now generate unified HTML reports with a consistent visual style:
Reports/
├── checkov/
│ └── html_reports/
│ ├── index.html # Summary index page
│ ├── stack_main.html # Per-stack report
│ └── stack_modules.html
├── trivy/
│ └── html_reports/
│ ├── index.html
│ └── ...
├── kics/
│ └── html_reports/
│ └── ...
├── opa/
│ └── html_reports/
│ └── ...
└── terraform-compliance/
└── html_reports/
└── ...
The ThothCTL web dashboard provides an interactive view of scan findings:
# Launch the dashboard after scanning
thothctl dashboard launch
# 1. Run scan with all tools
thothctl scan iac -t checkov -t trivy -t kics -t opa -t terraform-compliance
# 2. Launch dashboard to explore results
thothctl dashboard launch --port 8080
# 3. Open http://localhost:8080 in your browser
For detailed information about scanning IaC resources, see the IaC Scanning documentation.