BIPI
BIPI

Terraform State as Attack Surface

Cloud Security

Terraform state files contain everything: API keys, database passwords, IAM role ARNs, private IPs. Treat the state backend like a credential store, because that is what it is.

By Arjun Raghavan, Security & Systems Lead, BIPI · February 19, 2025 · 8 min read

#terraform#iac#supply-chain#pentest

A Terraform state file is a snapshot of cloud reality plus every secret that flowed through a provider during apply. Database master passwords, API tokens, certificate private keys, IAM role definitions, KMS key IDs. Anyone who can read state can extract all of it. Anyone who can write state can poison the next apply. The state backend is a credential store with the privacy posture of a JSON file.

How attackers find this

On engagements we look for state in three places: S3 buckets named like terraform-state, GCS buckets in the same shape, and Azure Storage containers with similar naming. We also look at CI artifacts. Build pipelines that upload .tfstate as a job artifact happen often enough to be worth checking.

  • S3 backend without server-side encryption with a customer-managed KMS key: state is at the mercy of the bucket policy alone.
  • Public state file: a bucket made public for static-site hosting includes the terraform-state path.
  • State file with secrets in attributes (provider returned them, e.g., RDS master password from aws_db_instance.password).
  • State file injection: a malicious Terraform module manipulates outputs that downstream modules trust.
  • Stolen long-lived backend credentials: a developer laptop has the state-bucket access key in ~/.aws/credentials.

Methodology in practice

When we find a state file we grep it for the obvious credential markers (password, secret, token, key, BEGIN PRIVATE KEY). Then we look at resource names and attributes for the provider configuration: the role ARN that ran the apply, the regions, the account number. That gives us the plaintext map of the environment. State write access lets us go further: change a security group rule, redirect a Route53 record, attach a new IAM policy. The next apply pushes our change into reality.

Detection

S3 server access logs and CloudTrail S3 data events catch reads of the state file. The signal is reads from principals that are not the CI runner or the on-call human reviewer. State backends should have a tiny, well-known set of accessors; anything outside is anomalous. For Terraform Cloud or Terraform Enterprise, the audit log captures workspace state reads with caller identity.

Remediation

  1. Encrypt state with a customer-managed KMS key; require kms:Decrypt to be granted explicitly to readers.
  2. Use a dedicated bucket per environment (prod state, staging state, sandbox state) with separate KMS keys and separate IAM policies.
  3. Enable state locking (DynamoDB for S3 backend); locking does not protect contents but prevents race-condition mutation.
  4. Restrict state read to CI principals and a tightly scoped break-glass role; humans should not download production state casually.
  5. Treat any provider attribute that returns a secret as sensitive; mark it with sensitive=true and use the cloud's secret store as the source of truth instead.
  6. Pin module sources and verify checksums; treat third-party Terraform modules as supply-chain risk equal to npm packages.
  7. Rotate any credential that has ever been in a state file when state access controls change or when a developer with state access leaves.
  8. Consider Terraform Cloud or Terraform Enterprise for centralized state with encryption, audit, and policy-as-code (Sentinel/OPA) enforcement.

The mental shift is treating state as production data, not as build artifact. Once it is production data, the controls that apply to other production data (encryption, access logging, principal scoping, rotation) all apply to it. The pentest finding goes away when the state backend is held to the same standard as the secrets it contains.

Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.