Verified10 commandsAI-assisted

Checkov

.md

Verified against Checkov 3.3.15, flags verified via `checkov --help` run locally, 2026-08-29 · official docs

What it is and where it fits 🎯#

Checkov is the broadest IaC static analyzer in this series — unlike tfsec (Terraform-only), it covers Terraform, CloudFormation, Kubernetes manifests, Helm, Dockerfiles, Ansible, ARM/Bicep, Serverless Framework, GitHub Actions/GitLab CI pipeline definitions, and more, from one tool. It also blurs into SCA territory: --framework sca_package/sca_image runs dependency and image vulnerability checks alongside the pure misconfiguration checks, which is functionality that overlaps with Snyk/Trivy/Grype elsewhere in this set.

Installation#

pipx install checkov          # isolated, recommended if you manage multiple Python CLI tools
pip3 install checkov          # official docs' primary method
brew install checkov          # macOS/Linux Homebrew

checkov --version

Warning

CKV2 (graph-based) checks don't run under the Homebrew build — only under pip/pipx. If Checkov seems to be missing checks you'd expect (cross-resource checks that require understanding relationships between two Terraform blocks, not just one in isolation), confirm you're not on the Homebrew install before assuming the check doesn't exist.

Core concepts ⚙️#

  • Framework — the IaC/config type being scanned (terraform, kubernetes, dockerfile, sca_package, ...). A single checkov -d . run auto-detects and scans every framework present in the directory.
  • CKV vs BC check IDsCKV_AWS_20 is a Checkov-native check id; BC_AWS_GENERAL_20 is the same check's id on the Bridgecrew/Prisma Cloud platform. Both refer to the same underlying rule; --output-bc-ids swaps which id format is shown, useful when cross-referencing platform findings against local CLI output.
  • Graph checks (CKV2) — checks that need Checkov's dependency graph of the whole IaC tree, not just one resource block in isolation (e.g., "is this security group referenced anywhere with an overly permissive ingress rule attached").

Scanning#

checkov -d .                                  # scan a directory recursively, auto-detect all frameworks present
checkov -f main.tf                            # scan a single file
checkov -d . --framework terraform             # limit to one framework
checkov -d . --framework terraform,secrets
checkov -d . --skip-framework sca_package      # e.g. skip the slower dependency-scanning framework

Filtering checks#

checkov -d . --check CKV_AWS_20                          # run only this check
checkov -d . --check HIGH,CRITICAL                        # or filter by severity
checkov -d . --skip-check CKV_AWS_8,CKV_AWS_20
checkov -d . -c CKV_AWS_20 --skip-check LOW                # combine include + exclude (include list applied first, then exclusions)

Inline suppression, directly above the resource:

#checkov:skip=CKV_AWS_20:"reason this is an accepted exception"
resource "aws_s3_bucket" "example" {
  # ...
}

CI gating#

checkov -d . --soft-fail                       # always exit 0 — reporting only
checkov -d . --hard-fail-on HIGH,CRITICAL       # non-zero exit only for these severities, everything else soft
checkov -d . --soft-fail-on LOW                  # inverse: only LOW is non-blocking

Note

Default (no -s/--hard-fail-on/--soft-fail-on) is a hard fail on any finding — non-zero exit whenever a single check fails, regardless of severity. Same "fails by default" behavior as tfsec, the opposite of Trivy/Grype's "reports by default" behavior — worth knowing before wiring three different scanners into one pipeline and being surprised only one of them blocked the build.

Output formats#

checkov -d . -o json --output-file-path console,results.json     # multiple outputs, one to console + one to a file
checkov -d . -o sarif                                              # for GitHub code scanning
checkov -d . -o cyclonedx_json                                     # SBOM-shaped output for the sca_package/sca_image frameworks
checkov -d . --compact                                             # hide code snippets in CLI output
checkov -d . --quiet                                                # only show failed checks

Sample output shape (illustrative — actual check counts/IDs depend entirely on the scanned IaC):

terraform scan results: Passed checks: 20, Failed checks: 3, Skipped checks: 0 Check: CKV_AWS_18: "Ensure the S3 bucket has access logging enabled" FAILED for resource: aws_s3_bucket.example File: /main.tf:3-8 Guide: https://docs.bridgecrew.io/docs/s3_13-enable-logging 3 | resource "aws_s3_bucket" "example" { 4 | bucket = "my-bucket" 5 | }

Baselining existing findings 💡#

checkov -d . --create-baseline               # snapshot current findings into .checkov.baseline
checkov -d . --baseline .checkov.baseline      # only report NEW findings vs. the baseline

Tip

This is the practical way to adopt Checkov on a large pre-existing codebase without a wall of noise on day one. Baseline the current state, wire the baseline-diff mode into CI immediately, and tackle the backlog on its own timeline — new misconfigurations still get caught right away, existing debt doesn't block anyone.

Listing available checks#

checkov --list                                # every built-in check, by ID and framework

Real-world scenario: scanning a Dockerfile alongside its Terraform#

A service's IaC repo often has both the infrastructure definition and the Dockerfile in one place. Checkov's multi-framework auto-detection means one invocation covers both without separate tool invocations:

checkov -d . --framework terraform,dockerfile,secrets

This single command catches a misconfigured S3 bucket, a Dockerfile running as root, and a hardcoded secret in the same pass — a genuinely useful "first thing to run against a new service repo" default.

Real-world scenario: GitHub Actions CI recipe#

# .github/workflows/checkov.yml
name: Checkov
on: [pull_request]
jobs:
  checkov:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: bridgecrewio/checkov-action@master
        with:
          directory: .
          framework: terraform,dockerfile,kubernetes
          output_format: sarif
          output_file_path: reports/results.sarif
          soft_fail: false
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: reports/results.sarif

Common pitfalls#

  • Installing via Homebrew and losing CKV2 checks silently — see the WARNING above.
  • Assuming "fails by default" applies elsewhere — it's the opposite of Trivy/Grype.
  • Not scoping --framework on a very large multi-purpose repo — an unscoped checkov -d . on a monorepo with unrelated non-IaC content can be noticeably slower than necessary; narrow the framework list to what's actually present.

Exit codes#

0 clean, or --soft-fail set · non-zero when a check fails and isn't soft-failed.

When to reach for something else#

For pure Terraform, tfsec/trivy config are lighter-weight and faster. Checkov's advantage is genuine multi-framework breadth (Ansible, Bicep, Serverless Framework specifically) that neither of those cover — reach for Checkov when the IaC footprint spans more than Terraform/Kubernetes/CloudFormation/Dockerfile.