skip to Main Content

It seems there’s a lot of information out there on how to retrieve and view sensitive data in terraform, but not a lot on how to prevent viewing of it via the nonsensitive function.

For example, suppose I have a secret stored in Azure Key Vault and I want my config to grab it and use it somewhere:

data "azurerm_key_vault_secret" "my_ultra_secret" {
    name         = "my_ultra_secret"
    key_vault_id = data.azurerm_key_vault.mykeyvault.id
}

(I’m using remote state stored in HCP Terraform, aka Terraform Cloud, with a service principal for Terraform to talk to Azure and manipulate resources.)

If a developer is able to get this code and go into terraform console, they can do this:

nonsensitive(data.azurerm_key_vault_secret.my_ultra_secret)

Thus exposing the secret in plain text. I don’t want the developer seeing the secrets, but obviously terraform cloud needs to, so the idea of restricting my service principal’s permissions doesn’t seem to fit the bill.

Any idea how I do this? (I’ve looked at dynamic provider credentialing, but this doesn’t seem to restrict permissions based on user, as far as I can tell.

2

Answers


  1. Chosen as BEST ANSWER

    After experimenting with various options, I think I have a fairly good solution. The documentation for HCP Cloud on these options is here, but I will translate into my own words in case that helps anyone.

    TL;DR: HCP cloud provides granular RBAC to control the things I talked about in the OP.

    • Keep in mind with HCP Cloud, there are two sets of credentials to manage: your HCP/terraform creds, and your Azure/whatever provider creds. These both can come into play while working in terraform, but for the purposes of this answer, we're concerned only about the former. HCP cloud determines who a user is when they run terraform login, and that's what you'll use to set these RBAC settings. The latter is controlled with az login, but again, out of scope for this answer.
    • If you have a service provider set up linking Azure and HCP Cloud (I hope you do), then that will continue to work as per the RBAC settings in Azure that you've set up. All the bullets below are purely concerned about developer access to your terraform workspaces, not to Azure.
    • If you want to block access to the terraform console completely and keep that Pandora's box closed, make sure to uncheck this option when setting up a team's permissions. This will effectively block any developer from being able to enter the console and view data that way. Note they may still be able to see some secrets using terraform output (more on that below). enter image description here
    • If you want to allow access to the console, you can also separately block access to state. Here is the solution to my original quandary: if you set "no access" or "read outputs only," then any sensitive values that you try to expose via the nonsensitive function will simply show (known after apply). If you allow full read access, then they will be able to see your secrets.
      enter image description here
    • Do note though, that if you have sensitive values in output variables, setting "read outputs only" will let them view those secrets with a command like terraform output myvar. If you set state to "no access," then the previous command will show No outputs found.
    • There are also options to control access to input variables, but that's beyond the scope of this question.

    This answer doesn't address any general security best practices when it comes to Terraform secrets, as you can find those all over the place.

    Hope this helps!


  2. Preventing the terraform developers from viewing secrets with the nonsensitive function

    In general, when an end user is provided enough permission to use a secret in multiple environment/resources we should have provided enough permissions to do those tasks.

    When it comes to access policies, we can provide the limitations to end users by providing the get permission alone which is minimal permission required to use the secret. Unfortunately, If the user got this privilege, then he will be having enough permission to see the secret as well i.e., vice versa.

    I can share to few steps by which you can overcome this but before applying these make sure your end user doesn’t have secret stored in his state file.

    • Even the nonsensitive() is a Terraform function if you use sensitive = true in the output block it will not allow the end user to see the secret.

    code configuration:

    data "azurerm_key_vault_secret" "example" {
      name         = "testsample"
      key_vault_id = data.azurerm_key_vault.example.id
    }
    
    output "exposed_secret_value" {
      value = nonsensitive(data.azurerm_key_vault_secret.example.value)
      sensitive = true
     
    }
    

    Deployement:

    enter image description here

    • Create specific roles for developers that do not include permission to view state files. Restrict their access to running sensitive operations like terraform console to avoid them from using nonsensitive(). you can also use pass the secretly using the Azure DevOps, GitHub Actions etc.
    • Try make some changes such that developers should not be in a position to make changes in the configuration file by locking it this can be done by pull requests before changes are made

    Note:
    when you provide necessary permission for the end user or developer, he will be able to see the value of secret using this. We have to live with it.

    Refer:

    https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_access_policy

    Need to display sensitive data output variables in terraform by Mark B

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search