Insecure Generated IaC
It planned cleanly. It shipped public.
What Is Insecure Generated IaC?
An AI assistant can write infrastructure code that is valid, readable and applies without an error, and still leaves storage open to the internet. Here a generated bucket module ships through a pipeline that only checks whether it will apply. You'll read what the HCL actually allows, add a policy-as-code gate to the plan stage, watch it fail the shipped module, fix the code, and confirm an anonymous request is now refused.
What You'll Learn in Insecure Generated IaC
- Explain why a clean Terraform plan says nothing about whether a change is safe
- Read generated HCL for what it grants: public ACLs, encryption and policy actions
- Add a policy-as-code check to the plan stage so a failed rule stops apply
- Show that the gate fails the insecure module and passes the fixed one
- Confirm from outside that an anonymous request to the bucket is refused
Insecure Generated IaC — Training Steps
-
A bucket for customer uploads
Ines, the platform lead, has filed an issue in Jotvane, the team tracker: she needs storage for the portal's customer uploads, and she wants it as Terraform so the pipeline can ship it.
-
Open the repository
The editor opens the infrastructure repository: an empty module file for the bucket and the terraform workflow that plans each pull request and applies on merge.
-
Ask for the module
Open Claude and ask for the bucket module, the way Ines described it.
-
Five resources, cleanly written
Claude reads the empty module and the workflow, then proposes five resources: the bucket, its ownership and public-access settings, an ACL, and a policy for the upload service. It is tidy, idiomatic HCL, and the reply says it will plan cleanly.
-
Accept the module
Accepting lands Claude's module in main.tf . The gutter marks every line violet and unreviewed: written by the assistant, not yet read by anyone.
-
Initialise the module
Before the pull request goes up, run the same first step the workflow runs: initialise the module so Terraform has its provider and state backend.
-
It plans cleanly
Now the plan, the check the workflow runs on every pull request. If it matches Claude's promise, it shows five resources to add and no errors; the pull request goes green, Ines approves it, and the merge applies the module.
-
A bucket that answers strangers
Far from Rushmarle, a scanner that trawls the internet for storage answering anonymous requests flags the new bucket. It lists without a key, so every object in it is there for the taking. One recursive copy, no credentials, and the whole thing lands on a disk that is not Rushmarle's.
-
Customer files, downloaded anonymously
Marit from security has filed an issue. The bucket the module created was listed and downloaded overnight by someone with no Rushmarle credentials at all.
-
Add a gate to the plan stage
The workflow checks that Terraform can apply the code and nothing else. Add a policy-as-code step to the plan job: checkov scans the module before plan runs, and a failed check fails the job, so apply never starts.
Security Framework Coverage
OWASP Top 10
- A08:2025 Software or Data Integrity Failures
- A02:2025 Security Misconfiguration
CWE
- CWE-1188 Initialization of a Resource with an Insecure Default
- CWE-732 Incorrect Permission Assignment for Critical Resource
MITRE ATT&CK
- T1530 Data from Cloud Storage
CIS Controls
- CIS 4 Secure Configuration of Enterprise Assets and Software
- CIS 16 Application Software Security
NIST CSF
- PR.AT-02 Individuals in specialized roles are provided with awareness and training so that they possess the knowledge and skills to perform relevant tasks with cybersecurity risks in mind
- PR.PS Platform Security