Open rwblokzijl opened 8 months ago
Thanks for this feature request! If you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions.
I've sent this to our product manager for review as well. Thanks again!
Thanks for the write-up @rwblokzijl!
This sounds more like a proposal to help remove sensitive information from the plan, which is definitely a valid concern. In the current architecture, delaying the read of secrets until apply would still end up with the same data stored in the state. Just to clarify some things here while other research is in progress, points which can't be addressed by these changes alone are as follows:
The idea that apply
is an action which requires elevated privileges is interesting. That might not be a complete solution for the CLI tool on its own, but within a managed workflow it might be part of a larger solution for secrets management.
Proposal for minimizing/removing secrets from the Terraform state file
With the additional benefit of low privilege Terraform plans.
Background:
Terraform is a game changer for infrastructure management, the ability to maintain everything as code is a godsend and our entire organization is using it to manage thousands of resources across 10 teams.
During our 3 years of setting up this infrastructure, we've noticed one issue that has been hard to reconcile: The fact that Terraform is "all powerful" whilst it is the only acceptable way of changing our infra. These two concepts are constantly at odds with each other. But it doesn't have to be this way.
terraform apply
is really the dangerous operation. It affects the infra, it can delete crucial resources, it has "write" permissions.terraform plan
however, does not do anything like that. It just does a bunch of GET requests, compares to the state, and proposes changes, it has "read" permissions.This mean
terraform plan
should be runnable by any engineer at our company. They can make changes to the Terraform code on their git branch, runterraform plan
locally, evaluate their changes, iterate, and eventually create a pull request, that runs anotherterraform plan
, to be reviewed by the gatekeepers of our organization. Works great, everyone can develop with velocity, and the security is maintained.However, its not that simple. There are a few issues that make
terraform plan
nearly as privileged asterraform apply
. Resources contain secrets in their configurations. These secrets need to be read byterraform plan
from a datasource API and later during Terraform refresh read again from the resource API for change detection. This means the underlying accounts needs permissions to read secrets from these APIs. Additionally, these secrets are then kept in the Terraform state, which is also readable byterraform plan
.During plan we'd want all operations to be as little privileged as possible, this way all engineers can develop and run `terraform plan`` without needing access to any secret values that could be misused for "write level" operations later.
Proposal
Please consider the following proposal for fixing this:
Read operations defined by the providers could be split between "plan" and "apply" time reads.
This would require a change in the contract between Terraform and its providers. And 1 change to the way Terraform calls the providers during "read" operations.
Backwards compatibility should be easy enough, if the provider does not define separate plan and apply time read operations, just the plan time read operation would be called.
The information returned during the apply time read would have to be consistent with the earlier plan time read. However this should solvable possible in most situations. (eg. Metadata or a unique version identifier). Also there could be a check that all the other fields haven't changed in the meantime.
This also means the underlying platforms and APIs should support separate metadata and read permissions. This is already supported by eg Vault and GCP secrets.
An example:
A datasource "vault_kv_secret_v2" is used to configure a resource "google_secret_manager_secret_version".
The 2 read operations will be referred to as "plan_read" and "apply_read"
In this example, both these resources have been updated to use the following endpoints:
Creation Plan (using low privileges):
.tfplan
. This will include a reference to vault_kv_secret_v2 and the metadata (no secrets)Creation Apply (using higher privileges):
Update/Read Plan:
Update: Apply
Our current workarounds
terraform apply
has permissions to grant them access to the vault secrets, without having access itself.terraform plan
only has permissions to view the permissions of the serverless functions, not the secrets themselves.Expansions on the idea
Additional benefits of apply time and read time fetches:
Another issue to setting up lower privileged plans is that provider configurations could depend on a datasource for authentication eg google_service_account_jwt for accessing vault in our GCP pipelines. If these values could update between plan and apply, it could be swapped for a higher privilege token on apply. In addition to the token being fresh.
https://github.com/hashicorp/terraform/issues/32100
Related issues:
https://github.com/hashicorp/terraform/issues/516 https://github.com/hashicorp/terraform/issues/32100