Reviewing Terraform IAM Changes With AI Before They Ship
IAM policy diffs are where Terraform plans quietly grant too much. AI is a sharp reviewer for privilege creep, if you feed it the right structured input.
- #terraform
- #ai
- #iam
- #security
- #review
The most dangerous lines in any Terraform PR are usually in an IAM policy, and they’re the lines reviewers skim hardest. A policy document is a wall of JSON-ish HCL, the diff is noisy, and "Action": "s3:*" looks roughly like "Action": "s3:GetObject" at 5pm on a Friday. That’s how * wildcards and "Resource": "*" slip into prod.
This is a near-perfect AI task. Models are good at reading structured permission documents and flagging over-grants — if you frame the question well and don’t expect them to know your intent. Treat the AI as a fast junior security reviewer: thorough, tireless, and in need of supervision. It reviews; you decide; and it never, ever gets the credentials to act on what it finds.
Why human IAM review fails
Three reasons IAM changes sneak through:
- Wildcards read like specifics.
iam:*andiam:PassRoleoccupy the same visual space. - The diff hides the union. A PR adds one statement, but the effective permission set is the merge of all statements plus attached managed policies. Reviewers see the delta, not the total.
- Intent isn’t in the diff. “This role needs to read one bucket” is in someone’s head, not the HCL.
AI helps with the first two directly and the third if you tell it the intent.
Give it the policy as data, not as a diff
Don’t paste a Git diff. Render the actual policy document and hand the model that, along with the stated purpose:
data "aws_iam_policy_document" "app" {
statement {
actions = ["s3:GetObject", "s3:PutObject"]
resources = ["${aws_s3_bucket.uploads.arn}/*"]
}
}
Then the prompt that matters:
This IAM policy is for a service whose only job is to read and write objects in the uploads bucket. List any permission that exceeds that purpose. For each, state the exact action and resource, and whether it could enable privilege escalation. Do not suggest fixes yet.
By stating the intended scope, you give the model the one thing the diff lacks. Now it can say “this iam:PassRole on * lets the service assume any role — that’s escalation, not object storage.” That’s a finding a tired human misses.
Make it hunt the specific anti-patterns
Generic “review this” gets generic answers. Give it the checklist that actually causes incidents:
Flag every occurrence of: action wildcards (
s3:*,*),Resource: "*",iam:PassRolewithout a resource constraint,sts:AssumeRolewith a permissive principal,NotAction/NotResource, and anyAllowthat grantsiam:*or*:*. Output a table: severity, statement, why.
# The AI should flag this hard:
statement {
actions = ["s3:*"]
resources = ["*"]
}
A wildcard action on a wildcard resource is the IAM equivalent of chmod 777 /. The model catches it instantly; the value is that it catches it on statement 14 of 30, where you’d have stopped reading.
Pro Tip: Ask the model to compare the policy against the actions the code actually uses. If the Terraform only ever calls GetObject and PutObject but the policy grants DeleteObject and ListBucket, that gap is dead permission — strip it. Least privilege is a diff between granted and used.
Trust-policy review is where the real escalation lives
Identity-based policies get the attention; trust policies (assume_role_policy) get the breaches. A too-broad principal lets the wrong account assume your role:
resource "aws_iam_role" "app" {
assume_role_policy = jsonencode({
Statement = [{
Effect = "Allow"
Principal = { AWS = "*" } # anyone, anywhere
Action = "sts:AssumeRole"
}]
})
}
Prompt the AI specifically: “Examine the trust policy. Who can assume this role? Is the principal scoped to a specific account, service, or external ID? Flag any * principal or missing condition.” Principal: AWS: "*" with no Condition is a public role. The AI names it; you fix it.
Have it propose least-privilege, then verify with plan
Once findings are agreed, let the AI draft the tightened policy. This is mechanical and it’s good at it:
statement {
sid = "ObjectRW"
actions = ["s3:GetObject", "s3:PutObject"]
resources = ["${aws_s3_bucket.uploads.arn}/*"]
}
But the proposal is just text until you run it through the pipeline. terraform plan shows the policy change; ideally your terraform test suite or a policy-as-code gate (OPA/Conftest, Sentinel) re-checks it deterministically. AI is the first-pass reviewer; the deterministic gate is the backstop. Never let the model’s “looks good” be the only signoff on a permission change.
The hard line: review only, never act
The AI reads policies and flags problems. It does not have an IAM role itself. It does not hold cloud credentials. It does not run terraform apply. It can’t tighten a policy in prod even if it wanted to — its entire output is reviewable HCL that goes through plan, gates, and a human. That separation is the security control. A fast junior reviewer pointing at risky lines is exactly what you want; a model with iam:* is the breach you were trying to prevent.
For an automated first pass on PRs like these, the code review dashboard applies a static pre-scan and risk floor before a human looks. Pair it with vetted prompts and prompt packs tuned for security review.
Conclusion
IAM is where Terraform plans quietly over-grant, and it’s where reviewers’ attention runs thinnest — a perfect spot for a tireless AI reviewer. Feed it the rendered policy plus the intended scope, make it hunt specific anti-patterns and trust-policy escalation, and back its findings with a deterministic gate. The model flags; a human and a policy engine decide; and the credentials stay far away from both. More guides at AI for Terraform.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.