Most cloud breaches are not exotic exploits; they are a public S3 bucket, a security group open to 0.0.0.0/0, an over-permissive IAM policy, an unencrypted volume.
Those misconfigurations live in Terraform, CloudFormation, and Kubernetes manifests, where a policy-as-code scanner catches the known-bad patterns and an LLM does the part scanners are weak at: explaining why a flagged config is dangerous in your specific architecture, reasoning about combinations no single rule sees, and drafting the least-privilege fix. The scanner is ground truth; the model is the analyst that turns findings into decisions. This playbook pairs them.
Run the policy scanner first and treat its output as fact; use the LLM to explain, prioritize, and fix — never to decide, on its own, that a flagged misconfiguration is acceptable.
Scan first with a policy-as-code tool. This is your grounding layer and it runs offline:
checkov -d infra/ --output json > /tmp/checkov.json
# or: tfsec infra/ --format json ; trivy config infra/
Hand the model the findings plus the IaC and ask for prioritized, explained risk:
You are reviewing Infrastructure-as-Code I own. Here are policy-scanner
findings and the relevant Terraform. For each finding:
- explain the concrete exposure in THIS architecture (who could reach
what, and how) — not the generic rule description
- rate real-world severity given surrounding context (is the resource
internet-facing? does it hold sensitive data?)
- give the minimal fix as a diff
Then, separately: identify any risks that arise from COMBINATIONS of
resources that no single finding flags.
FINDINGS: <paste checkov json summary>
TERRAFORM:
<paste the relevant .tf>
Expected output: per-finding exposure explanations grounded in your setup (e.g., "this SG opens 22 to the internet AND the instance has an IAM role with s3:* — an SSH compromise becomes bucket access"), context-adjusted severities, minimal fixes, and a combination-risk section.
Focus on least privilege for IAM. IAM is where scanners are noisiest and where the real damage lives. Ask specifically: "for each policy, what's the minimal permission set the resource actually needs, based on how it's used in this config?" and treat the answer as a proposal to verify against actual usage.
Apply minimal fixes and re-scan. Confirm the finding clears and no new one appears.
Record accepted risks explicitly. Where a finding is a genuine, deliberate exception (a load balancer that must be public), document it with a reason — that record is your audit evidence and your defense when someone asks later.
terraform plan — confirm the fix does what you intended and doesn't destroy-and-recreate something stateful.IaC reveals a client's cloud architecture, account IDs, and sometimes secrets in variables. Before prompting, strip real account IDs, ARNs, hostnames, and any secret from the snippet, and keep only the resource shapes the review needs. The scanners (Checkov, tfsec, Trivy) run entirely offline, so grounding never requires an external call — only the explanatory prose does. Where the client bars public tools, use a local model for that prose. Keep accepted-risk records in the client's own repo, and get per-client approval before any config leaves their boundary.