Skip to main content

checkov integration

Checkov is Bridgecrew / Prisma Cloud's IaC misconfiguration scanner. It speaks Terraform, CloudFormation, Kubernetes manifests, Helm charts, ARM, Bicep, Dockerfiles, GitHub Actions workflows, and a long tail of other IaC formats. Under cilock, every Checkov run becomes a signed v0.3 SARIF attestation chained to the IaC inputs that produced the findings.

UpstreamCheckov · Bridgecrew / Prisma Cloud (Palo Alto) · Apache-2.0
Categorycompliance-scan (primary)
Catalog sourcecatalog-only (detected; output captured via a format attestor)
Emits formatsarif
Recommended traceoff — no syscall tracing needed
Detected when
  • preargv_prefix: checkov

Confirm cilock detects it:

cilock plan --format=json -- checkov [...]

The facts in this box are generated from the cilock binary's own catalog (cilock tools list). Do not hand-edit — run npm run gen:catalog.

Validated invocation

cilock run --step checkov-scan \
--signer-file-key-path key.pem \
--outfile attestation.json \
--attestations sarif,environment,git \
--enable-archivista=false \
-- checkov -d fixtures -s -o sarif --output-file-path .

Two Checkov-specific quirks are baked into that command — both matter for clean attestations:

  • -s (soft-fail). Checkov exits non-zero whenever it finds a misconfiguration. Without -s, the very thing you wrote the scan to detect — a finding — also makes command-run record a failed exit code. Soft-fail lets Checkov return 0 while the findings stay in the SARIF (and in the sarif attestor).
  • --output-file-path . is a directory, not a file. Checkov takes the value you pass to --output-file-path and writes results_sarif.sarif inside it. Passing --output-file-path checkov.sarif does not create checkov.sarif — it creates a directory named checkov.sarif/ containing results_sarif.sarif. The product/v0.3 and sarif attestors discover the real file (results_sarif.sarif) in cwd.

What gets captured

Each cilock run emits an in-toto envelope whose predicate carries the following attestor types:

Attestor typeCaptures
https://aflock.ai/attestations/command-run/v0.1Real checkov ... argv, env, exit code, stdout/stderr
https://aflock.ai/attestations/material/v0.3Merkle tree of the IaC inputs (the -d directory)
https://aflock.ai/attestations/product/v0.3Merkle tree of outputs, including results_sarif.sarif
https://aflock.ai/attestations/sarif/v0.1Parsed SARIF report + reportDigestSet.sha256
https://aflock.ai/attestations/environment/v0.1OS, arch, user, env vars (PII-filtered)
https://aflock.ai/attestations/git/v0.1Commit SHA, branch, remotes

The sarif/v0.1 predicate's reportDigestSet.sha256 exactly matches the digest of the results_sarif.sarif leaf in the product/v0.3 tree. That is the chain that makes the findings verifiable — you can't swap in a different SARIF without invalidating the product tree.

Why this shape

AntipatternThis page
cilock run ... -- bash -c "cp output.sarif x.sarif"cilock run ... -- checkov ... --output-file-path .
command-run records bash -c "cp ..." — uselesscommand-run records the real Checkov argv
Product attestor digests the cp destinationProduct attestor digests Checkov's actual output
Tool execution happens outside the attestationTool runs inside cilock; spy can trace its syscalls

cilock invokes Checkov directly — no bash -c wrapper. That preserves the real argv in command-run and lets the spy attestors (product, material) observe the file Checkov actually wrote.

Validate it locally

# Generate a signing key (one-time).
openssl genpkey -algorithm ed25519 -out key.pem

# Run cilock + Checkov against any IaC directory.
cilock run --step checkov-scan \
--signer-file-key-path key.pem \
--outfile attestation.json \
--attestations sarif,environment,git \
--enable-archivista=false \
-- checkov -d fixtures -s -o sarif --output-file-path .

