CIS Terraform Enterprise Benchmark

Security configuration recommendations for HashiCorp Terraform Enterprise

v1.0.0 01-2025

Overview

▶

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.

16Recommendations
7Sections
2Profile Levels
SectionAreaFocus
1Organization Settings2FA enforcement, SAML SSO, and team least-privilege access
2Workspace SecurityAuto-apply controls, sensitive variables, and remote state sharing
3VCS & Run SecurityOAuth-based VCS integration and speculative plan enforcement
4Policy EnforcementSentinel and OPA policy sets with hard-mandatory enforcement levels
5API Token ManagementToken rotation and preference for team tokens over org tokens
6Network SecurityTLS certificate configuration and agent pool isolation
7Audit & LoggingAudit trail streaming and run/state version retention

Profile Definitions

▶
ProfileDescriptionIntended Use
L1Level 1 — StandardEssential security for all Terraform Enterprise deployments; minimal performance impact.
L2Level 2 — HardenedAdvanced hardening for PCI-DSS, HIPAA, or high-security environments.

1 — Organization Settings

▶

1.1 Organization Security

▶
1.1.1 Ensure two-factor authentication is enforced for all users (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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
Remediation
# 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_NAME
1.1.2 Ensure SAML SSO is configured (Automated)
L1 Auto
Description

This 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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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/settings
1.1.3 Ensure teams follow least-privilege principles (Automated)
L1 Auto
Description

This 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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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/teams

2 — Workspace Security

▶

2.1 Workspace Configuration

▶
2.1.1 Ensure auto-apply is disabled on production workspaces (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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_ID
2.1.2 Ensure sensitive variables are marked as sensitive (Automated)
L1 Auto
Description

This 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.

Rationale

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.

Audit
# 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}'
Remediation
# 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_ID
2.1.3 Ensure global remote state sharing is disabled (Automated)
L1 Auto
Description

This 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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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 workspaces

3 — VCS & Run Security

▶

3.1 Version Control

▶
3.1.1 Ensure VCS providers use OAuth applications (Manual)
L1 Manual
Description

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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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
3.1.2 Ensure speculative plans are enabled for pull requests (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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_ID

4 — Policy Enforcement

▶

4.1 Sentinel & OPA Policies

▶
4.1.1 Ensure policy sets are configured for security guardrails (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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}'
Remediation
# 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-sets
4.1.2 Ensure security policies use hard-mandatory enforcement (Automated)
L1 Auto
Description

This 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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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_ID

5 — API Token Management

▶

5.1 Token Security

▶
5.1.1 Ensure API tokens are rotated regularly (Manual)
L1 Manual
Description

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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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
5.1.2 Ensure organization-level tokens are avoided (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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'
Remediation
# 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

▶
6.1.1 Ensure TLS is configured with valid certificates (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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
Remediation
# 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
6.1.2 Ensure agent pools are scoped and isolated (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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-pools

7 — Audit & Logging

▶

7.1 Audit Configuration

▶
7.1.1 Ensure audit logging is enabled and streamed externally (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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
Remediation
# 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
7.1.2 Ensure run history and state versions are retained (Manual)
L1 Manual
Description

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.

Rationale

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.

Audit
# 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"}'
Remediation
# 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