Static + plan-time Terraform analysis with attack-graph prioritisation, MITRE ATT&CK mapping, and one-click PR fix suggestions. Drop into CI in under 5 minutes.
Quickstart Β· Why tf-analyze? Β· Features Β· Integrations Β· Screenshots Β· Documentation Β· Adding a rule Β· Demo corpora Β· Repo layout Β· Contributing Β· Provenance Β· License
Same engine, ten surfaces β Claude Code skill, Python CLI, GitHub Action, Docker, pre-commit hook, LSP server, VS Code extension, HCP Run Task, MCP server for AI agents, native Terraform provider. Pick the one that fits your workflow; the rule catalogue, score, and fix_hcl are identical across all of them.
| Cloud | Security | Hardening | Ops & Reuse | Total |
|---|---|---|---|---|
| AWS | 62 | 25 | 4 | 91 |
| GCP | 41 | 47 | 3 | 91 |
| Azure | 56 | 32 | 3 | 91 |
| K8s / Helm | 12 | 6 | 0 | 18 |
| Cross-cloud / engine | 21 | 27 | 14 | 62 |
| Total | 192 | 137 | 24 | 353 |
Hardening = ROB-* + STK-*; Ops & Reuse = OPS-* + COST-* + MOD-* + MOD-REUSE-* + INT-* + CI-* + STYLE-*. Full per-family breakdown and shape-by-cloud commentary in Detection β.
docker run --rm -v "$(pwd):/workspace" \
ghcr.io/chrisadkin8/tf-analyze \
--target /workspace --format html > report.html
open report.htmlgit clone https://github.com/ChrisAdkin8/tf-analyze.git
cd tf-analyze
./install.sh # installs as a Claude Code skill
pip install python-hcl2 # optional fast-path (default-on if present)
python3 scripts/detect.py --target /path/to/terraform
python3 scripts/detect.py --target . --mode diff --fail-on HIGH --format sarif > out.sarif
python3 scripts/detect.py --list-rules
python3 scripts/detect.py --explain SEC-AWS-IAM-POLICY-005/tf-analyze # full audit, all areas
/tf-analyze focus:security mode:diff # PR review
/tf-analyze mode:verify-fixed # confirm prior fixes
Live diagnostics, Quick Fix, attack graph, Module Reuse Advisor, and a vscode:// URI handler β all from a self-contained .vsix (the engine and rule catalogue are bundled; no companion repo to clone).
# Marketplace (preferred, once the listing is live)
code --install-extension tfanalyze.tf-analyze
# Or from a downloaded .vsix (current path until the Marketplace listing publishes)
code --install-extension tf-analyze-0.1.57.vsixOpen any Terraform workspace and the six status-bar shortcuts appear bottom-left:
π‘ tf-analyze: 82 (B) Β· 7 findings π€ Attack Graph π Delta β
Compliance πͺ Remediate π¦ Module Reuse
To see the deeper panels render against rich input, open one of the showcase corpora in examples/ β examples/module-reuse-demo/ (π¦) or examples/attack-graph-demo/ (π€). Full reference: docs/vscode-extension.md.
- uses: ChrisAdkin8/tf-analyze@v1
with:
fail-on: HIGH
post-pr-comment: true # inline `suggestion` blocks on every PR
compliance-framework: owasp_iac # optional β adds a collapsible compliance gap report
attack-graph: true # optional β embeds Mermaid attack graph in PR summary
ref: v0.2.6 # optional β shorthand for image tag (default: :latest)ref: is a convenience alias β ref: v0.2.6 is equivalent to image: ghcr.io/chrisadkin8/tf-analyze:0.2.6 (the leading v is stripped before building the docker tag, since docker/metadata-action publishes semver tags without it). Both v0.2.6 and 0.2.6 work; non-semver values like main or latest pass through untouched. Set ref: or image:, not both. See action.yml for the full input reference, and integrations/github-action.yml for an alternative install-from-source workflow that adds SARIF upload + HTML artefact.
A scanner is only as good as the actions it provokes. Where comparable tools stop at "here is a finding", tf-analyze ranks findings by attack-path centrality, ships an HCL fix, and surfaces the adversarial scenario on hover.
| tf-analyze | tfsec | checkov | Prowler | |
|---|---|---|---|---|
| Attack-path graph promoting findings on the critical path | β | β | β | β |
Blast-radius analysis (--blast-radius; per-finding + top-N) |
β | β | β | β |
CISA KEV + FIRST.org EPSS exploitability ranking (--rank-by) |
β | β | β | β |
Drift mode against terraform show -json state.tfstate |
β | β | β | |
| Public web scanner β paste a GitHub URL, get a permalink | β tfanalyze.com | β | β | β |
| Module Reuse Advisor with lines-saved ROI | β | β | β | β |
Full feature matrix (26 rows) β click to expand
| tf-analyze | tfsec | checkov | Prowler | |
|---|---|---|---|---|
| Static HCL analysis | β | β | β | β (live) |
Plan-time (terraform show -json) analysis |
β | β | β | |
| Built-in attack-path graph | β | β | β | β |
| Module Reuse Advisor with lines-saved ROI | β | β | β | β |
| Aggregate risk score + letter grade (AβF) | β | β | β | β |
fix_hcl snippet on every fixable rule |
β (93%; remaining 7% are module-reuse / advisory / version-bump rules where no single HCL edit is correct) | n/a | ||
Inline GitHub PR suggestion blocks |
β | β | β | n/a |
| MITRE ATT&CK mapping (technique + tactic-grouped output) | β pinned to v17 | β | ||
| MITRE D3FEND defensive-technique tagging | β | β | β | β |
| CWE taxonomy in SARIF output | β | β | β | |
CISA KEV + FIRST.org EPSS exploitability ranking (--rank-by exploitability) |
β | β | β | β |
--mode drift against terraform show -json state.tfstate |
β | β | β | |
Compliance PDF export for CISOs (--pdf-output) |
β | β | β | β |
| Public web scanner (paste a GitHub URL, get a permalink) | β (tfanalyze.com/scan/<owner>/<repo>) | β | β | β |
Blast-radius analysis β "what could one terraform apply destroy?" |
β
(--blast-radius; per-finding + per-node + top-N) |
β | β | β |
| OSCAL Assessment Results JSON output | β | β | β | β |
| Compliance frameworks shipped (with real per-rule data) | 11 (CIS, PCI-DSS, SOC 2, OWASP IaC, NIST CSF 2.0, NIST SP 800-53, CSA CCM v4, SLSA, OWASP Top 10, OWASP API, OWASP K8s); 3 more CLI modes (OWASP CICD / LLM / ASVS) ship as flags but have no tagged rules yet | 1 (CIS) | 6 | 5 |
Baseline ratcheting (--baseline prior.json) |
β | β | β | |
| LSP server for IDE diagnostics | β | β | β | β |
| HCP Terraform Run Task integration | β | β | β | β |
Native Terraform provider (data "tfanalyze_scan") |
β | β | β | β |
| MCP server for AI agents (Cursor / Claude Desktop / β¦) | β | β | β | β |
| YAML custom rules | β pattern + policy DSL (cross-resource / conditional / aggregate) | β (Rego) | β (Python+YAML) | β (Python) |
| Stdlib-only core (optional fast-path) | β | n/a | β (pip) | β (pip) |
Comparison reflects features documented as of 2026-05; corrections welcome via issue.
- Attack-path graph + fix centrality β BFS from internet-reachable resources to crown jewels. Findings on the critical path are promoted one urgency tier; fixes are ranked by how many crown jewels each one unblocks.
fix_hclon every rule, with disruption classification β every finding ships an HCL snippet plus aNon-disruptive/Plan required/Forces replacementbadge, so reviewers see operational impact before applying.- Adversarial scenario narratives β HIGH/CRITICAL findings come with a 3β4 sentence breach story (Capital One, Accenture, SolarWinds) to anchor severity in real outcomes.
- IAM policy analysis (HCL + inline JSON) β ten dedicated rules walking both
data "aws_iam_policy_document"blocks ANDpolicy = jsonencode({...})strings onaws_iam_policy/aws_iam_role_policy. Covers wildcard action, wildcard resource, public principal,iam:*privesc, full-admin, NotAction. - Baseline ratcheting β adopt on a noisy legacy repo by snapshotting today's findings; only regressions block CI thereafter.
- Kubernetes + Helm coverage β
kubernetes_namespacePod Security Admission, missingkubernetes_network_policy,cluster-adminRoleBindings, plushelm_releaseoverrides likeservice.type=LoadBalancerandsecurityContext.privileged=true. - Provider-version-aware β rules can declare
applies_when: { min_provider: { aws: "5.0" } }so they self-skip on older provider versions instead of false-positiving. - Policy-as-code DSL (
kind: policy) β author cross-resource, conditional, and aggregate rules as catalogue data (e.g. "every S3 bucket must have anaws_s3_bucket_logging"), without writing Python or vendoring Rego. A small, safe predicate language over the parsed resource model; findings flow through the same ID/urgency/SARIF/score/suppression pipeline. Seedocs/policy-dsl.md.
353 rules across six families. --list-rules enumerates them; --explain RULE-ID prints one in full.
| Family | Prefix | Focus |
|---|---|---|
| Security | SEC-* |
IAM over-grant, public exposure, hardcoded secrets, encryption gaps, exposed ports, MFA, key rotation |
| Robustness | ROB-* |
Missing prevent_destroy, no state locking, unversioned providers, missing backups |
| Stack | STK-* |
GKE/EKS/AKS hardening, RDS/CloudSQL config, Lambda DLQ/tracing, KMS rotation |
| Ops & Governance | OPS-*, MOD-*, COST-* |
Tags/labels, unpinned modules, supply-chain refs, cost controls |
| Cross-resource | INT-*, graph_check |
Intentβimplementation gaps, KMS location parity, IAM breadth |
| Module reuse (advisory) | MOD-REUSE-* |
Hand-rolled scaffolding that mirrors a popular Terraform Registry module β INFO tier, never gates CI. Pass --show-info to render |
Per-cloud breakdown (numerical parity across AWS, GCP, Azure as of 2026-05-13):
| Cloud | SEC | ROB | STK | OPS | COST | MOD-REUSE | Total |
|---|---|---|---|---|---|---|---|
| AWS | 62 | 13 | 12 | 2 | 1 | 1 | 91 |
| GCP | 41 | 5 | 42 | 1 | 1 | 1 | 91 |
| Azure | 56 | 7 | 25 | 1 | 1 | 1 | 91 |
| K8s/Helm | 12 | β | 6 | β | β | β | 18 |
| Cross-cloud / engine | β | β | β | β | β | β | 62 |
Why the per-section shapes differ at the same headline count. Each cloud puts services in different boxes, and the catalogue follows the provider taxonomy rather than forcing a synthetic split:
- AWS skews
SEC(62) because more discrete services have their own dedicated security rule β KMS, ECR, CloudTrail, GuardDuty, Security Hub, MSK, Neptune, DocDB, Athena, Cognito, Kinesis, SNS, SQS, Secrets Manager, SSM. Each surfaces a distinct misconfiguration class that maps 1:1 to a rule. - GCP skews
STK(42) because GCP rolls multi-feature platforms (GKE, Cloud Run, Cloud SQL, BigQuery, Composer, Dataproc) where hardening is expressed as stack-level configuration (release channels, workload identity, binary authorization, IAM auth flags, CMEK on the platform) rather than per-serviceSEC-*rules. - Azure skews
SEC(56) because Azure's policy / Defender / Synapse / Databricks story exposes many fine-grained controls (auth_settings_v2,microsoft_defender,data_exfiltration_protection_enabled,oms_agent, vault per-resource diagnostic settings, federated-identity-credential subjects) that each get their own rule. App-Service / Functions / Event Grid / Search platform hardening goes underSTK(25). ROBis small everywhere (13 / 5 / 7) because lifecycle and backup gaps map onto a small set of stateful resource shapes per cloud (RDS / Cloud SQL / Azure SQL + Cosmos + VMSS).OPS/COST/MOD-REUSEare deliberately 1-2 each per cloud β these tier-INFO/MEDIUM rules are about workflow ergonomics, not service depth, so one well-curated rule per cloud beats many redundant ones.
The headline number is parity. The shape is a property of each provider's product surface.
| Mode | Use case |
|---|---|
static (default) |
Full source scan β no credentials needed |
diff |
Changed files only, auto-detected base branch β ideal for PR CI |
plan |
Static + resolved values from terraform show -json |
fleet |
Multi-repo scan; surfaces organisation-wide patterns |
trend |
Walk git history; new/resolved/net per commit |
pr-review |
Post inline GitHub PR review comments with one-click suggestion blocks |
--format |
What you get |
|---|---|
text (default) |
One-line score header + findings list + attack-graph mermaid |
json |
Top-level summary block + findings; consumed by --compare, --baseline |
sarif |
SARIF v2.1.0 β line-level annotations on GitHub Code Scanning |
html |
Self-contained report with score banner, urgency badges, attack-graph SVG |
compliance |
CIS / PCI-DSS / SOC 2 / OWASP IaC PASS/FAIL per control (--compliance-framework <name>; --oscal PATH for OSCAL JSON). The owasp_iac framework maps the static-analysable items from the OWASP IaC Security Cheat Sheet. |
mitre |
Findings grouped by MITRE ATT&CK technique |
pr-summary |
GitHub-flavoured Markdown shape sized for PR descriptions / PR-bot comments β score banner, top-3 findings table (linked to docs site), top fix, collapsed Mermaid attack graph |
Every text, JSON, and HTML scan emits a deterministic 0β100 health score and letter grade A/B/B-/C/D/F. The score is the same number SKILL.md describes β _RISK_WEIGHTS and _GRADE_TIERS in scripts/detect.py are the single source of truth.
# tf-analyze: 82 (B) Β· 0 CRITICAL Β· 0 HIGH Β· 4 MEDIUM Β· 6 LOW Β· 0 INFO
"summary": {
"scoring_version": 1,
"score": 82,
"grade": "B",
"counts": {"CRITICAL": 0, "HIGH": 0, "MEDIUM": 4, "LOW": 6, "INFO": 0},
"suppressed_count": 0,
"formula": "max(0, floor(100 - sum(weight * count))); weights: CRITICAL=15, HIGH=7, MEDIUM=3, LOW=1, INFO=0; suppressed at half weight"
}Suppressed and baseline-suppressed findings count at half weight (acknowledged, but the underlying risk still exists). INFO findings carry weight 0. The scoring_version field pins the formula β weight changes bump it so downstream gates can detect breakage. CI gates use --fail-on LEVEL (the urgency tier) rather than gating on the grade, intentionally β the grade is for trend visibility, not pass/fail.
| Flag | Effect |
|---|---|
--fail-on LEVEL |
Exit 1 if any finding at LEVEL or above (CI gate) |
--baseline prior.json |
Ratchet against a snapshot β only NEW findings affect exit code |
--attack-graph |
Build internet β crown-jewels graph; promote critical-path findings |
--show-fixes |
Render fix_hcl inline with disruption badges |
--gen-tests OUTDIR |
Emit native .tftest.hcl assertion files |
--apply-fixes dry-run|apply |
Preview / write fix_hcl patches to source files |
--cache |
Incremental scan cache keyed on file + catalogue hash |
--diff-base REF |
Limit to .tf files changed since REF |
--no-hcl2 |
Disable the python-hcl2 fast-path (env: TF_ANALYZE_NO_HCL2=1) |
--show-info |
Render INFO-tier findings (e.g. MOD-REUSE-* module-reuse advisories). Default off β INFO is counted in summary.counts.INFO but not displayed |
--rank-by exploitability|hybrid |
Promote findings whose rule touches a CISA KEV-listed CWE one urgency tier; surface π₯ KEV badge in text/PR-summary/SARIF. Daily-cached at ~/.cache/tf-analyze/. Pair with --no-threat-intel for air-gapped CI. |
--explain-score |
Top-5 findings ranked by score impact, with projected score/grade if each is fixed. Tells you which fix is worth most. Surfaces as a header block in text output and a structured score_explanation field in JSON. |
--mode drift --state-json PATH |
Diff the static-HCL findings against terraform show -json state.tfstate output. Findings tagged mode='state' so oncalls can spot the gap between the HCL the team wrote and what's actually deployed. |
--pdf-output PATH |
Render the compliance gap report to a CISO-targetable PDF via weasyprint (optional dep). Pair with --compliance --compliance-framework <name>. |
--apply-fixes Γ --baseline |
When both are set, --apply-fixes skips findings already in baseline. Closes the "snapshot today, fix only new stuff" UX. |
--mode diff Γ --baseline |
Narrow to changed files AND filter against baseline tuples. Compose the two layers cleanly. |
Full CLI reference: docs/cli.md.
| Path | Doc | |
|---|---|---|
| GitHub Action (marketplace) | action.yml |
Published composite action β uses: ChrisAdkin8/tf-analyze@v1. SARIF upload, inline PR suggestion blocks, engine-rendered PR summary (--format pr-summary), optional compliance-framework / attack-graph inputs, pin via ref: or image: for reproducible CI. |
| GitHub Action (workflow template) | integrations/github-action.yml |
Alternative reference workflow that installs the engine from source instead of pulling the Docker image. Adds show-info input. Copy into your own .github/workflows/. |
| VS Code extension (v0.1.57) | vscode-extension/ |
Self-contained .vsix (engine + catalogue bundled). LSP-driven diagnostics, Quick Fix, status-bar score+grade badge, attack-graph + π blast-radius + module-reuse panels, bulk apply-fixes with diff preview, baseline suppression UI, vscode:// URI handler. Full feature list: docs/vscode-extension.md. |
| Score badge service | integrations/badge-service/ |
FastAPI app β embeddable SVG score badges per repo (https://<host>/score/<owner>/<repo>.svg); HMAC-signed /ingest endpoint accepts detect.py --format json output. Engineering complete; awaits flyctl deploy. |
LSP server (--lsp) |
scripts/detect.py --lsp |
docs/lsp.md |
| Docker image | ghcr.io/chrisadkin8/tf-analyze |
Multi-arch linux/amd64 + linux/arm64; bundles python-hcl2 |
| Web demo | demo/ |
FastAPI + CodeMirror 6 + d3 attack graph |
| Pre-commit hook | .pre-commit-hooks.yaml |
docs/pre-commit.md |
| HCP Terraform Run Task | integrations/run-task/ |
docs/run-task.md |
| MCP server (Cursor / Claude Desktop / Continue / β¦) | integrations/mcp-server/ |
FastMCP wrapper β scan_workspace, explain_rule, apply_fixes, attack_graph, compliance_report tools + tfanalyze://catalogue resource. stdio transport. Hardened against agent-side abuse: TFA_REPO_ROOT containment, <tf-analyze-output> envelope on every tool, finding/byte truncation caps. See integrations/mcp-server/README.md#hardening. |
| Terraform provider | terraform-provider/ |
data "tfanalyze_scan" data source β gates terraform plan/apply on a clean scan via precondition blocks, no external CI required. |
| Trend dashboard (R31.4) | tfanalyze.com/trend/<owner>/<repo> |
Hosted permalink rendering --mode trend output as a per-commit findings sparkline + new/resolved/net velocity table + biggest-jump annotation + OG preview card. Same per-SHA cache pattern as /scan/. ?lookback=N query param (clamped 7-365 days). |
| Auto-remediation bot (R31.2) | integrations/github-action-bot.yml |
GitHub Actions workflow that runs on a schedule, applies non-disruptive fix_hcl patches via the new --apply-fixes-max-disruption none engine flag, opens a single PR per repo (force-pushes tf-analyze-bot/auto-fixes). PR body groups fixes by rule family + names what was deliberately skipped. See integrations/github-action-bot/README.md. |
Additional screenshots: compliance report Β· fix-disruption badges Β· findings narrative panel.
| Topic | Doc |
|---|---|
| Full CLI reference (auto-generated) | docs/cli.md |
Authoring custom CUSTOM-* rules |
docs/custom-rules.md |
| LSP server (Neovim, Emacs, Zed, coc.nvim) | docs/lsp.md |
| HCP Terraform Run Task | docs/run-task.md |
| Pre-commit hook | docs/pre-commit.md |
| VS Code extension | docs/vscode-extension.md |
| Severity calibration methodology | docs/severity-calibration.md |
| Catalogue rule schema | catalog/README.md |
| Sample reports against terragoat | reports/README.md |
| Skill prose (LLM-facing instructions) | SKILL.md |
| Roadmap and TODO | TODO.md |
| Changelog | CHANGELOG.md |
| Blog (design notes, debugging tours, retros) | docs/blog/ |
When this repo is served via GitHub Pages (Settings β Pages β Deploy from branch: main / docs), the same content is reachable at https://chrisadkin8.github.io/tf-analyze/ with the blog at /blog/.
python3 scripts/detect.py --new-rule SEC-MYDOMAIN-001
# wrote catalog/SEC-MYDOMAIN-001.yaml
# wrote fixtures/sec_mydomain_001/main.tfEdit the two scaffolded files (TODO markers throughout), then run:
python3 -m pytest tests/test_fixtures.py -k sec_mydomain_001
python3 scripts/detect.py --explain SEC-MYDOMAIN-001
python3 scripts/detect.py --strict-catalog --target /tmp # validates schemaCatalogue schema: catalog/README.md. Custom-rule walkthrough: docs/custom-rules.md.
Three corpora that double as engine smoke tests and end-to-end demos for the surfaces that do graph reasoning across multiple resources. See examples/README.md for the chooser.
| Corpus | Purpose |
|---|---|
examples/terragoat/ |
Three-cloud intentionally-vulnerable corpus modelled on Bridgecrew's terragoat. Triggers ~295 findings across SEC / ROB / STK / OPS / COST domains. Broadest coverage; the right pick for first-time users. |
examples/module-reuse-demo/ |
Five hand-rolled VPC/network/AKS clusters across AWS / GCP / Azure that match popular community modules + two negative cases. Exercises the π¦ Module Reuse panel end-to-end with all three confidence-badge tiers visible. |
examples/attack-graph-demo/ |
Multi-tier AWS app: ALB β public EC2 β over-broad IAM role β S3 / Secrets / RDS. 19 nodes, 13 edges, 6 internet-reachable, 3 crown jewels. Exercises the π€ Attack Graph panel and the d3 demo. |
python3 scripts/detect.py --target examples/terragoat --format html > demo.htmlThe single-rule fixtures under fixtures/ (239 positive + 146 clean) complement these corpora β they isolate one rule each so a self-test failure points at exactly which detector broke. Drift on the demo corpora is gated by tests/test_examples_demos.py so a catalogue change that shifts the documented finding counts fails the local pytest run instead of silently breaking the README screenshots.
.
βββ SKILL.md # Skill prose loaded as /tf-analyze in Claude Code
βββ README.md # This file
βββ CHANGELOG.md # Per-round release notes
βββ TODO.md # Roadmap and backlog
βββ CONTRIBUTING.md
βββ LICENSE # MPL-2.0
βββ Dockerfile # ghcr.io/chrisadkin8/tf-analyze
βββ pyproject.toml
βββ install.sh # Symlinks repo into ~/.claude/skills/tf-analyze
βββ .pre-commit-hooks.yaml # pre-commit.com hook declaration
βββ .github/workflows/ # CI (ci.yml, docker.yml)
βββ catalog/ # 343 rule definitions (one YAML per rule)
β βββ README.md # Schema reference
βββ fixtures/ # 239 positive + 146 clean (negative) fixtures
βββ examples/ # Showcase corpora
β βββ terragoat/ # β’ Multi-cloud deliberately-vulnerable corpus
β βββ module-reuse-demo/ # β’ Module Reuse Advisor showcase (3 clouds)
β βββ attack-graph-demo/ # β’ Multi-tier AWS app for the Attack Graph
βββ scripts/
β βββ detect.py # Detection engine orchestrator (~3,000 LoC after R30.15 split)
β βββ _handlers_*.py # 51 detector handlers in 5 topic modules (generic / security /
β β # robustness / modules / infra) β registered into the engine
β β # by side-effect import
β βββ _hcl.py # HCL-parsing primitives (find_blocks, brace_walk, β¦)
β βββ _lsp.py # `--lsp` server entry point
β βββ _attack_graph.py # Attack-graph BFS + Mermaid render
β βββ _blast_radius.py # Blast-radius graph walker
β βββ self_test.py # Walks fixtures/ vs catalog/, asserts expected IDs
β βββ test_schema.py # Catalogue schema regression tests
β βββ stub-status.py # Reports stale `status: stub` entries
β βββ gen-cli-docs.py # Regenerates docs/cli.md from argparse
β βββ gen_clean_fixtures.py # Auto-scaffolds clean fixtures from fix_hcl
β βββ apply_mitre.py # Idempotent MITRE ATT&CK mapper
βββ tests/ # pytest suite (872 passing, 2 skipped)
βββ docs/ # User-facing documentation
βββ integrations/
β βββ github-action.yml
β βββ pre-commit-hook.yaml
β βββ run-task/ # HCP Terraform Run Task FastAPI server + Dockerfile
βββ vscode-extension/ # TypeScript extension (Quick Fix, attack-graph webview)
βββ demo/ # FastAPI + d3 web demo (deployable to Fly.io)
βββ reports/ # Example report outputs (delta-tracking demos)
βββ assets/ # Banner, icon
The skill files (SKILL.md, catalog/, scripts/, fixtures/, integrations/) live at the repo root so ./install.sh can ln -s the whole directory into ~/.claude/skills/tf-analyze β no nested skill/ subdir.
Contributions welcome β see CONTRIBUTING.md for the workflow.
Versioning note for the VS Code extension: every reference to a specific
tf-analyze-X.Y.Z.vsixfilename in user-facing documentation (this README's integrations table,docs/vscode-extension.md,vscode-extension/README.md) must always match the latestvscode-extension/package.json#version. Historical references inside changelogs and archived planning docs are exempt β they intentionally pin to the artefact that shipped at that version. Full rules and the version-bump checklist live inCONTRIBUTING.mdΒ§ VS Code extension version sync.
Routine maintenance commands:
python3 -m pytest tests/ # Full suite (~45s)
python3 scripts/test_schema.py # Catalogue schema regression
python3 scripts/stub-status.py --age 90d # Find stale stubs
python3 scripts/gen-cli-docs.py # Regenerate docs/cli.md after argparse changes
python3 scripts/gen_clean_fixtures.py --write # Auto-scaffold clean fixtures from fix_hcl
python3 scripts/gen_sample_reports.py # Regenerate reports/*.{md,json} from terragoatCI gate (.github/workflows/ci.yml) runs the pytest suite, the schema validator, the CLI-docs freshness check, and stub-status.py --age 180d. The Docker image is built and published on tag pushes via .github/workflows/docker.yml.
Built and exercised inside an HCP Vault + Consul + GKE platform engineering project; many catalogue rules trace to real audit findings on that infra. The skill is provider-agnostic in design β see the per-cloud breakdown under Detection for the current split. Full CIS Foundations Benchmark coverage on GCP; growing parity on AWS and Azure. Compliance output covers CIS, PCI-DSS v4.0, SOC 2 Trust Services Criteria, and the OWASP IaC Cheat Sheet.
Mozilla Public License 2.0. Catalogue rules and fixtures are released under the same licence to permit upstream contributions and downstream forks.



