Secretless Terraform Authentication
The Defakto Terraform provider can authenticate using Workload Identity Federation (WIF). An OIDC token from your CI/CD platform is exchanged for a service account session, removing the need for a long-lived Ed25519 private key.
Prerequisites
- A Defakto Administrator account to register the WIF issuer
- A Defakto service account with a role appropriate for your Terraform operations
- A CI/CD platform or environment that issues OIDC tokens
Step 1: Register a WIF issuer
Using the Defakto Administrator account, register the OIDC provider as a trusted WIF issuer:
spirlctl iam wif-issuer set "my-platform" https://issuer.example.com
Example output:
WIF issuer "my-platform" set successfully.
ID: owi-def8901234
Name: my-platform
Issuer URL: https://issuer.example.com
Key Source: auto-discover
For Terraform Cloud, use https://app.terraform.io as the issuer URL.
Alternatively, manage the issuer as a Terraform resource:
resource "spirl_org_wif_issuer" "platform" {
name = "my-platform"
issuer_url = "https://issuer.example.com"
}
Step 2: Attach a WIF Configuration to your service account
As a service account owner (or an administrator) attach a WIF Configuration specifying which identity from your OIDC provider is allowed to authenticate as this service account. Every claim listed must be present in the token with an exactly matching value.
spirlctl iam service-account wif-config set my-service-account my-platform \
--claim <claim-name>=<claim-value>
The available claims depend on your OIDC provider. For example, with Terraform Cloud's workload identity token:
spirlctl iam service-account wif-config set my-service-account terraform-cloud \
--claim terraform_organization_name=my-org \
--claim terraform_workspace_name=my-workspace
Example output:
WIF config set successfully.
ID: sawif-tyce2dfe3
Service Account: sa-1123j3k2
Issuer: owi-def8901234
Allow Any Bearer: false
Claims:
terraform_organization_name = my-org
terraform_workspace_name = my-workspace
Scope claims as tightly as practical to limit which identities can authenticate as this service account.
Alternatively, manage the WIF Configuration as a Terraform resource using spirl_service_account_wif_config. Use the spirl_service_account data source to look up the service account ID by name:
data "spirl_service_account" "deployer" {
name = "my-service-account"
}
resource "spirl_service_account_wif_config" "deployer" {
service_account_id = data.spirl_service_account.deployer.id
org_wif_issuer_name = spirl_org_wif_issuer.platform.name
claims = {
terraform_organization_name = "my-org"
terraform_workspace_name = "my-workspace"
}
}
Step 3: Configure the Terraform provider
Retrieve the service account ID:
spirlctl iam service-account info my-service-account
Pass the ID to the provider via a Terraform variable:
variable "service_account_id" {
description = "Service account ID (e.g. sa-wi00vs0sm3). Retrieve with: spirlctl iam service-account info <name>"
}
Choose how to supply the OIDC token:
- Environment variable
- Terraform Cloud
- Provider attribute
Set an environment variable named SPIRL_OIDC_TOKEN in your CI/CD workspace with the OIDC token as its value. The provider reads it automatically:
provider "spirl" {
service_account_id = var.service_account_id
}
Terraform Cloud injects the workload identity token into every run as the environment variable TFC_WORKLOAD_IDENTITY_TOKEN (HCP Terraform docs). The provider reads that variable automatically, so no additional token configuration is needed:
provider "spirl" {
service_account_id = var.service_account_id
}
Pass the OIDC token explicitly using the oidc_token provider attribute. This is useful when you want to source the token from a Terraform variable:
provider "spirl" {
service_account_id = var.service_account_id
oidc_token = var.oidc_token
}
variable "oidc_token" {
description = "OIDC token from the CI/CD platform."
sensitive = true
}
Set TF_VAR_oidc_token as an environment variable in your CI/CD workspace with the OIDC token as its value.
When both service_account_id and an OIDC token are resolved, the provider uses WIF token exchange to authenticate instead of key-based authentication. The two authentication modes are mutually exclusive.
How it works
When Terraform runs, the provider:
- Resolves
service_account_idfrom the provider configuration and the OIDC token from the provider configuration,SPIRL_OIDC_TOKEN, or (on Terraform Cloud)TFC_WORKLOAD_IDENTITY_TOKEN. Both values are required. - Calls
ExchangeTokenon the Defakto control plane, passing both values. - The control plane decodes the JWT, looks up the WIF Configuration for the service account, and verifies the issuer and all configured claims.
- The control plane fetches the JWKS from the OIDC issuer, verifies the token signature, audience, and expiry.
- On success, the control plane returns a standard service account session token. The provider uses this token for all subsequent API calls.
The resulting session carries the same organization role and realm assignments as the service account. From an authorization standpoint it is identical to a key-based session. The session will always have an expiration less than or equal to the expiration of the OIDC token.
Removing WIF from a service account
To revert to key-based authentication, delete the WIF Configuration:
spirlctl iam service-account wif-config delete my-service-account
The service account's keys are unaffected by WIF Configuration changes. After deleting the WIF Configuration, the provider must be reconfigured to use a key.