Share a Checkov report
Checkov reads your Terraform, CloudFormation, Kubernetes manifests and Helm charts and tells you which of them will embarrass you later. Then it tells you in a pipeline log, in colour, 400 lines long.
The people who need to act on that — a platform lead, a security reviewer, the auditor asking for evidence — are not going to read a pipeline log. Terraform plan output has the same problem, and the same fix; see share a Terraform plan.
Get HTML out of it
Checkov has no HTML writer. Two conversions, both fine:
# via SARIF — the format the rest of your security tooling speaks
checkov -d . --output sarif --output-file-path .
pip install sarif-tools
sarif html results.sarif --output checkov.html
# or via JUnit XML, if your pipeline already consumes it
checkov -d . -o junitxml > checkov.xml
SARIF is the better intermediate: the same converter then handles Semgrep, Trivy and anything else in the pipeline that emits it, so you set it up once. See share a Semgrep report.
Publish it
checkov -d . --output sarif --output-file-path . || true
sarif html results.sarif --output checkov.html
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html checkov.html \
--arg title "IaC scan — $(git rev-parse --short HEAD)" \
'{title: $title, html: $html}')"
One call, no assets. checkov exits non-zero when it finds failures, so
the || true and an if: always() are load-bearing — a failing scan is
when the report matters. Use a scoped token
(reports:write) from CI secrets and PATCH a saved report id so one URL
accumulates a revision per scan. See publishing from CI.
Triage, on the finding
IaC findings are unusually argumentative, because a check that is correct in general is often wrong for your architecture:
CKV_AWS_18wants access logging on a bucket that exists to hold logs. Someone has to write that down once.- The public-read check fires on the bucket that is deliberately a public static site.
- The baseline scan of an account you inherited, with 300 findings you are burning down over two quarters — a shared document with a trend, not a gate.
Published to a URL, each of those is a thread anchored to the finding,
surviving across scans. The next engineer who trips CKV_AWS_18 on that
bucket finds the reasoning attached to it instead of re-deriving it or,
worse, quietly adding another skip-check comment. See
commenting on HTML.
Revision diffs give the burndown honestly: two scans, one diff, which findings actually cleared — as opposed to a count that dropped because someone widened a skip.
Treat it as sensitive
The report names resources, file paths and the specific misconfiguration. Access is per report: private, team, any signed-in user with the link, or public, with view / comment / edit rights for link holders. Default to team or private; use a link deliberately when handing it to an auditor. Password gates and expiring links are Enterprise. See sharing & access control.
Limits
- Entry HTML: 5 MB. A first baseline scan of a large estate can exceed it — publish by severity or by directory, which is how it gets read anyway. Assets: 25 MB per file, 250 MB and 500 files total.
- Scripts run, sandboxed (
allow-scripts, noallow-same-origin). - 60 requests/minute per token.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.