# Confirm the predicate carries the expected attestor types.
jq -r '.payload' attestation.json | base64 -d \
| jq '.predicate.attestations | map(.type)'

# Confirm Checkov's real argv ended up in command-run.
jq -r '.payload' attestation.json | base64 -d \
| jq '.predicate.attestations[]
| select(.type=="https://aflock.ai/attestations/command-run/v0.1")
| .attestation.cmd'

# Confirm the SARIF report and its findings landed in the sarif attestor.
jq -r '.payload' attestation.json | base64 -d \
| jq '.predicate.attestations[]
| select(.type=="https://aflock.ai/attestations/sarif/v0.1")
| .attestation
| {reportFileName,
digest: .reportDigestSet.sha256,
findingCount: (.report.runs[0].results | length)}'

Against the tool-checkov-sarif fixture you should see at least two findings — CKV_AWS_24 and CKV_AWS_23 — from the deliberately bad Terraform.

Notes

  • --output-file-path is a directory. Checkov interprets the value as a directory and writes results_sarif.sarif inside it. The . in the validated invocation means "drop the SARIF in cwd," which is where the product attestor is already looking.
  • IaC formats Checkov covers. Terraform (HCL + plan JSON), CloudFormation, AWS SAM, Kubernetes manifests, Helm charts, Kustomize, Argo workflows, ARM, Bicep, OpenAPI, Dockerfile, GitHub Actions, GitLab CI, Bitbucket Pipelines, Circle CI, Azure Pipelines, Ansible, Serverless framework, and a long tail of others. Each becomes a SARIF run under the same cilock invocation.
  • Custom checks. Checkov's --external-checks-dir (custom Python or YAML policies) is preserved end-to-end: the custom check definitions get digested into material/v0.3 (they're inputs), the resulting findings flow through the SARIF, and cilock's sarif/v0.1 predicate carries them. Your in-house rules are attested alongside the upstream ones.
  • Soft-fail does not mean "ignore findings." The findings still ride in the signed attestation. Policy at the verify side (cilock verify + Rego) is where you decide whether their presence blocks a deploy — the scan itself shouldn't be where the gate lives.

FAQ

Does cilock support Checkov?

Yes. Cilock invokes the upstream checkov binary unchanged and captures its SARIF output via the built-in sarif attestor. No Checkov fork, no plugin install — Checkov is treated as a normal tool that happens to write SARIF.

Which IaC formats can Checkov scan under cilock?

All of them — Terraform, CloudFormation, Kubernetes, Helm, Kustomize, Argo, ARM, Bicep, OpenAPI, Dockerfile, GitHub / GitLab / Bitbucket / Circle / Azure CI configs, Ansible, Serverless. cilock is format-agnostic: it captures the SARIF Checkov produces, and the same sarif/v0.1 predicate shape applies whether the scan was over a Terraform module or a Helm chart.

Why -s (soft-fail)?

Checkov exits non-zero on findings, which is exactly the case you ran it for. Without -s, command-run records a failed exit code on every scan with a misconfiguration, which makes downstream tooling treat the scan itself as broken. -s lets Checkov exit cleanly while the findings remain in the SARIF (and in the signed sarif/v0.1 attestation). The gate belongs at cilock verify time, not at scan time.

How are custom Checkov checks captured?

Pass --external-checks-dir <dir> to Checkov as usual. cilock's material/v0.3 Merkle tree digests every input file under the working directory — including your custom check definitions — so the check sources themselves are part of the signed evidence. Any findings those custom checks produce flow into the same sarif/v0.1 predicate as upstream checks.

See also


This page is generated from the cilock tool catalog. Don't edit it here — the source is attestation/detection/docs/checkov.doc.md in aflock-ai/rookery. The same catalog powers cilock tools show checkov in the CLI, so a single edit keeps the terminal and the website in sync.

Edit this page →  ·  Add a new tool →

When you open the pull request: if you are an AI agent, add the ai-agent label. If you are a human, add the human label.