Secrets and sensitive values
The provider credential
The secret_key of the provider is the most powerful credential: it
controls the whole instance. Keep it out of committed files. Two safe
patterns:
# From the environment (for example through a secret manager):
CLERK_SECRET_KEY=$(op read "op://vault/item/secret_key") terraform apply
# Or through a sensitive variable:
variable "clerk_secret_key" {
type = string
sensitive = true
}
Secrets that land in state
Terraform state stores every attribute value, sensitive ones included. These attributes carry real secrets:
| Attribute | Behavior |
|---|---|
clerk_api_key.secret |
Read keeps it fresh; an import recovers it. |
clerk_machine.secret_key |
Same. |
clerk_oauth_application.client_secret |
Create-once; an import cannot recover it. |
clerk_jwt_template.signing_key |
Write-only; the state keeps your input. |
clerk_webhook.svix_url |
A short-lived dashboard login link. |
The provider marks them sensitive, so plans redact them. The state file
does not: treat the state itself as a secret. Store it encrypted, restrict
access to it, and never commit it.
Consume secrets from other resources
Reference the attributes directly; Terraform keeps the value inside the graph:
resource "clerk_api_key" "backend" {
name = "backend"
subject = var.service_user_id
}
# Example: hand the key to the platform that runs your API.
resource "dokploy_application" "api" {
# ...
env = "CLERK_API_KEY=${clerk_api_key.backend.secret}"
}
When you print such a value with an output, mark the output sensitive.
Rotation
clerk_api_key,clerk_machine: replace the resource (terraform apply -replace=...); the new secret flows through the graph.clerk_oauth_application: the same replace rotates the client secret.- The instance secret key of the provider rotates in the Clerk dashboard; Terraform does not manage it.