IaC Security: What it Catches and What it Misses
Most IaC security content sells scanning as the whole product: run a scan, catch the misconfigured resource, ship a clean report, move on. A scanner that flags a public bucket without telling you how many other resources actually depend on it gives you a checklist, not a security posture. The policy-as-code pitch that's a supposed fix has its own blind spot: it's excellent at blocking a known bad pattern but misses the blast radius of changes it approves.
Infrastructure as code (IaC) turned provisioning into software, inheriting software's failure mode along with the speed.
A developer who fat-fingers a security group by hand in the AWS console has made one mistake, contained to one resource. A developer who writes that same mistake into a Terraform module has made a mistake that ships every time the module gets called, across every environment that references it, until someone notices.
That multiplier is the main reason IaC security is a discipline in and of itself rather than a subset of general cloud security.
This guide defines IaC security, covering the specific risks it exists to catch, where those checks have to sit across a real pipeline, what the tool landscape looks like once the vendor marketing gets stripped away, and what policy-as-code buys you against what it costs.
By the end, you'll know exactly what effective IaC security looks like, which specific issue each layer of it solves, and when you will need to look for a solution elsewhere.
IaC security: checking the code before the cloud does
IaC security, or infrastructure as code security, is the practice of evaluating the configuration that provisions cloud infrastructure – in Terraform, OpenTofu, CloudFormation, Kubernetes manifests, or ARM templates – rather than evaluating the resources that configuration eventually produces.
A scanner reads the HCL or YAML, checks it against a library of rules, and flags a violation before anything gets applied.
In that way, IaC also has cybersecurity implications, not just engineering ones: it's the discipline that treats provisioning code as the artifact worth reviewing, the same way application security treats source code as the artifact worth reviewing.
Cloud security posture management and runtime monitoring involve you looking at deployed resources after the fact, catching drift, live misconfigurations, and active threats regardless of whether infrastructure as code produced them.
IaC security means you look upstream of that, at the template before it ever reaches an account. Both are worth doing, and neither substitutes for the other; a clean result from one may say nothing about the other.
The risks to manage with IaC security
Manual misconfiguration is bounded by what one person touched. IaC misconfiguration is bounded by how many times the module gets called, which becomes a much higher ceiling once a shared networking or compute module sits behind a dozen services. That mechanism is underneath every item on the risk list that vendors publish.
The security risks themselves are consistent across the industry, though the wording might change; you need to prioritize recognizing each one in the framing of IaC.
- Insecure default configurations and missing encryption. A storage resource or database provisioned without encryption at rest, or a default left open because the module never set an explicit value, ships identically everywhere the module gets consumed.
- Hard-coded secrets. Sensitive data like API keys, database passwords, and SSH keys committed straight into a
.tfor.tfvarsfile are readable by anyone with repository access and, once merged, by anyone who can read the commit history. - Ghost resources. Untagged or orphaned assets left behind after a test or a partial teardown accumulate cost, widening an already potentially broad attack surface every audit eventually has to account for.
- Excessive privileges. IAM roles and service accounts provisioned with broader permissions than the workload needs, usually because scoping them precisely took more time than the deadline allowed.
- Compliance violations. A resource that drifts out of alignment with compliance controls tied to a framework like PCI DSS or HIPAA surfaces the failure at audit time, long after the window to fix it cheaply has closed.
- Configuration drift. A change applied by hand outside the pipeline, often introduced by human error under incident pressure rather than by an attacker, diverges the running resource from what the code claims, and stays invisible until something forces a comparison between the two.
Drift is a genuine driver of costly production incidents: in Firefly's State of IaC 2026 report, a third of respondents tied drift directly to a costly incident, and 8% said it caused significant downtime.
You aren't only risking yourself to a sophisticated attacker. A template that reproduces the same gap everywhere it's used is what makes IaC security a different discipline than just reviewing one engineer's one-off change.
How to secure infrastructure-as-code pipelines
These risks sit inside a wider set of Terraform security practices spanning state files, execution access, and third-party modules, but the pipeline question is narrower and more mechanical: where does each check actually belong and what security best practices should you follow?
Bolting one scan onto one CI job and calling the pipeline secured is a path to failure, though it's an understandable one, since it's also the fastest thing to set up. Securing infrastructure-as-code pipelines properly has to work across multiple points, not one.
Feedback starts in the integrated development environment (IDE), where a plugin flags an obvious violation while the code is still being written, before it has traveled anywhere near a shared branch. It's the cheapest place for early detection, because the cost of a fix at this stage is a keystroke, not a re-review.
The pull request is the next gate. A scan that is triggered on commit or PR open should block or flag before merge, not after, while the scan's findings need to appear as a comment on the diff a reviewer is already looking at, not a separate report they have to go find.
Version control is important here too: an infrastructure change belongs in the same branch and the same review as the feature that needs it, not a separate change nobody connects back to the feature it was for.
The CI/CD pipeline build stage is where the deeper, slower checks belong: static analysis against a fuller policy set and secret scanning across the whole diff, plus anything too expensive to run on every keystroke back in the IDE.
You will also find the merits of least-privilege scoping here. A pipeline identity that can only touch the resources that specific run is managing effectively limits what a bad plan can actually do, regardless of what the configuration itself says.
Beyond merge, scheduled scans and drift checks cover what a point-in-time gate cannot: a resource that passed review on day one and diverged from its template on day forty.
If you treat this as optional, a clean pull request history can coexist with a genuinely unsecured environment, because nothing after merge was ever actually watching.
Once it's wired into every stage of the software development lifecycle (rather than one CI job near the end of it), security will stop being a separate gate you have to remember to run, and start being part of how your team is writing code in the first place.
The best IaC security tools
There's no single best IaC security solution. In fact, there are three categories, split by different jobs that don't substitute for each other.
Open-source static scanners
Open-source static scanners, Checkov chief among them, read a template or a generated plan and check it against a known rule library before anything is applied.
They're free, self-hosted, and genuinely good at the everyday list: open security groups, missing encryption, hard-coded secrets, and IAM policies with wildcard actions.
Checkov specifically has become a default choice for teams that want broad framework coverage without paying for a platform.
CI/CD-native and platform-integrated scanning
These tools provide a check of security issues that is built directly into the pipeline tooling already sitting inside your team's developer workflows, so there's no separate service to stand up or maintain. They trade some depth and customization for the lowest possible setup cost, since the scanning already lives where the pipeline lives.
Cloud-native application protection platforms (CNAPPs)
CNAPPs are the broadest category: IaC scanning shows up as one module inside a much larger platform that also covers runtime detection, posture management, and workload protection across the deployed estate.
That breadth is genuinely useful for a security team that wants a single surface to find security vulnerabilities, and CNAPP vendors also tend to blur pre-deployment scanning and post-deployment monitoring into a single offering, which makes the two jobs harder to evaluate separately.
For a deeper, tool-by-tool comparison across all three categories, check out our roundup sorted by IaC scanning category. The broader infrastructure as code tools landscape it sits inside covers provisioning and configuration management too.
How policy-as-code makes IaC security enforceable
Policy-as-code is the process of writing an organization's security and compliance rules as code, most commonly with Open Policy Agent (OPA) and its Rego language, so those rules get evaluated automatically against every template the same way the template itself gets scanned.
Start from rules that map to a real compliance control or an actual past incident, not an imported rule pack applied wholesale on day one. A policy nobody can trace back to a specific requirement is a policy nobody will defend when it blocks something legitimate.
Run new policies in warn-only mode first, so the team can see what would have failed before anything actually blocks a merge, and only flip to a hard gate once that backlog is visibly under control.
Version the policies themselves with the same discipline as the infrastructure code they govern; you don't want a policy that drifts from the infrastructure it's supposed to police.
A rule written for the general case eventually meets a legitimate, specific exception, and when it blocks that change, the fastest fix under deadline pressure is an override, not a rewrite of the rule.
Enough of those, and the gate trains people to route around it instead of relying on it. And a policy engine, however well-tuned, is still evaluating one template against one ruleset in isolation; it has no way to tell a reviewer whether the resource it just approved sits at the center of the dependency graph or off in a corner by itself.
A clean scan doesn't tell you everything
Every tool covered so far, whether a scanner or a policy engine, evaluates a template or a change in isolation. None of them reveal how much of the rest of your environment sits downstream of what the scan just flagged.
Stategraph approaches the challenge from the dependency graph rather than the flat file. Checkov is bundled directly into the product (a pinned, SHA256-verified version, meaning there's no separate CI step to wire up or maintain), and because Stategraph stores infrastructure as a graph instead of a flat state file, every finding it produces carries blast radius context: how many resources and modules are transitively downstream of the flagged resource, including across state boundaries a standalone scanner never sees.
stategraph tf plan surfaces which findings a pending change adds and which it resolves before anyone applies it, and findings carry lifecycle tracking (first seen and resolved) so posture over time is an actual trend rather than a snapshot compared manually against another snapshot.
Stategraph's scanning reads the configuration behind the state, not live cloud resources directly, and it doesn't do CVE scanning, container scanning, secrets scanning, or runtime threat detection, or perform auto-remediation. It doesn't enforce policy-as-code either, and it never blocks or gates an apply; it surfaces impact and leaves the decision with you.
Conclusion
IaC security needs more than just tool or one gate, and treating it that way is how your team ends up with a clean scanner report and a bad week.
Scanning catches the everyday list of misconfigurations before they ship. Policy-as-code makes an organization's own rules enforceable instead of aspirational, at the cost of the friction any enforced rule eventually creates.
Neither one, nor any CNAPP dashboard built on top of them, tells a reviewer how much of the environment actually depends on the resource a finding just flagged. Try Stategraph free and see what a scan looks like in the context of your own state.
IaC security FAQs
What is IaC in cyber security?
IaC in cyber security refers to treating infrastructure provisioning code, Terraform, OpenTofu, CloudFormation, and similar formats, as the artifact a security review has to cover, not just the application code that eventually runs on top of it.
Practically, that means scanning the configuration for hard-coded secrets and policy violations before it's ever applied. It is the same discipline application security applies to source code, aimed at a different layer.
Is IaC security the same as static application security testing (SAST)?
No, though the two get grouped together. SAST analyzes application source code for logic vulnerabilities like SQL injection or cross-site scripting, while IaC security analyzes infrastructure for the misconfigurations and policy violations that shape what a cloud resource looks like once it's provisioned. They have different inputs, different rule sets, and in most real pipelines, different stages entirely.
Does IaC scanning replace policy-as-code, or the other way around?
Neither replaces the other; they check different things. IaC scanning evaluates a template against a fixed library of known misconfiguration patterns, while policy-as-code evaluates it against rules an organization wrote for its own specific requirements, and most mature pipelines run both, scanning for the general case and policy-as-code for everything particular to that organization.