The Blast Radius Problem
A compromised Terraform Cloud workspace is not a developer-account compromise. It is a production-infrastructure compromise. The workspace runs with cloud credentials capable of destroying databases, exfiltrating state files that contain secrets, and deploying attacker-controlled infrastructure to your VPCs. In 2026, after a year of supply-chain attacks targeting IaC platforms specifically, this is the most underweighted threat model on most platform teams.
Terraform Cloud (now HCP Terraform) is the backbone of most mid-market and enterprise platform teams. It holds state, it holds variables, it holds the modules that describe production. The 2026 threat profile is specific: stolen API tokens, malicious modules, drifted state, and over-privileged workspaces. Every item on that list is addressable. Most teams address none of them because the defaults mostly work, and mostly-works is enough to get to a Series B.
This post covers the ten controls that turn a working Terraform Cloud setup into a secure one. It assumes you are already running HCP Terraform or Terraform Enterprise, with multi-workspace infrastructure, and that your platform team has 2–15 engineers.
Control 1: Workspace Isolation by Environment and Tier
The single most common misconfiguration is one workspace per environment and nothing more. Platform teams end up with a production workspace that holds the entire blast radius.
The pattern that scales: one workspace per environment and per tier, with tiers drawn along blast-radius lines. A typical split:
-
prod-networking— VPC, subnets, route tables, Transit Gateway -
prod-data— RDS, DynamoDB, S3 data buckets, KMS keys -
prod-compute— EKS, ECS, Lambda, ALB -
prod-edge— Route 53, CloudFront, WAF -
prod-identity— IAM roles, OIDC providers, SSO configuration
Each workspace has its own cloud credentials, scoped via IAM to only the resource types it manages. A compromise of the prod-edge workspace cannot drop your RDS instances.
Use workspace run tasks or Sentinel policies to enforce naming and tagging conventions. Every resource created by the prod-data workspace must carry a workspace:prod-data tag; anything else fails the plan.
Control 2: State Protection
Terraform state is a secrets file masquerading as JSON. It contains RDS passwords, IAM access keys (if you are still using them — you should not be), JWT signing keys, and enough cloud metadata to map your entire network from memory.
HCP Terraform stores state encrypted at rest by default. The controls you still need to add:
State locking — enabled by default; verify it. A workspace without state locking is a race condition waiting to happen.
State versioning with retention — default is unlimited. Keep the last 90 days and document the retention policy. Compliance auditors ask.
State file access restricted to the workspace service account only. In HCP Terraform, the Manage Workspace permission grants state download. Restrict this role to platform leads and SRE on-call; everyone else gets read-only workspace variables access via a separate role.
Client-side state encryption for sensitive workspaces. For workspaces that provision secrets-bearing resources (databases, KMS), wrap sensitive outputs in sensitive = true, and evaluate using the sops or vault provider to keep high-sensitivity values out of state entirely.
Control 3: OIDC Federation for Cloud Credentials
Long-lived AWS access keys, GCP service account keys, or Azure client secrets in Terraform Cloud variable sets are the largest remaining legacy risk in most platform setups. In 2026, OIDC federation is the expected default.
HCP Terraform now supports dynamic credentials for AWS, GCP, Azure, and Vault natively. The flow: HCP Terraform issues a signed JWT for each workspace run; your cloud IAM trust policy validates the JWT and returns short-lived session credentials scoped to that workspace.
Benefits:
- No cloud credentials stored in HCP Terraform
- Credentials expire with the run (no standing authorization)
- Audit logs in both HCP Terraform and your cloud provider
- No rotation toil
The migration cost is a few hours per cloud provider. If you have not done this, it is the single highest-leverage security change you can make in a week.
Control 4: Sentinel or OPA Policy-as-Code
Sentinel (HashiCorp’s native policy engine) and Open Policy Agent (via conftest or third-party integrations) are the mechanism by which you prevent humans and compromised tokens from doing damaging things with valid permissions.
The 2026 minimum-viable Sentinel/OPA policy set:
-
No public S3 buckets.
aws_s3_bucket_public_access_blockmust be fully restrictive;aws_s3_bucket_aclmust not bepublic-readorpublic-read-write. - No 0.0.0.0/0 ingress to non-HTTPS ports. Security groups and NACLs must not expose SSH, RDP, databases, or internal ports to the internet.
- Encrypted volumes only. EBS, RDS, EFS, Redshift — all encrypted, KMS CMK preferred over AWS-managed keys for regulated workloads.
-
IAM policies must not include wildcard actions + wildcard resources.
"Action": "*", "Resource": "*"is an immediate fail. -
Tags required. Every resource carries
team,service,env, andcost-centertags. - Module source restrictions. Modules may only come from your private registry or the official HashiCorp registry — no random GitHub forks.
Start with advisory mode (soft-fail) to measure impact. Move to hard-fail once noise is triaged. Keep policy-as-code in its own repo with its own CODEOWNERS and its own review requirements.
Control 5: Private Module Registry
A public module from a random GitHub org is a supply-chain attack vector. The 2025 fake-terraform-aws-modules incident — where a typosquat module added an exfiltration step to locals.tf — made this a board-level concern at several banks.
Use HCP Terraform’s private module registry or a self-hosted Terraform registry (tfe-registry, artifactory) for internal modules. Allow public modules only from a hardcoded allowlist of trusted sources: hashicorp/, terraform-aws-modules/, cloudposse/, GoogleCloudPlatform/. Enforce the allowlist via Sentinel policy on module source URLs.
Version-pin every module to a specific tag, never to main or a floating ~> constraint for top-of-graph dependencies in sensitive workspaces.
See the IAN team run on your cloud. We connect to your AWS account via a scoped read-only role, run the Observe-tier agents, and leave you with a concrete audit report — cost waste, security exposure, compliance gaps, and a labor-offset estimate. You keep the findings regardless of next steps. Get a free infrastructure audit →
Control 6: Drift Detection and Response
HCP Terraform’s drift detection (and the OSS equivalents — driftctl, terrafirma) runs periodic terraform plan comparisons against real cloud state and surfaces resources that were changed outside of Terraform.
Drift is a security signal, not just a correctness signal. A security group that suddenly has a 0.0.0.0/0:22 rule in AWS but not in Terraform state means someone opened SSH from the console and did not commit it. That someone may be a well-intentioned engineer, or it may be an attacker with console access. Either way, you want to know within hours, not months.
2026 playbook for drift:
- Run drift detection on every production workspace, at minimum daily
- Route drift alerts into the same incident channel as production pages
- Every drift event gets a ticket — either reverted, or documented as intentional-manual-change with an expiration date
- Report drift rates per workspace monthly; workspaces with chronic drift are a cultural problem, not a tooling problem
Control 7: Run Tasks for External Scanning
Run tasks in HCP Terraform let you hook external tools into the plan/apply lifecycle. The 2026 stack of run tasks worth configuring on every production workspace:
- tfsec or Checkov — static analysis on the plan output for known-bad patterns
- Infracost — cost impact of the plan, surfaced as a status check
- Bridgecrew / Prisma Cloud IaC — enterprise IaC scanning if you have it
- Snyk IaC — known CVE detection in provider versions
Gate applies on critical-severity findings. Advisory on lower severities. The status check on the PR that triggered the run is where your engineers read the results.
Control 8: OpenTofu Considerations
By Q2 2026, a meaningful fraction of platform teams are running OpenTofu alongside or instead of Terraform. OpenTofu’s state encryption feature — native, provider-agnostic state encryption that even HCP Terraform does not offer — is the single biggest differentiator for regulated environments.
If you are evaluating OpenTofu migration for security reasons specifically:
- State encryption with client-controlled keys is a real and material gain for FedRAMP, HIPAA, and EU-sovereign workloads
- Provider compatibility is near-complete; most modules work unchanged
- CI/CD compatibility requires the
opentofu/setup-opentofuaction; the flow is identical tohashicorp/setup-terraform - Policy-as-code with Sentinel is Terraform Cloud-specific; OpenTofu users should plan on OPA with
conftestor a dedicated policy service
The migration path for most teams is workspace-by-workspace, starting with non-production. Plan on 2–6 weeks of platform engineering time depending on module count and provider variety.
Control 9: Access Hierarchy and SSO
HCP Terraform’s team and role model is permissive by default. Tighten it:
- SSO/SAML required for all users; disable username/password
- Team membership synced via SCIM from your identity provider
-
Manage Organizationrole limited to 2–3 platform leads - Workspace permissions granted via team membership, never via direct user grants
- Read-only access is the default; write access is opt-in, role-scoped, and reviewed quarterly
- API tokens have the shortest practical TTL; use dynamic provider credentials instead of user API tokens for CI
Audit the team list monthly. Every team without an active owner gets archived. Every user whose HR status changed gets deprovisioned within 24 hours.
Control 10: Audit Logging and SIEM Integration
HCP Terraform’s audit log captures workspace changes, run triggers, variable changes, and permission changes. Pipe it to your SIEM.
The 2026 detections that are worth writing rules for:
- New API token created outside business hours
- Variable set changed with an unusual actor
- Workspace permissions elevated
- Module source changed in a production workspace
- First-time run from a new user account
None of these are high-volume signals. All of them catch real incidents. The cost to wire the audit log to Splunk, Datadog, or Elastic is a one-time configuration step.
How IAN Helps
IAN connects to your HCP Terraform organization (or self-hosted Terraform Enterprise) and reviews workspace configuration, variable sets, policy coverage, and recent runs. It flags workspaces missing OIDC federation, workspaces without Sentinel/OPA coverage, modules sourced from outside the allowlist, and variable sets that contain long-lived cloud credentials.
When it finds a gap, it opens a pull request against your policy-as-code repo — a new Sentinel rule to close the gap, a variable set migration to OIDC, a module source refactor to the private registry. Platform teams using IAN report that the first 30 days close roughly 80% of the Sentinel-policy coverage gap without any dedicated engineering time.
The Priority Order
If you can only do three things this month, do these three:
- Migrate cloud credentials from long-lived keys to OIDC dynamic credentials
- Apply the minimum-viable Sentinel/OPA policy set on every production workspace in advisory mode
- Enable drift detection on every production workspace and route alerts into your incident channel
Those three close the majority of the real attack surface. The rest of the controls are the difference between “working infrastructure” and “infrastructure that survives an audit.”
Next step: talk to the team
30 minutes. We'll look at your cloud together and scope what we'd take off your plate — see pricing.