IaC Scanner
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.
Quickstart (30 seconds, no cost)
Pick whichever path matches your setup:
GitHub Models (free for any GitHub user)
pip install iac-scanner
export GITHUB_TOKEN=$(gh auth token)
iac-scan scan ./my-tf --provider github -o ./out
Ollama (fully local, offline, free)
pip install iac-scanner[local]
ollama pull qwen2.5-coder:7b-instruct # first run only
iac-scan scan ./my-tf --provider ollama -o ./out
MCP server — drive from Claude Desktop / Cursor
pip 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"
OpenAI / Anthropic (bring your own key)
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)
No-network demo (no AI, just parse)
iac-scan scan ./samples/tf -o ./out --scan-only
Every mode writes scan-report.json (findings) and, when AI is enabled, fixed/ (corrected code).
Input (CLI)
- 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.
What we skip (automatic)
terraform.tfstate*, *.tfvars, .env*, *.pem, *.key, id_rsa*, .terraform/, node_modules/, cdk.out/. See SECURITY.md for the full skip-list and threat model.
Process
- 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/.
Output
- 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.
Usage
# 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
Environment variables
| 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). |
Install
# 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]"
Blog and tutorial
Articles and a step-by-step tutorial are published on GitHub Pages at https://alphacrack.github.io/iac-scanner/. Source lives under docs/.
Contributing
See CONTRIBUTING.md for development setup, test strategy, and the release process (Trusted Publishing + SBOM + Sigstore signing).
Governance & support
- 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.
Security
See SECURITY.md for the threat model (prompt injection, secret exposure, hallucinated fixes, supply-chain, cost abuse) and private disclosure channel.
Project layout
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
Metadata
Release files for iac-scanner 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| iac_scanner-0.5.0.tar.gz | 133.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| iac_scanner-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 192.8 kB
Release files / iac_scanner-0.5.0.tar.gz
| Download URL | iac_scanner-0.5.0.tar.gz |
|---|---|
| Size | 133.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
683de7eb5b9061477cb6a91f0ed08d4819fea02d0c42955543ebef78674e1312
|
|
BLAKE2b-256 checksum How to use checksums |
deb0dd847a8ba12aca614eb524389223375eb04566a4069f1377750ab56b597d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / iac_scanner-0.5.0-py3-none-any.whl
| Download URL | iac_scanner-0.5.0-py3-none-any.whl |
|---|---|
| Size | 58.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
baf1f33559f6d5e4e33b017db60661c36e5d75eb6af1a77e9638ae96f786d590
|
|
BLAKE2b-256 checksum How to use checksums |
a3f72677ca197cb19bd6184ea595a46037bdd252c7c47f373fe3389a2e15b546
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logSecurity for iac-scanner 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for iac_scanner-0.5.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.