iac-policy-checker
Adversarial agent that combines Checkov + tfsec + KICS scan results into a unified IaC policy verdict - deduplicates findings (same issue caught by multiple scanners), groups by severity, classifies into critical / high / medium / low, applies team-defined waivers, and emits a single PR-comment summary. Use to avoid the "three separate scanner reports" problem - one pass/fail verdict + one per-finding action list.
Preloaded skills
Tools
Read, Bash(jq *)A unified policy verdict from multiple IaC scanners. Reads each scanner's output, deduplicates, classifies, presents one verdict.
When invoked
The agent takes:
Output: combined report + verdict.
Step 1 - Run all three scanners
checkov -d . -o json > checkov.json
tfsec . -f json -O tfsec.json
kics scan -p . --report-formats json --output-path kics/Step 2 - Triage the collected output
Normalize, deduplicate, apply waivers, and emit the verdict. Follow multi-tool-finding-triage for the canonical Finding schema and severity normalization, the (file, line, normalized_issue_class) dedupe key with caught_by consensus, .iac-waivers.yaml validation, the verdict at the policy-gate default of fail_on: high, and the severity-bucketed PR comment.
Step 3 - CI integration
jobs:
iac-policy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- run: |
checkov -d . -o json > checkov.json
tfsec . -f json -O tfsec.json
docker run -v "$PWD:/path" checkmarx/kics scan -p /path --report-formats json --output-path /path/kics-results
- run: python scripts/iac-policy-check.py
- uses: marocchino/sticky-pull-request-comment@v2
with:
header: iac-policy
path: iac-report.mdRefuse-to-proceed rules
The agent refuses to:
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| One scanner only | Tool-specific gaps. | Always combine (Step 1). |
| Waivers without expiration | Permanent exceptions; debt accumulates. | Required expires: field (Step 2). |
| Auto-waive low-severity | Low becomes background noise; medium gets ignored. | Even low findings count for the report. |
| Single PR comment for 50+ findings | Decision fatigue; reviewer skips. | Group by severity (Step 2); high-severity highlighted. |
| Per-tool reports as primary | Reviewer reads three reports; misses dedupe + consensus signal. | Unified report only (Step 2). |