Python CLI that scans Terraform and AWS CDK Infrastructure-as-Code, reports security + best-practice findings, and writes the fix. Runs locally, keylessly, or grounded by Checkov.
iac-scanner complements rule-based scanners like Checkov, tfsec, and KICS — it doesn't replace them. Its differentiator is AI-generated fixes alongside findings, and keyless operation via GitHub Models, Ollama, or an MCP server.
AI-generated output — review before applying. Fixed code is written to
scan-output/fixed/and must be human-reviewed before overwriting your working tree. No auto-apply.
License: Apache License 2.0.
Pick whichever path matches your setup:
pip install iac-scanner
export GITHUB_TOKEN=$(gh auth token)
iac-scan scan ./my-tf --provider github -o ./outpip install iac-scanner[local]
ollama pull qwen2.5-coder:7b-instruct # first run only
iac-scan scan ./my-tf --provider ollama -o ./outpip install iac-scanner[mcp]
# Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
# "mcpServers": { "iac-scanner": { "command": "iac-scan-mcp" } }
# Then in Claude: "Scan the Terraform in ~/work/infra"pip install iac-scanner
export OPENAI_API_KEY=sk-...
iac-scan scan ./my-tf --provider openai -o ./out
# or: iac-scan scan ./my-tf --provider auto (picks ollama → github → openai → anthropic)iac-scan scan ./samples/tf -o ./out --scan-onlyEvery mode writes scan-report.json (findings) and, when AI is enabled, fixed/ (corrected code).
- Terraform: a directory containing
main.tf, or the path tomain.tfitself. Sibling.tffiles are included. - CDK: a directory containing
index.ts/index.js, or the path to that file.lib/andbin/subdirectories are included.
terraform.tfstate*, *.tfvars, .env*, *.pem, *.key, id_rsa*, .terraform/, node_modules/, cdk.out/. See SECURITY.md for the full skip-list and threat model.
- Factory creates the right scanner (
TerraformScannerorCdkScanner) from the given path. - Scan: load entry file(s), apply the skip-list, redact obvious secrets, enforce the 200 KB input cap.
- (Optional) Rule engine pre-pass (
--rules-engine=checkov) adds framework-mapped findings with CWE/CIS/NIST tags. - Analysis (LLM, structured output): findings as a Pydantic-validated JSON array with severity + location.
- Fix (LLM, text output): regenerates corrected code with a mandatory
AI-generated — review before applyingbanner. - Output: JSON and/or SARIF 2.1.0 report; fixed files under
fixed/.
- JSON report (
scan-report.json):iac_type,entry_path,findings,metadata,provider,analysis_model,fix_model,prompt_version. - SARIF 2.1.0 (
--format sarif|both): consumed by GitHub Code Scanning, GitLab Security Dashboards, SonarQube. - Fixed code (
fixed/): multi-file output preserves the original layout; each file starts with the AI-generated banner.
# Basic scan (analysis + fix)
iac-scan scan ./my-tf-dir
# No-AI parse only (no keys needed)
iac-scan scan ./my-tf-dir --scan-only
# Findings only, skip fix generation
iac-scan scan ./my-tf-dir --no-fix
# Output SARIF for GitHub Code Scanning
iac-scan scan ./my-tf-dir --format sarif -o ./out
# Or both at once
iac-scan scan ./my-tf-dir --format both -o ./out
# Choose a provider explicitly
iac-scan scan ./my-tf-dir --provider github
iac-scan scan ./my-tf-dir --provider ollama
iac-scan scan ./my-tf-dir --provider openai
# Ground the LLM with Checkov rule findings (hybrid mode)
pip install iac-scanner[rules]
iac-scan scan ./my-tf-dir --rules-engine checkov
# CI gate: exit non-zero on any HIGH or CRITICAL finding
iac-scan scan ./my-tf-dir --fail-on high
# Cost cap: abort if projected LLM cost exceeds $0.50
iac-scan scan ./my-tf-dir --max-spend 0.50
# Force-refresh: skip the response cache for this run
iac-scan scan ./my-tf-dir --no-cache| Variable | Purpose |
|---|---|
IAC_PROVIDER |
openai | anthropic | github | ollama (overrides auto-detect). |
OPENAI_API_KEY |
Required when --provider=openai. |
ANTHROPIC_API_KEY |
Required when --provider=anthropic. |
GITHUB_TOKEN |
Required when --provider=github. Any gh auth token works (free tier). |
OLLAMA_HOST |
Ollama endpoint. Default: http://localhost:11434. |
IAC_ANALYSIS_MODEL |
Override analysis model (e.g. gpt-4o, claude-3-5-sonnet-20241022). |
IAC_FIX_MODEL |
Override fix model. |
IAC_MAX_SPEND_USD |
Hard dollar cap per run. Abort if projected cost exceeds it. |
IAC_MAX_INPUT_BYTES |
Input size cap (default 200 KB, floored to 1 KB, ceilinged to 10 MB). |
IAC_NO_CACHE |
When set, skip the content-addressed response cache. |
IAC_NO_REDACT |
Disable secret redaction (not recommended — see SECURITY.md). |
IAC_CACHE_DIR |
Override cache directory (default ~/.cache/iac-scanner/). |
IAC_OUTPUT_FORMAT |
Default output format (json | sarif | both). |
# Base install — includes OpenAI and Anthropic providers + GitHub Models
pip install iac-scanner
# With optional extras
pip install iac-scanner[local] # Ollama local-LLM provider
pip install iac-scanner[mcp] # MCP server mode for Claude Desktop / Cursor
pip install iac-scanner[rules] # Checkov hybrid mode
pip install iac-scanner[all] # all of the above
# From source
git clone https://github.com/alphacrack/iac-scanner
cd iac-scanner
pip install -e ".[dev]"Articles and a step-by-step tutorial are published on GitHub Pages at https://alphacrack.github.io/iac-scanner/. Source lives under docs/.
See CONTRIBUTING.md for development setup, test strategy, and the release process (Trusted Publishing + SBOM + Sigstore signing).
- GOVERNANCE.md — roles, decision-making, branch protection policy.
- MAINTAINERS.md — canonical list of maintainers.
- SUPPORT.md — where to ask questions, file bugs, and request features.
- CODE_OF_CONDUCT.md — Contributor Covenant 2.1.
See SECURITY.md for the threat model (prompt injection, secret exposure, hallucinated fixes, supply-chain, cost abuse) and private disclosure channel.
src/iac_scanner/
cli.py # CLI entry (click)
factory.py # create_scanner(path) → TerraformScanner | CdkScanner
models.py # Pydantic: Finding, FindingsList, ScanReport, VerificationResult
cache.py # content-addressed SHA-256 response cache
cost.py # tiktoken preflight + IAC_MAX_SPEND_USD enforcement
mcp_server.py # iac-scan-mcp entry — MCP server for host LLMs
scanners/
base.py # IacScanner (abstract), ScanResult
_filters.py # skip-list, secret redaction, input size cap
terraform.py # TerraformScanner (main.tf)
cdk.py # CdkScanner (index.ts / index.js)
llm/
providers.py # LLMClient + OpenAI / Anthropic / GitHub Models / Ollama
orchestration/
tasks.py # analysis + fix LangChain tasks (structured output, XML fencing)
runner.py # run_pipeline: scan → cache → cost check → LLM → result
hybrid.py # rule-pre-pass + LLM augment + dedupe
rules/
engine.py # rule-engine dispatcher
checkov.py # Checkov subprocess adapter with CWE/CIS/NIST mapping
output/
report.py # write_report_and_fixes — JSON + fixed/ banner
sarif.py # SARIF 2.1.0 emitter