Secrets, Ephemeral Values, and Least Privilege

Protect credentials and state, distinguish sensitive from ephemeral values, and use provider-supported write-only inputs.

Advanced⏱ 3 min readLesson 13 of 16#terraform#security#secrets#ephemeral#iam

Protect the whole workflow

Secrets can appear in variable files, state, plan files, logs, outputs, and CI artifacts. Hiding a value in ordinary CLI output does not remove it from every artifact.

TechniqueWhat it providesLimit
sensitive = trueRedaction in ordinary displayValue may still be stored
Encrypted remote stateProtection of stored bytesAuthorized readers can read contents
Short-lived runner credentialsReduced credential lifetimeRunner still needs narrow permissions
Ephemeral valuesOmission from persisted Terraform state/planOnly permitted in compatible contexts
Write-only resource argumentsProvider input omitted from persisted artifactsProvider and resource must support them

Ephemeral input example

Terraform 1.10 introduced ephemeral input variables. In a supporting configuration:

variable "session_token" {
  type      = string
  sensitive = true
  ephemeral = true
}

This value must be used in a permitted ephemeral context, such as provider configuration or a write-only resource argument. You cannot use it as the ordinary content of local_file, because that resource value is persisted.

When applying a saved plan, ephemeral values needed during apply must be supplied again. Design runner credential renewal accordingly.

Write-only arguments

Terraform 1.11 added write-only resource arguments. The provider must implement them; adding _wo to an arbitrary argument name does not create support. For a resource offering a write-only password and companion version field, a password rotation typically supplies a new ephemeral password and increments the persisted version field so the provider performs the update.

Check the exact resource schema and provider release before using this pattern. Terraform cannot compare old and new write-only passwords because it does not retain them. See write-only arguments and ephemeral variables.

Least privilege for people and runners

Use identity federation such as OIDC for CI instead of long-lived access keys. Scope the trust policy to the intended repository, branch or protected environment, and token audience. Give the assumed role only the API operations and resources the root module needs.

State permissions are separate from application permissions. A runner with access to production state may learn secrets even if its cloud resource permissions are limited.

Separate plan and apply identities where practical. A plan often requires read access, but some providers or data sources need additional capabilities. Verify actual behavior rather than assuming all plans are strictly read-only.

Handle artifacts carefully

Commit the provider lock file; keep secrets out of Git. Protect plan artifacts with limited access and short retention. Suppress debug logs unless necessary; inspect them for sensitive content before sharing. terraform output -json and -raw can reveal sensitive output values.

Exercise: inventory every artifact in your proposed CI workflow. Who can read each artifact? What happens if an untrusted pull request modifies provider configuration or executes a malicious external data source?

Key takeaway: Terraform configuration is executable input to a privileged runner. Review changes to code and dependencies as part of infrastructure security.