Terraform genesyscloud_oauth_client secret in state file

Just noticed that genesyscloud_oauth_client stores the client secret in the state file despite setting sensitive = true. The docs state:

“The client_secret attribute is sensitive and will not be displayed in the console output.”

However, it persists in the .tfstate JSON. I am using Terraform 1.5.7 with provider 1.14.2. Is there a workaround to exclude this from state or should I rely on state encryption?

The best way to fix this is to accept that Terraform state files are not secret vaults and enforce strict access controls on the state backend itself. The sensitive = true attribute in the Genesys Cloud provider only suppresses output during terraform apply or plan. It does not encrypt or hide the value in the .tfstate JSON blob. If your state file is stored locally or in an unencrypted S3 bucket without server-side encryption, you are already exposed.

To mitigate this, you must ensure your state backend is encrypted at rest and in transit. For AWS S3 backends, enable SSE-KMS. Here is the minimal secure configuration for the backend:

terraform {
 backend "s3" {
 bucket = "my-terraform-state"
 key = "genesys/oauth-client/terraform.tfstate"
 region = "us-east-1"
 encrypt = true
 kms_key_id = "alias/terraform-state-key" # Use a KMS key
 dynamodb_table = "terraform-locks"
 }
}

Additionally, restrict IAM policies so only the CI/CD service account or specific admin roles can read the state file. Do not rely on the provider’s sensitive flag for security. If you need to rotate the secret, use the Genesys Cloud API directly via Postman or a script, then update the Terraform configuration to point to the new client ID if rotation requires a new client, or simply update the secret in the state via terraform state rm and re-apply if the provider supports updating existing clients (though creating a new client is often cleaner for rotations).

Always audit your state file access logs. If you see unauthorized reads, rotate all secrets immediately. The state file contains every sensitive attribute you have ever provisioned, including API keys, database passwords, and yes, OAuth client secrets. Treat it like a credential dump.

You are correct that the sensitive flag only masks console output, not the state file itself. To mitigate this, you must enforce server-side encryption on your remote backend and restrict IAM policies. For AWS S3, ensure your bucket policy includes aws:RequestTag/GenesysSecret and enables SSE-KMS. This prevents accidental exposure if the state file is downloaded by unauthorized personnel.

resource "aws_s3_bucket" "tf_state" {
 bucket = "genesys-terraform-state"

 server_side_encryption_configuration {
 rule {
 apply_server_side_encryption_by_default {
 sse_algorithm = "aws:kms"
 kms_master_key_id = aws_kms_key.tf_state.arn
 }
 }
 }

 versioning {
 enabled = true
 }
}

resource "aws_kms_key" "tf_state" {
 description = "Encrypts Genesys Cloud Terraform State"
 enable_key_rotation = true
}

In my experience building secure custom widgets, relying on client-side SDKs like the Guest API requires similar discipline. If you leak credentials in a browser console, the impact is limited to that session, but a leaked Terraform state file exposes your entire infrastructure identity. I recommend rotating the OAuth client secret immediately after any state file breach. Use the Genesys Cloud API to generate a new secret via POST /api/v2/oauth/clients/{id} and update your Terraform variables. Do not store the old secret in version control. The provider will detect the drift and update the remote resource during the next apply. This approach ensures that even if someone reads the plaintext state file, the credentials are already invalid. Combine this with strict role-based access control on the state backend to minimize risk.