Quickstart
This page takes ctfkit by compliance.tf from access to two scans: one over a configuration before init, and one over a plan JSON. The first scan needs only the files. The second needs a root you can already init and plan, with your registry token and cloud credentials.
It is for platform engineers trying ctfkit on one root before wiring it into CI.
1. Get access and install ctfkit
Request access. The repository is private and readable once access is granted.
The download needs the GitHub CLI signed in to an account that has access, or GH_TOKEN set to a token with read access to compliancetf/ctfkit; either works. On Linux x86_64:
gh release download v0.2.1 --repo compliancetf/ctfkit \
--pattern 'ctfkit_0.2.1_Linux_x86_64.tar.gz' --pattern 'checksums.txt'
awk -v a='ctfkit_0.2.1_Linux_x86_64.tar.gz' '$2==a' checksums.txt | sha256sum -c -
tar -xzf ctfkit_0.2.1_Linux_x86_64.tar.gz ctfkit
sudo install -m 0755 ctfkit /usr/local/bin/ctfkit
ctfkit versionOn macOS with Apple silicon:
gh release download v0.2.1 --repo compliancetf/ctfkit --pattern 'ctfkit_0.2.1_Darwin_arm64.tar.gz' --pattern 'checksums.txt'
awk -v a='ctfkit_0.2.1_Darwin_arm64.tar.gz' '$2==a' checksums.txt | shasum -a 256 -c -
tar -xzf ctfkit_0.2.1_Darwin_arm64.tar.gz ctfkit && sudo install -m 0755 ctfkit /usr/local/bin/ctfkitctfkit version prints the release, the Go version it was built with and your platform:
ctfkit version 0.2.1
go version: go1.25.14
platform: linux/amd64For Windows, macOS on Intel, the .deb, .rpm and .apk packages and the pre-commit hook, follow the Install section of the ctfkit README.
2. Scan a configuration before plan
A pre_plan scan reads .tf and .tofu files as written. It needs no init, no credentials and no network:
ctfkit scan --stage pre_plan ./infraIt checks module sources, pinning, disabled controls and providers. A clean run prints:
All checks passed: no findings.
stage pre_plan, catalog 2026.9.3 (embedded)A run with findings lists each one, then a summary line. Here the configuration uses the upstream terraform-aws-modules/s3-bucket/aws module with version = "~> 3.0":
ERROR ctf.coverage.module_source
module.s3_bucket (non_ctf_module.tf:1)
Upstream terraform-aws-modules/s3-bucket/aws is a migration candidate; the same path is served under this organisation's framework host
fix: use soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws ~> 3.0
WARNING ctf.policy.floating_ref
module.vpc_from_git (non_ctf_module.tf:20)
Module source git::https://github.com/terraform-aws-modules/terraform-aws-vpc.git has no ref, so the code that runs can change without a configuration change
2 finding(s): 1 error, 1 warning, 0 note, 0 suppressed
stage pre_plan, catalog 2026.9.3 (embedded)
ctfkit: 1 finding(s) at or above errorThe error names the same module path on soc2.compliance.tf, the framework host that serves the SOC 2 build. The fix always names a framework host, picked with --remediation-host; Hosts and registry tokens explains framework hosts and your organization's host. In a pre_plan scan the fix keeps the version constraint your configuration already has, here ~> 3.0.
3. Scan a plan
A post_plan scan reads the plan as JSON. ctfkit never runs terraform or tofu, so produce the JSON first. init needs your compliance.tf registry token when the root uses compliance.tf modules, and plan needs the cloud credentials the root normally uses:
cd infra
terraform init # or: tofu init
terraform plan -out=tfplan # or: tofu plan -out=tfplan
terraform show -json tfplan > plan.json
ctfkit scan plan.json--stage auto, the default, picks post_plan because a plan was given. At this stage Terraform has already resolved variables, count, for_each and nested modules, so ctfkit also checks raw resources that a compliance.tf module covers, required tags and sensitive changes. Here a raw aws_s3_bucket has no module version to keep, so the fix gives the version the catalog recommends, ~> 5.0:
ERROR ctf.coverage.module_source
aws_s3_bucket.logs (main.tf:1)
Raw aws_s3_bucket where the compliance.tf module soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws exists
fix: use soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws ~> 5.0
1 finding(s): 1 error, 0 warning, 0 note, 0 suppressed
stage post_plan, catalog 2026.9.3 (embedded)
ctfkit: 1 finding(s) at or above errorWhen the plan file sits somewhere other than the configuration, name the configuration with --chdir so file and line anchors resolve: ctfkit scan --plan out/plan.json --chdir ./infra.
4. Read the output
Each finding has up to four parts. The fix: line appears only when a compliance.tf module closes the finding, so the WARNING above has none.
| Line | Meaning |
|---|---|
ERROR, WARNING or NOTE, then the rule ID | the level and the reference analyzer rule that fired |
address and file:line | the resource or module, and where it is declared |
| message | what was found |
fix: | the compliance.tf module source and version that close it, when one applies |
The exit code tells your pipeline what happened:
| Exit | Meaning |
|---|---|
0 | nothing at or above --fail-on (default error) |
1 | unsuppressed findings at or above --fail-on |
2 | environment error: unreadable input, invalid settings or an invalid flag |
To hand the findings to another tool, pick a format:
ctfkit scan plan.json --format sarif --out findings.sarif # code scanning
ctfkit scan plan.json --format json --fail-on never > findings.json # OPA or Conftest
ctfkit scan plan.json --format sarif,json,junit --out-dir out/ # several at onceNext steps
- Commands - every flag, the settings file and exceptions.
- Run checks in GitHub Actions or in Spacelift.
- Reference analyzers - what each rule checks and where it stops.