No Terraform state in repo
On this page
Detect Terraform state committed to the repository. State files hold every
provider credential, connection string, and resource attribute in
plaintext - including values marked sensitive in configuration.
State belongs in a remote backend with locking, never in git.
What’s detected#
Two detection paths, content first:
| Path | Signal |
|---|---|
| Content | The document carries both "terraform_version" and "lineage" - present in every real state file regardless of Terraform version, so renamed state (backup/state.json) still fires |
| Filename | Basename ending .tfstate or .tfstate.backup (the automatic backup Terraform writes next to the state) |
Severity#
BLOCK. Committed state is a credential leak the moment it lands;
terraform { backend } configuration files are unaffected.
Detection scope#
- Triggers:
pre-commit,cli. - Applies to every scanned path. Binary files (NUL byte in content) and files over 1 MiB are skipped for the content path; noise dirs are excluded uniformly.
Failure message#
State content is never echoed.
✗ security/no-terraform-state-in-repo (security)
Terraform state committed (content redacted):
- infra/terraform.tfstate:0 - Terraform state content (terraform_version + lineage)
fix: remove the state from the push and rotate every credential it
contains; move state to a remote backend (S3 + locking, Terraform
Cloud, or your host's equivalent) and add `*.tfstate*` to .gitignore
Override#
Per-file disable (for a verified-sanitized fixture):
// appframes:disable security/no-terraform-state-in-repo
What’s NOT detected#
- Terraform configuration (
*.tf,*.tfvars) - configuration is meant to be committed; secrets inside.tfvarsare the value-matching frames' job. - Other IaC state (Pulumi checkpoints, CDK context) - candidates for a follow-up frame once their stable markers are catalogued.
- State inside archives - archive contents are not unpacked.
BLOCK rejects the push. Turn frames on per repo on the dashboard's Policy page - see choosing what the gate checks.
Source on GitHub Live demo How it works Questions: contact@nimblegate.com