CIS Terraform Enterprise Benchmark
Security configuration recommendations for HashiCorp Terraform Enterprise
v1.0.0 01-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for HashiCorp Terraform Enterprise deployments. It covers organization settings, workspace security, VCS integration, Sentinel/OPA policy enforcement, API token management, network security, and audit logging using the TFE API and replicatedctl administration.
| Section | Area | Focus |
|---|---|---|
| 1 | Organization Settings | 2FA enforcement, SAML SSO, and team least-privilege access |
| 2 | Workspace Security | Auto-apply controls, sensitive variables, and remote state sharing |
| 3 | VCS & Run Security | OAuth-based VCS integration and speculative plan enforcement |
| 4 | Policy Enforcement | Sentinel and OPA policy sets with hard-mandatory enforcement levels |
| 5 | API Token Management | Token rotation and preference for team tokens over org tokens |
| 6 | Network Security | TLS certificate configuration and agent pool isolation |
| 7 | Audit & Logging | Audit trail streaming and run/state version retention |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all Terraform Enterprise deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Organization Settings
▶1.1 Organization Security
▶This recommendation ensures that two-factor authentication is enforced for all users on the Terraform Enterprise infrastructure-as-code platform. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the Terraform Enterprise infrastructure-as-code platform may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Check organization settings via API:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/organizations/$ORG_NAME | \
jq '.data.attributes | {"cost-estimation-enabled", "collaborator-auth-policy", "two-factor-conformant"}'
# Via terraform CLI:
terraform login tfe.example.com
terraform show# Enforce 2FA at organization level:
curl -s -X PATCH -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"organizations","attributes":{"two-factor-conformant":true,"collaborator-auth-policy":"two_factor_mandatory"}}}' \
https://tfe.example.com/api/v2/organizations/$ORG_NAMEThis recommendation verifies that SAML SSO is configured on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check SSO configuration:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/admin/settings | \
jq '.data.attributes | {"sso-enabled", "saml-enabled"}'# Configure SAML SSO:
# Admin Console > Settings > SAML
# SSO Sign-On URL: https://idp.company.com/sso/saml
# Entity ID: https://tfe.example.com
# Certificate: Upload IdP X.509 certificate
# Force SAML authentication:
curl -s -X PATCH -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"admin-settings","attributes":{"saml-enabled":true}}}' \
https://tfe.example.com/api/v2/admin/settingsThis recommendation verifies that teams follow least-privilege principles on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List all teams and membership:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/teams | \
jq '.data[] | {name: .attributes.name, permissions: .attributes."organization-access"}'# Create team with minimal permissions:
curl -s -X POST -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"teams","attributes":{"name":"developers","organization-access":{"manage-workspaces":false,"manage-policies":false,"manage-vcs-settings":false,"manage-modules":false}}}}' \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/teams2 — Workspace Security
▶2.1 Workspace Configuration
▶This recommendation verifies that auto-apply is disabled on production workspaces on the Terraform Enterprise infrastructure-as-code platform. Disabling or removing unnecessary components reduces the attack surface and limits potential vectors for exploitation.
Running unnecessary components on the Terraform Enterprise infrastructure-as-code platform increases the attack surface and the risk of exploitation. Disabling or removing them follows the principle of least functionality and reduces exposure to known vulnerabilities.
# Check workspace execution mode and auto-apply:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/workspaces | \
jq '.data[] | {name: .attributes.name, "auto-apply": .attributes."auto-apply", "execution-mode": .attributes."execution-mode"}'# Disable auto-apply on workspaces:
curl -s -X PATCH -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"workspaces","attributes":{"auto-apply":false}}}' \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_IDThis recommendation verifies that sensitive variables are marked as sensitive on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check workspace variables for sensitive values:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_ID/vars | \
jq '.data[] | {key: .attributes.key, sensitive: .attributes.sensitive, category: .attributes.category}'# Mark variables as sensitive:
curl -s -X PATCH -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"vars","attributes":{"sensitive":true}}}' \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_ID/vars/$VAR_IDThis recommendation verifies that global remote state sharing is disabled on the Terraform Enterprise infrastructure-as-code platform. Disabling or removing unnecessary components reduces the attack surface and limits potential vectors for exploitation.
Running unnecessary components on the Terraform Enterprise infrastructure-as-code platform increases the attack surface and the risk of exploitation. Disabling or removing them follows the principle of least functionality and reduces exposure to known vulnerabilities.
# Check remote state sharing:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_ID | \
jq '.data.attributes | {"global-remote-state": ."global-remote-state"}'# Disable global remote state:
curl -s -X PATCH -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"workspaces","attributes":{"global-remote-state":false}}}' \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_ID
# Share state only with specific workspaces:
# Settings > General > Remote state sharing > Specific workspaces3 — VCS & Run Security
▶3.1 Version Control
▶This recommendation verifies that VCS providers use OAuth applications on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check VCS providers:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/oauth-clients | \
jq '.data[] | {name: .attributes.name, "service-provider": .attributes."service-provider"}'# Configure VCS with OAuth (not personal tokens): # Settings > VCS Providers > Add a VCS Provider # Use OAuth Application, not personal access token # Restrict to specific repos/branches
This recommendation verifies that speculative plans are enabled for pull requests on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check run triggers and speculative plans:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_ID | \
jq '.data.attributes | {"speculative-enabled": ."speculative-enabled", "queue-all-runs": ."queue-all-runs"}'# Enable speculative plans for PRs:
curl -s -X PATCH -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"workspaces","attributes":{"speculative-enabled":true}}}' \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_ID4 — Policy Enforcement
▶4.1 Sentinel & OPA Policies
▶This recommendation verifies that policy sets are configured for security guardrails on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List policy sets:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/policy-sets | \
jq '.data[] | {name: .attributes.name, "policy-count": .attributes."policy-count", global: .attributes.global}'# Create a Sentinel policy set:
curl -s -X POST -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"policy-sets","attributes":{"name":"security-policies","global":true,"kind":"sentinel"},"relationships":{"organization":{"data":{"type":"organizations","id":"'$ORG_NAME'"}}}}}' \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/policy-setsThis recommendation verifies that security policies use hard-mandatory enforcement on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check OPA/Sentinel enforcement levels:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/policy-sets/$POLICY_SET_ID/policies | \
jq '.data[] | {name: .attributes.name, "enforcement-level": .attributes."enforcement-level"}'# Set policy to hard-mandatory enforcement:
curl -s -X PATCH -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"policies","attributes":{"enforcement-level":"hard-mandatory"}}}' \
https://tfe.example.com/api/v2/policies/$POLICY_ID5 — API Token Management
▶5.1 Token Security
▶This recommendation verifies that API tokens are rotated regularly on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List API tokens for a team:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/teams/$TEAM_ID/authentication-token | \
jq '.data | {"created-at": .attributes."created-at", "expired-at": .attributes."expired-at"}'# Regenerate team tokens periodically: curl -s -X DELETE -H "Authorization: Bearer $TFE_TOKEN" \ https://tfe.example.com/api/v2/teams/$TEAM_ID/authentication-token curl -s -X POST -H "Authorization: Bearer $TFE_TOKEN" \ -H 'Content-Type: application/vnd.api+json' \ https://tfe.example.com/api/v2/teams/$TEAM_ID/authentication-token
This recommendation verifies that organization-level tokens are avoided on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check for organization-level tokens: curl -s -H "Authorization: Bearer $TFE_TOKEN" \ https://tfe.example.com/api/v2/organizations/$ORG_NAME/authentication-token | \ jq '.data.attributes'
# Use team tokens instead of org tokens: # Organization tokens have broad access; prefer team tokens # Delete org token if not explicitly needed: curl -s -X DELETE -H "Authorization: Bearer $TFE_TOKEN" \ https://tfe.example.com/api/v2/organizations/$ORG_NAME/authentication-token
6 — Network Security
▶6.1 Transport & Isolation
▶This recommendation verifies that TLS is configured with valid certificates on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check TLS certificate for TFE: openssl s_client -connect tfe.example.com:443 -brief 2>/dev/null | head -5 # Check TFE replicated console: replicatedctl app-config export | grep -i tls
# Configure TLS in TFE application settings: replicatedctl app-config set --key hostname --value tfe.example.com replicatedctl app-config set --key tls_cert_file --value /etc/tfe/ssl/cert.pem replicatedctl app-config set --key tls_key_file --value /etc/tfe/ssl/key.pem # Restart TFE: replicatedctl app stop && replicatedctl app start
This recommendation verifies that agent pools are scoped and isolated on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check network isolation (agents):
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/agent-pools | \
jq '.data[] | {name: .attributes.name, "organization-scoped": .attributes."organization-scoped"}'# Create isolated agent pools:
curl -s -X POST -H "Authorization: Bearer $TFE_TOKEN" \
-H 'Content-Type: application/vnd.api+json' \
-d '{"data":{"type":"agent-pools","attributes":{"name":"production-agents","organization-scoped":false}}}' \
https://tfe.example.com/api/v2/organizations/$ORG_NAME/agent-pools7 — Audit & Logging
▶7.1 Audit Configuration
▶This recommendation verifies that audit logging is enabled and streamed externally on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check audit log configuration: curl -s -H "Authorization: Bearer $TFE_TOKEN" \ https://tfe.example.com/api/v2/organization/audit-trail | \ jq '.data[:3]' # Export audit logs: curl -s -H "Authorization: Bearer $TFE_TOKEN" \ 'https://tfe.example.com/api/v2/organization/audit-trail?since=2025-01-01' \ -o audit-log.json
# Configure audit log streaming: # Admin > Settings > Audit Log Destinations # Add destination: Splunk / AWS S3 / Azure Log Analytics # Set up automated log export: # cron: 0 * * * * curl -s -H 'Authorization: Bearer $TFE_TOKEN' \ # 'https://tfe.example.com/api/v2/organization/audit-trail?since=$(date -d '-1 hour' +%Y-%m-%dT%H:%M:%S)' \ # >> /var/log/tfe/audit.json
This recommendation verifies that run history and state versions are retained on the Terraform Enterprise infrastructure-as-code platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Terraform Enterprise infrastructure-as-code platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check run history and state versions:
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://tfe.example.com/api/v2/workspaces/$WORKSPACE_ID/runs?page%5Bsize%5D=5 | \
jq '.data[] | {id: .id, status: .attributes.status, "created-at": .attributes."created-at"}'# Enable state version backups: # Configure external state storage backups # Use S3 versioning or Azure Blob versioning # Maintain run history for compliance: # Do not prune workspace runs within retention period