Tutorial: IaC + cloud hardening
The repo scanner runs Trivy IaC and Checkov in parallel against Terraform, CloudFormation, Helm, Kubernetes manifests, and Dockerfiles. This tutorial walks through wiring the policy threshold, suppressing intentional exceptions, and turning the output into a control attestation.
Scenario
- Repo.
acme-co/infra— ~150 Terraform modules, ~80 Helm charts, three CloudFormation stacks. - Constraint. A handful of legacy modules cannot satisfy the CIS benchmark today — we need to suppress them with a recorded justification, not just disable the scanner.
- Goal. A clean scan + an audit trail of every suppression.
1. Run the scan
If the infra is in the same repo as application code, connecting the repo once enables IaC scanning automatically — both Trivy IaC and Checkov fan out as part of the standard repo scan.
If infra lives in a dedicated repo:
curl -X POST -H "Authorization: Bearer $PENCHEFF_API_KEY" \
"$PENCHEFF_API_BASE/repos/$REPO_ID/scan"The scan opens at /repos/scans/{id} with a per-scanner card
showing the Trivy IaC and Checkov counts.
2. Triage the noise
Both scanners default to flagging medium+. The Checkov rule pack
is broad, so the unified findings view will surface a long list on
the first run. Two paths to focus engineer attention:
- Filter at view time. The repo scan’s
severityfilter hides MEDIUM in one click. - Suppress recurring noise. For policy hits that you’ve already accepted, suppress them with a justification (next step) — suppressed findings stay in the database but don’t appear on the report by default.
3. Suppress with a justification
A finding can be suppressed with one of:
accepted_risk— known and accepted (recorded with reason- reviewer)
wont_fix— acknowledged but not in remediation scopefalse_positive— confirmed noiseduplicate— same root cause tracked elsewhereout_of_scope— outside agreed test scope
curl -X POST -H "Authorization: Bearer $PENCHEFF_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "accepted_risk",
"notes": "Dev cluster only — does not handle production data. Reviewed by SRE 2026-04-12."
}' \
"$PENCHEFF_API_BASE/findings/$FINDING_ID/suppress"Suppressions are logged with timestamp, user, and notes; they appear on the audit trail and survive re-scans.
4. Read the compliance rollup
/repos/scans/{id}/compliance — switch to NIST 800-53.
IaC findings (category: iac or misconfiguration) light up:
CM-6— Configuration SettingsCM-7— Least FunctionalitySC-7— Boundary Protection (when network-config flagged)
For PCI-DSS the same findings light up 2.2 / 6.2. For ISO 27001:2022
they hit A.8.8 / A.8.9.
5. Container hardening
When the repo also contains a Dockerfile, Trivy’s container
image scanner fans out automatically. Findings carry the offending
layer and the recommended fix line.
For images already in a registry (not in a connected repo), the MCP
host exposes scan_container_image as a one-shot tool — pass
the image reference (acme/api:1.42.0), it returns the same
finding shape as the repo-scan path.
Deliverable
- A clean repo scan you can attach to the next infra PR.
- A signed-off suppression list for the legacy modules.
- A NIST 800-53 control rollup the auditor can ingest as evidence.