Somewhere in your Terraform, there is probably a line that reads Action = "*" and Resource = "*". Someone wrote it to unblock themselves during a late-night debugging session, meaning to tighten it later. It got merged, applied, and forgotten. Today it is a role in your production account that can do anything to everything — and the only reason it has not caused an incident is that nobody has found it yet.
This is the quiet reality of managing cloud infrastructure as code. The same tooling that lets a small team stand up and manage enormous environments — Terraform, CloudFormation, Kubernetes manifests, Helm charts — also lets a single careless line define a serious security weakness, review it as casually as a variable rename, and ship it to production in minutes. Infrastructure-as-Code (IaC) scanning exists to close that gap: to catch the dangerous configuration while it is still a line in a pull request, before it becomes a live misconfiguration in a running account.
This article is for engineers and security practitioners who already know their infrastructure lives in code and who sense that it should be getting security review it currently is not. We will cover why IaC is such a potent source of cloud risk, the specific classes of misconfiguration that matter most (with IAM wildcards front and center), why catching them at the pull request is categorically better than catching them in a cloud posture scan after deployment, how IaC scanning fits into a real workflow, its honest limitations, and how the whole thing connects to the broader picture of cloud security.
Why infrastructure-as-code is a first-class security surface
For most of cloud computing’s history, infrastructure was something you clicked together in a console. That had obvious downsides — no version history, no review, no repeatability — but it had one accidental security property: changes were slow and visible. Someone had to log in and do something deliberate.
Infrastructure-as-code changed that trade completely, and overwhelmingly for the better. Your network topology, your IAM roles, your storage buckets, your Kubernetes resources — all of it is now declared in text, versioned in git, reviewed in pull requests, and applied by automation. This is a massive improvement in repeatability, auditability, and speed. But it also means that a security misconfiguration is now authored the same way a feature is: typed into a file, committed, reviewed (maybe), and deployed by a pipeline that has the access to make it real.
The implication is simple and often missed: your infrastructure code is exactly as security-sensitive as your application code — arguably more so. A SQL injection bug exposes one endpoint. An IAM role with Action: "*" exposes your entire account. A security group opened to 0.0.0.0/0 on a database port exposes your data tier to the internet. These are not application bugs; they are configuration defects, and because they are written in code, they can and should be caught the same way application bugs are caught — by scanning the code before it ships.
The reason this gap persists is organizational as much as technical. Application code has owners who think about security. Infrastructure code is often written by whoever needed the resource, reviewed by a teammate focused on whether the Terraform will apply cleanly, and merged. Nobody in that loop is necessarily asking “does this policy grant more than it should?” — and so the misconfiguration sails through a review that was never looking for it.
The misconfigurations that matter most
IaC scanning can flag a long list of issues, but a handful account for the overwhelming share of real cloud risk. Understanding these concretely is what lets you take the findings seriously rather than treating them as lint.
Over-permissive IAM — the one that matters most
Identity is the control plane of the cloud. A role’s permissions define its blast radius: if that role is ever assumed by an attacker — through a compromised workload, a leaked credential, or a vulnerable service — the damage is bounded by what the role can do. Which is why over-permissive IAM is the single most consequential class of IaC misconfiguration.
The canonical offender is the wildcard:
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
This grants every action on every resource. A role with this policy, attached to a workload, means that compromising the workload compromises the account. Variants are almost as dangerous: Action: "s3:*" on Resource: "*" (full control of every bucket), iam:* (the ability to escalate to anything by rewriting permissions), or a trust policy that allows Principal: "*" to assume the role. These are not exotic — they are what people write when they want something to “just work” and intend to scope it down later. “Later” rarely comes.
IaC scanning catches these at authoring time by reading the policy document and flagging wildcards, overly-broad actions, and dangerous trust relationships. The fix is usually straightforward once it is pointed out — enumerate the specific actions and resources the workload actually needs — but it only gets fixed if someone is told, and a human reviewer skimming a Terraform diff frequently is not the one to catch it.
Publicly-exposed resources
The second great category is unintended public exposure. A security group with an ingress rule of 0.0.0.0/0 on port 3306, 5432, 6379, or 27017 puts a database or cache directly on the internet. An S3 bucket with public-read ACLs or a public bucket policy exposes whatever it holds. An RDS instance with publicly_accessible = true does exactly what it says. A Kubernetes service of type LoadBalancer with no restrictions hangs a workload off a public endpoint.
Every one of these is a one-line decision in an IaC file, and every one of them has been the root cause of major, well-documented breaches. IaC scanning flags the public-exposure patterns so that “this bucket is public” is a pull-request comment, not a headline.
Missing encryption
Data at rest should be encrypted; data in transit should use TLS. IaC scanning checks that storage (S3, EBS, RDS, etc.) has encryption enabled, that keys are managed appropriately, and that resources are not accepting unencrypted connections. These findings are often low-effort to fix in code — frequently a single attribute — but easy to forget when standing up a resource quickly.
Logging and monitoring gaps
If CloudTrail is disabled, if flow logs are off, if a resource is not emitting the telemetry you would need to investigate an incident, you are flying blind. IaC scanning can assert that the audit and logging configuration your security program depends on is actually present in the infrastructure being deployed, rather than discovered to be missing during an incident.
Insecure defaults and drift from policy
Beyond the big categories, there is a long tail of provider defaults that are convenient but not secure, and organization-specific rules (“all resources must be tagged with an owner,” “no resource may be created outside these regions”). IaC scanning encodes these as policy and checks every change against them, so that the standards your team agreed on are enforced automatically rather than remembered inconsistently.
Why the pull request beats the posture scan
Here is the argument at the heart of IaC security, and it is worth laying out carefully because it is the reason to do this at all rather than relying solely on a cloud posture scanner.
You can find an over-permissive IAM role two ways. You can scan your running cloud with a Cloud Security Posture Management (CSPM) tool, which inspects the resources that actually exist and reports the wildcard role it finds. Or you can scan the Terraform in the pull request that is about to create that role, and flag it before it is ever applied. Both find the same problem. The difference in cost and consequence between them is enormous.
By the time a CSPM scan finds it, it is already real. The role exists, attached to a workload, in a live account. There is a window — however long until the next scan and the subsequent fix — during which the misconfiguration is exploitable. Fixing it now means a change to production infrastructure, which carries its own risk and process. And you have to figure out why it exists, who depends on it, and whether tightening it will break something — archaeology that the person who wrote it could have answered instantly at authoring time.
When IaC scanning finds it, it is still just text. The role does not exist yet. The developer who wrote the line is right there, in context, and can fix it in the same pull request with zero production risk, because nothing has been applied. The feedback loop is seconds, not “whenever the posture scan runs and someone triages the finding.”
This is the same shift-left logic that applies to application code, and it is just as valid for infrastructure: the earlier you catch a defect, the cheaper and safer the fix. A CSPM tool is still essential — it catches drift, resources created outside IaC, and changes made directly in the console, and it tells you the true current state of your cloud. But IaC scanning is what stops the misconfiguration from being created in the first place. The two are complementary, not redundant: IaC scanning prevents, CSPM detects what slipped through or was never in code. For the detection side, see our overview of cloud security posture management.
Fitting IaC scanning into a real workflow
The mechanics are straightforward once the intent is clear. IaC scanning runs where your infrastructure code is reviewed and where it is deployed:
- At the pull request. When a developer opens a PR that modifies Terraform, CloudFormation, or Kubernetes manifests, the scan runs against the changed files and posts its findings as review comments or a status check. A wildcard policy, a public security group, an unencrypted bucket — each shows up inline, at the relevant line, with an explanation and a suggested fix. The developer resolves it in the same PR.
- At the pipeline gate. The same scan runs in CI (Jenkins, GitHub Actions, GitLab CI, Azure DevOps) and can fail the build on serious findings, so a dangerous change cannot be merged or applied even if a human reviewer missed it. This is the enforcement backstop behind the advisory PR comment.
- As policy, versioned and consistent. The rules the scanner checks — both the standard security checks and your organization-specific ones — should themselves be defined in a consistent, reviewable way and applied the same across every repository, so the standard does not drift from team to team.
The design considerations mirror those of any pipeline check: fail the build on high-severity, clearly-dangerous findings (a wildcard IAM policy, a public database); surface the lower-severity and stylistic findings as informational; and provide a recorded exception path for the genuine cases where a finding cannot be resolved before a deadline, so that nobody’s answer is to silently disable the check.
The honest limitations of IaC scanning
To use IaC scanning well, you have to know what it cannot do, because over-trusting it creates a false sense of safety.
- It only sees what is in code. This is the big one. IaC scanning analyzes the infrastructure definitions in your repositories. It is blind to resources created by hand in the console, to changes made directly via the cloud API outside your IaC, and to drift between what your Terraform says and what actually exists. If half your environment was click-opsed into being, IaC scanning covers the other half. This is precisely why it complements rather than replaces a posture scanner that inspects the live account.
- Static policy analysis lacks full runtime context. An IaC scanner evaluating a policy document sees that the role grants broad permissions. What it does not natively know is whether that role is attached to an internet-facing workload or an isolated one, or what sensitive data sits behind the permissions it grants. The finding is correct — the role is over-permissive — but the severity depends on context that lives outside the IaC file. A wildcard role on a public-facing service is an emergency; the same wildcard on an isolated, never-exposed batch job is still worth fixing but is not the same fire. Severity that reflects this requires connecting the IaC finding to the runtime reality.
- It is not a substitute for reviewing intent. A scanner catches known-bad patterns. It will not tell you that a perfectly well-formed, least-privilege policy nonetheless grants access to the wrong team’s data because of a logic error only a human who understands the business would catch. IaC scanning raises the floor; it does not replace thoughtful review.
Knowing these limits is what keeps IaC scanning in its proper place: a powerful preventive control that catches the large, common classes of misconfiguration early and cheaply, operating alongside live posture detection and human judgment rather than in place of them. For the conceptual grounding, see infrastructure-as-code security.
The deeper payoff: closing the code-to-cloud loop
There is a reason IaC scanning is the most interesting bridge between “code security” and “cloud security,” and it is worth drawing out explicitly.
A permissive IAM policy in a Terraform file is a code finding — it lives in a repository, in a pull request. The over-permissive role it creates once applied is a cloud finding — it lives in your account, visible to a posture scanner. These are the same problem at two points in time: the intention expressed in code, and the reality it produces in the cloud. In most organizations, those two are handled by two different tools owned by two different teams, and nobody connects them. The AppSec-adjacent folks reviewing Terraform and the cloud team triaging posture findings are looking at two ends of one thing without realizing it.
When IaC scanning sits on the same asset graph as cloud posture, something better becomes possible. The Terraform finding and the resulting cloud misconfiguration are recognized as connected. Better still, the severity of the IaC finding can be informed by the runtime reality the resource will land in — so “this wildcard policy will be attached to an internet-facing workload that can reach your production database” is a very different, and correctly louder, finding than “this wildcard policy will be attached to an isolated internal job.” That is the whole idea of code-to-cloud security: the risk lives in the relationship between what the code says and where it runs, and seeing both on one graph is what makes the relationship visible.
How Cloudanix handles IaC scanning
The practices above stand on their own regardless of tooling. Cloudanix Code Security is built to make IaC scanning part of one connected picture rather than a siloed check.
Cloudanix scans Infrastructure-as-Code alongside SAST, SCA, and secrets detection, running at the pull request and in the CI pipeline (GitHub Actions, Jenkins, GitLab CI, Azure DevOps) with configurable quality gates that can fail a build on serious findings. It flags the classes that matter — over-permissive IAM including wildcard actions and resources, public exposure of storage and compute, missing encryption, and logging gaps — as review comments in the pull request, before the change is applied, with guidance on the fix.
The differentiator is that IaC scanning does not stand alone. Because Cloudanix is a CNAPP+ running code security and CSPM on a single asset graph, the preventive IaC check and the live posture detection are two views of the same environment, not two disconnected products. An IaC finding — the wildcard policy about to be created — is connected to the cloud reality it will produce, and when the layers are linked for a service, its severity reflects the real blast radius rather than the pattern in isolation. That closes the loop between the Terraform in the pull request and the role running in production, which is exactly the loop that over-permissive IAM exploits when it goes unnoticed.
To be precise about scope: IaC scanning sees what is in code, and the live posture view catches what was created outside it — the two together are what give you full coverage, and neither alone is sufficient.
If you want to see your own infrastructure code and cloud posture on one graph, connect a repository and a cloud account and watch the IaC findings line up against the live resources: book a free assessment.