← MCP server and skill grades

terraform-mcp-server

hashicorp/terraform-mcp-server

B
Type
MCP server
Scanned
Oct 29, 2026
Version
062700de87bb
Files read
401

The Terraform MCP Server is an official HashiCorp MCP server that lets AI agents query the Terraform Registry and manage HCP Terraform or Terraform Enterprise workspaces, runs, variables, teams, and projects. Its main risks are that it enables all toolsets and silently falls back to local Terraform CLI credentials (~/.terraform.d/credentials.tfrc.json) by default, and that its organization allowlist does not restrict ID-based tool calls.

What it can reach

Network
Makes outbound HTTPS requests to the public Terraform Registry (registry.terraform.io), GitHub raw content (raw.githubusercontent.com), and HCP Terraform or Terraform Enterprise (app.terraform.io or TFE_ADDRESS). Can also listen for HTTP connections in streamable-http mode and export telemetry to OpenTelemetry or Instana endpoints.
Files
Reads local Terraform CLI credentials from ~/.terraform.d/credentials.tfrc.json (or %APPDATA%/terraform.d/credentials.tfrc.json on Windows), reads optional TLS certificate and key files, and optionally writes logs to a user-specified file.
Secrets
Accesses Terraform API tokens from TFE_TOKEN, HTTP Authorization headers, or credentials.tfrc.json, as well as the optional TF_MCP_SHARED_SECRET environment variable.

Findings

3 medium2 low
  1. MediumAll toolsets are enabled by default and silently authenticate using local Terraform CLI credentials

    pkg/client/tfe_client.go:214

    Although the documentation states that only the public 'registry' toolset is enabled by default and that TFE_TOKEN is required for HCP Terraform tools, the '--toolsets' CLI flag actually defaults to 'all' (in pkg/cli/commands.go) and CreateTfeClientForSession automatically falls back to reading ~/.terraform.d/credentials.tfrc.json when TFE_TOKEN is not set. A user running the binary locally after 'terraform login' (or running streamable-http mode on a host with a credentials file) will expose authenticated workspace, variable, team, project, and run creation tools to the agent or unauthenticated HTTP clients without having provided TFE_TOKEN.

    Fix: Change the default value of the --toolsets flag to toolsets.Default ('registry'), and only read credentials.tfrc.json in stdio mode or when explicitly opted in via a flag or environment variable.

  2. MediumOrganization allowlist is bypassed by tools that take resource IDs instead of an organization name

    pkg/client/org_allowlist_tool_middleware.go:26

    When MCP_ORGANIZATION_ALLOWLIST is configured, the HTTP middleware only verifies that the bearer token can access at least one allowlisted organization, and OrganizationAllowlistToolMiddleware only checks the 'terraform_org_name' argument. More than 20 TFE tools (such as action_run, get_state_version, delete_workspace_safely, delete_project, delete_team, grant_team_access, and variable set tools) take a resource ID (like run_id, workspace_id, project_id, or team_id) without 'terraform_org_name'. If a user's token has access to both an allowlisted organization and another organization, prompt injection or tool calls can read and modify resources in the non-allowlisted organization.

    Fix: Require 'terraform_org_name' on all organization-scoped tools and verify that the fetched resource's organization matches the allowlisted organization before performing the operation, or resolve the resource's organization via the TFE API inside the allowlist middleware.

  3. MediumClients can disable outbound TLS certificate verification via HTTP header or query parameter

    pkg/client/middleware.go:360

    In streamable-http mode, TerraformContextMiddleware accepts TFE_SKIP_TLS_VERIFY from client HTTP headers and URL query parameters. An untrusted client can send 'TFE_SKIP_TLS_VERIFY: true' to disable TLS certificate verification on the server's outbound requests to HCP Terraform / Terraform Enterprise and the Terraform Registry, even when the server is using a server-side TFE_TOKEN.

    Fix: Source TFE_SKIP_TLS_VERIFY exclusively from the server's environment configuration rather than client-supplied HTTP headers or query parameters.

  4. LowBinding to 0.0.0.0 is treated as localhost and bypasses the TLS requirement

    pkg/client/tls.go:85

    The HTTP server requires TLS certificates when bound to a non-localhost address, but IsLocalHost treats '0.0.0.0' as localhost. Binding to 0.0.0.0 exposes the server on all network interfaces without TLS encryption.

    Fix: Remove '0.0.0.0' from IsLocalHost or require an explicit flag/environment variable to allow plaintext HTTP when binding to 0.0.0.0 in container environments.

  5. LowOpenTelemetry HTTP exporter always disables TLS

    pkg/otelmetrics/otelmetrics.go:51

    When OTEL_METRICS_ENABLED is set to true, the OTLP HTTP metrics exporter is initialized with otlpmetrichttp.WithInsecure(), sending telemetry over plaintext HTTP even if a remote collector endpoint is configured.

    Fix: Only use WithInsecure() when targeting localhost or when an explicit insecure environment variable is set.