Infrastructure Security

Terraform Provider Verification: Securing Your Infrastructure as Code Supply Chain

Terraform providers are plugins that execute with full access to your infrastructure credentials. Verifying their integrity is not optional.

Alex
Platform Security Lead
5 min read

Terraform providers are the interface between your infrastructure code and your cloud resources. The AWS provider manages your EC2 instances and S3 buckets. The Kubernetes provider manages your cluster resources. The GitHub provider manages your repositories.

These providers are plugins that Terraform downloads and executes. They run with whatever credentials Terraform has access to, which typically means broad infrastructure access. A compromised Terraform provider can read your cloud credentials, modify your infrastructure, and exfiltrate sensitive configuration data.

Despite this risk, most teams trust Terraform providers implicitly. They run terraform init, the providers download, and nobody verifies what was installed. This is a supply chain risk that deserves attention.

The Terraform Provider Trust Model

HashiCorp Registry

The Terraform Registry (registry.terraform.io) is the primary distribution channel for providers. It hosts official providers maintained by HashiCorp, verified providers maintained by technology companies (AWS, Azure, Google), and community providers maintained by individuals or organizations.

Official and verified providers undergo review by HashiCorp. Community providers do not. The distinction is visible in the registry UI but not enforced during terraform init, which downloads whatever provider your configuration requests.

Provider Signing

Terraform providers distributed through the registry are signed with GPG keys. Terraform verifies these signatures during download. Official providers are signed by HashiCorp's key. Verified and community providers are signed by their respective publishers' keys.

The key trust is established through the registry: Terraform downloads the provider's signing key from the registry and uses it to verify the provider binary. If you trust the registry, you transitively trust the keys it distributes.

Dependency Lock File

Terraform 0.14 introduced the .terraform.lock.hcl file, which records the checksums of downloaded providers. Subsequent runs verify providers against these checksums, ensuring that the same provider binary is used consistently.

This is important: commit .terraform.lock.hcl to version control. Without it, each terraform init could potentially download a different provider binary.

Verification Steps

Check Provider Source

Verify that your configuration references the correct provider source. A typo or intentional confusion could point you at a malicious provider:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

Verify the source namespace (hashicorp) and provider name (aws) match the official provider. An attacker could publish a provider named hashicorp-aws/aws or hashicorp/awss to catch typos.

Pin Provider Versions

Do not use unbounded version constraints. Pin to specific versions or use tight constraints:

# Risky - accepts any version
version = ">= 4.0"

# Better - restricts to a minor version range
version = "~> 5.31"

# Best - pins to an exact version
version = "= 5.31.0"

Exact version pinning ensures you know exactly what version is deployed and can review changes before upgrading.

Verify the Lock File

After running terraform init, examine .terraform.lock.hcl. It contains checksums for each platform:

provider "registry.terraform.io/hashicorp/aws" {
  version     = "5.31.0"
  constraints = "= 5.31.0"
  hashes = [
    "h1:abc123...",
    "zh:def456...",
  ]
}

These hashes verify provider integrity on subsequent runs. If the provider binary changes without the lock file being updated, Terraform will reject it.

Review Provider Changes Before Updating

When updating provider versions, review the changelog and release notes. Look for changes in maintainership, unexpected new capabilities, and modifications to how the provider handles credentials.

Use a Provider Mirror

For high-security environments, run a Terraform provider mirror that caches approved provider versions. Configure Terraform to use the mirror instead of the public registry:

# In .terraformrc
provider_installation {
  filesystem_mirror {
    path    = "/usr/share/terraform/providers"
    include = ["registry.terraform.io/*/*"]
  }
}

This gives you control over which provider versions are available to your teams and prevents unexpected provider downloads.

Securing Provider Credentials

Minimize Provider Permissions

Terraform providers execute with the credentials you provide. Follow least privilege: if your Terraform configuration only manages EC2 instances and S3 buckets, do not give the AWS provider administrator access.

Create IAM roles or service accounts with permissions scoped to exactly what Terraform needs to manage.

Rotate Credentials

Rotate the credentials used by Terraform providers regularly. Long-lived credentials that are compromised give attackers persistent access to your infrastructure.

Use short-lived credentials where possible: AWS STS temporary credentials, GCP workload identity federation, or Azure managed identities.

Protect State Files

Terraform state files contain sensitive data including resource attributes that may include passwords, connection strings, and other secrets. Store state files in encrypted, access-controlled backends. Never commit state files to version control.

Community Provider Risks

Community providers carry higher risk than official or verified providers. They may be maintained by a single individual, may not have undergone security review, and may use dependencies with known vulnerabilities.

Before using a community provider, check the provider's GitHub repository for activity, stars, and contributor count. Review the provider's source code, especially credential handling. Verify that the provider is actively maintained. Evaluate whether the functionality could be achieved with an official or verified provider instead.

How Safeguard.sh Helps

Safeguard.sh provides visibility into the supply chain of your infrastructure-as-code tooling, including Terraform providers and their dependencies. It tracks which provider versions are in use across your organization, identifies providers with known vulnerabilities, and monitors for changes in provider provenance that could indicate compromise. When a Terraform provider has a security issue, Safeguard.sh ensures you know which configurations and environments are affected.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.