Infrastructure as code (IaC) has a supply chain: the providers, modules, images and scripts your templates download and run with cloud credentials. Secure it by pinning versions, committing lock files, pulling through a controlled registry, reviewing plans before apply, and limiting what the pipeline's credentials can change.
What are the dependencies in IaC?
Your Terraform, Pulumi or CloudFormation files look like configuration, yet they resolve external code. A typical configuration depends on providers (plugins that talk to a cloud API), modules written by other people, base machine images, container images and shell scripts called during provisioning. Each one runs with the permissions of whoever applies the change.
That is a stronger position than an ordinary library has. A compromised application dependency runs inside your app. A compromised infrastructure module can create users, open network rules and read secrets.
What does HashiCorp's own documentation warn about?
The Terraform documentation on the dependency lock file is specific. Terraform records provider selections in a file named .terraform.lock.hcl, and the docs recommend including it in version control. The same page says Terraform does not remember version selections for remote modules, and will always select the newest available module version that meets the constraint unless you pin it.
The practical meaning: an unpinned module reference can change between Tuesday's plan and Friday's apply, and nothing in your repository shows it.
Which attacks from the OWASP list apply?
OWASP's CICD-SEC-3, Dependency Chain Abuse, lists dependency confusion, dependency hijacking, typosquatting and brandjacking. All of them work against IaC registries too, because a module source is just a name. Its recommendations carry over directly: pull through an internal proxy, prefer pre-vetted versions over latest, enable checksum and signature verification, and register private packages under your organization's scope.
Where does build provenance fit?
SLSA, the Supply-chain Levels for Software Artifacts specification, describes provenance: verifiable information about where and how an artifact was built. For IaC, that means being able to say which commit and which pipeline produced the plan that was applied, and which module versions went in. Even without full SLSA levels, recording that chain makes an incident far easier to investigate.
Why is the plan not enough to catch this?
A plan shows what will change in your cloud account. It does not show what changed inside the module that produced the change. Reviewers read the diff of resources, not the diff of the module source, so a quiet edit upstream arrives looking like normal output. Reading module source on every update is unrealistic at scale, which is why pinning and a mirror matter more than vigilance.
What does a bad week look like?
Constructed example: a platform team references a community networking module with a loose version range. The maintainer's account is taken over and a new release adds a rule that allows one extra inbound port. The next scheduled plan shows a diff, but it is long, and the reviewer skims it. Pinned versions, a registry mirror and a policy that flags any new public ingress would each have caught it at a different stage.
How to check or apply this
- Pin every module and provider to an exact version, and commit the lock file. Update through a reviewed pull request.
- Mirror modules and providers in an internal registry, and block direct downloads from build runners where you can.
- Verify checksums and signatures where the ecosystem supports them.
- Run policy checks on the plan, not just the source: public ingress, wildcard permissions, unencrypted storage, new IAM principals.
- Give the apply job only the cloud permissions that stack needs. Separate state and credentials per environment.
- Treat base images and provisioning scripts like application dependencies: pin by digest and scan them.
- Keep records of what was applied, by which commit and pipeline run.
Safeguard's SBOM and dependency scanning, and policies and gates, can be pointed at the libraries and containers in the same repositories, so IaC does not become the unwatched corner of the supply chain.
Quick check
Does a lock file protect my Terraform modules?
Not by itself. The Terraform documentation says the lock file tracks providers, and that remote module versions are not remembered, so pin module versions explicitly.
Is IaC scanning the same as supply chain security?
No. Scanning templates finds misconfigurations. Supply chain security also covers where modules, providers and images come from and whether they changed.
Sources
- Terraform documentation, Dependency Lock File
- OWASP Top 10 CI/CD Security Risks, CICD-SEC-3 Dependency Chain Abuse
- SLSA specification, About SLSA
Last reviewed: 18 October 2026.