- Provider: Genesys Cloud CX as Code v2.10.0
- Environment: Azure DevOps Pipeline / Private Registry
- Issue: Secret leakage in
terraform.tfstate
Just noticed that our Chrome extension’s OAuth client credentials are being persisted in plaintext within the Terraform state file. This is a critical security risk for our multi-tenant BPO setup in Toronto. We use the genesyscloud_oauth_client resource to provision new clients for different divisions.
Here is the resource definition:
resource "genesyscloud_oauth_client" "extension_client" {
name = "ChromeOverlay-Dev"
description = "OAuth client for screen pop extension"
redirect_uris = ["https://localhost:3000/callback"]
# Secrets are generated by the API
client_secret = "${genesyscloud_oauth_client.extension_client.client_secret}"
}
When I run terraform apply, the state file contains:
"client_secret": "sk_live_abc123def456..."
The API docs suggest using sensitive = true, but I am unsure if the Genesys provider supports this attribute for output values or if it actually masks the value in the JSON state.
- Does the provider support
sensitive flags on generated secrets?
- Is there a recommended pattern to store these in Azure Key Vault instead of relying on the state file?
- Can I force the provider to not write the secret to state at all?
the problem here is you are storing secrets in state instead of using variables. never put oAuth creds in tfvars. use vault or azurkeyvault provider.
resource "azurerm_key_vault_secret" "genesys_client_id" {
name = "genesys-client-id"
value = "your-client-id"
key_vault_id = azurerm_key_vault.kv.id
}
variable "genesys_client_id" {
type = string
sensitive = true
}
You need to decouple the credential injection from the state persistence layer entirely. While storing secrets in Azure Key Vault is a standard practice, relying on Terraform to fetch them at plan time still risks leakage if the state file is not encrypted at rest or if the CI/CD pipeline logs expose variable interpolation.
For a Python automation engineer managing Genesys Cloud org resources, I recommend using an environment variable injection pattern combined with the genesyscloud provider’s native support for dynamic credentials. This avoids persisting the client_id and client_secret in the state file altogether.
First, ensure your Azure DevOps pipeline retrieves the secrets into environment variables:
- script: |
export GENESYS_CLIENT_ID=$(az keyvault secret show --name genesys-client-id --vault-name myVault --query value -o tsv)
export GENESYS_CLIENT_SECRET=$(az keyvault secret show --name genesys-client-secret --vault-name myVault --query value -o tsv)
displayName: 'Retrieve Genesys Credentials'
Then, configure your Terraform provider block to consume these environment variables directly. The genesyscloud provider automatically checks GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET if not explicitly provided in the provider block.
terraform {
required_providers {
genesyscloud = {
source = "mygenesys/genesyscloud"
version = "~> 1.0.0"
}
}
}
provider "genesyscloud" {
# No client_id or client_secret here.
# The provider will read from ENV vars automatically.
}
This approach ensures that even if terraform.tfstate is compromised, no OAuth secrets are present. The state file will only contain resource IDs and configuration metadata. Additionally, this aligns with the principle of least privilege, as the secrets exist only in the memory space of the pipeline runner during execution. Remember to set sensitive = true on any local values that might reference these tokens for debugging purposes.