DevSecOps: Scan Infrastructure Code for Misconfigurations with Checkov¶
Infrastructure code contains security misconfigurations. Open buckets, unencrypted databases, overly permissive access policies. Checkov scans IaC files across 20+ formats for these patterns before you deploy.
TL;DR: Install checkov, scan your IaC directory, configure your repository, and add it to your CI pipeline to catch infrastructure misconfigurations before they reach production.
Install checkov¶
Verify:
Scan a project¶
Basic usage: scan an entire directory recursively:
Scan a single file:
Checkov groups findings by resource type. AWS findings use CKV_AWS_XX IDs, Azure uses CKV_AZURE_XX, Kubernetes uses CKV_K8S_XX, and so on.
Configuration files¶
You can configure checkov with a YAML file in your repo:
The skip-check list matches --skip-check on the command line. The compact flag collapses findings and only displays failures.
Output formats¶
Checkov supports several output formats. The default is text. For CI integration, use JSON, SARIF, or JUnit XML.
# Default: human-readable text
checkov -d .
# JSON (parseable in CI)
checkov -d . -o json -o findings.json
# SARIF (GitHub Code Scanning, GitLab SAST)
checkov -d . -o sarif -o findings.sarif
# JUnit XML (for CI systems)
checkov -d . -o junitxml -o findings.xml
SARIF integrates with GitHub Code Scanning and GitLab SAST which renders findings as in-line annotations on the source files.
Add to CI/CD¶
The checkov-action with the github_failed_only output reports failures on the GitHub action page.
# .github/workflows/checkov.yml
name: Checkov
on: [pull_request]
jobs:
checkov:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Checkov
uses: bridgecrewio/checkov-action@v12
with:
output_format: github_failed_only
Understand the checks¶
Checkov has 750+ built-in policies across 20+ IaC types.
IaC formats¶
| IaC Type | Format | Suppression |
|---|---|---|
| Terraform / OpenTofu | .tf, .tofu, .hcl, .tfvars | # checkov:skip=CKV_AWS_21: reason |
| Kubernetes | .yaml, .json | checkov.io/skip1: CKV_K8S_20=reason |
| CloudFormation | .json, .yaml, .yml, .template | # checkov:skip=CKV_AWS_1: reason |
| Dockerfile | Named files (Dockerfile, Dockerfile.*, dockerfile) | #checkov:skip=CKV_DOCKER_1: reason |
| Bicep | .bicep | #checkov:skip=CKV_AZURE_1: reason |
| ARM Templates | .json | CLI only (--skip-check) |
| Ansible | .yaml, .yml, .json | #checkov:skip=CKV_ANSIBLE_1: reason |
| Argo Workflows | .yaml | checkov.io/skip1: CKV_ARGO_1=reason |
| Serverless Framework | .yml, .yaml | #checkov:skip=CKV_AWS_1: reason |
| AWS SAM | .yaml, .yml | #checkov:skip=CKV_AWS_1: reason |
| OpenAPI | .yaml, .json | // checkov:skip=CKV_OPENAPI_1: reason |
| Azure Pipelines | .yml, .yaml | #checkov:skip=CKV_AZUREPIPELINES_1: reason |
Auto-detected¶
Helm and Kustomize auto-detect config file presence, then template out to Kubernetes manifests for scanning. AWS CDK requires running cdk synth to generate a CloudFormation JSON template, which checkov then scans.
| IaC Type | Format | Suppression |
|---|---|---|
| Helm | Auto-detected by Chart.yaml presence | Via #checkov:skip on templates |
| Kustomize | Auto-detected by kustomization.yaml presence | Via #checkov:skip on templates |
| AWS CDK | Synthesized from .ts, .js, .py (cdk synth to JSON first) | CDK construct metadata |
VCS configuration¶
Checkov evaluates organization and repository settings from the respective APIs, not from code files. You need to provide a personal access token for each platform.
| IaC Type | Format | Suppression |
|---|---|---|
| GitHub Actions | .yml, .yaml | #checkov:skip=CKV_GITHUB_1: reason |
| GitHub Configuration | .json (fetched from GitHub API) | CLI only (--skip-check) |
| GitLab CI | .yml, .yaml | #checkov:skip=CKV_GITLABCI_1: reason |
| GitLab Configuration | .json (fetched from GitLab API) | CLI only (--skip-check) |
| Bitbucket Pipelines | .yml | #checkov:skip=CKV_CIRCLECIPIPELINES_1: reason |
| Bitbucket Configuration | .json (fetched from Bitbucket API) | CLI only (--skip-check) |
See the GitHub, GitLab, and Bitbucket scan examples for required environment variables.
Other¶
| IaC Type | Format | Suppression |
|---|---|---|
| SCA | .lock, .json, .txt, .xml, .toml (varies by language) | File-level comment in lock file |
| Git History | (repository commit history, not a file format) | CLI only (--skip-check) |
| Terraform Plan | .tfplan (Terraform plan output, not source) | CLI only (--skip-check) |
Checkov's full policy index is auto-generated from the source and available at Policy Index.
Takeaways¶
- Use
--skip-checkor.checkov.yamlfor known misconfigurations. Don't skip checks blindly. - Use
checkov:skipcomments to suppress individual findings in the code. Explain why. - SARIF output integrates with GitHub Code Scanning for inline annotations on source files.
- Run checkov in CI on pull requests. Prevent misconfigurations from reaching production.