Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secret keys in Terraform remote state #22890

Open
joe-boyce opened this issue Sep 24, 2019 · 4 comments
Open

Secret keys in Terraform remote state #22890

joe-boyce opened this issue Sep 24, 2019 · 4 comments

Comments

@joe-boyce
Copy link

Terraform Version

Not specific to a version

Terraform Configuration Files

data "terraform_remote_state" "firewall" {
    backend = "gcs"
    config {
        bucket = " tf-state-bucket"
        prefix = "a/path"
        credentials = "${file("${var.provider_credentials}")}"
    }
}

Actual Behavior

This may have been discussed in depth before but I couldn't find a specific ticket covering the subject

When using a remote datasource in terraform we have noticed that the secret key being used to pull the data is dumped into the terraform remote state, is there any reason for this as it poses a security risk where by users who have pull access to read the remote datasource can steal secrets keys

Expected Behavior

Terraform shouldn't be storing secret keys in the remote state

Steps to Reproduce

  1. terraform show
  2. Example output:
data.terraform_remote_state.firewall:
  id = 2019-09-23 15:18:26.321949 +0000 UTC
  mysql-master-tag = mysql-master-55e6362a5b17e26b
  mysql-slaves-tag = mysql-slaves-c4acdc3ff749cdc1
  backend = gcs
  config.# = 1
  config.2904908756.bucket = tf-state-bucket
  config.2904908756.credentials = {
  "type": "service_account",
  "project_id": "project-id",
  "private_key_id": "abcdefghijklmnopqrstuvwxyz123456789",
  "private_key": "-----BEGIN PRIVATE KEY-----\nabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\n-----END PRIVATE KEY-----\n",
  "client_email": "emailaddress",
  "client_id": "123456789101112",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/terraform%40email"
}
  config.2904908756.prefix = a/path
  environment = default
  workspace = default
@teamterraform
Copy link
Contributor

Hi @joe-boyce,

The Terraform backends and providers tend to offer arguments to override their default credentials-gathering behaviors in order to support more complex usage patterns, but the "normal" way to use backends and providers is to omit the credentials from the Terraform configuration altogether and instead allow the backend or provider to gather the credentials in a vendor-standard way from the environment.

For example, the GCS backend supports the documented mechanisms for configuring credentials for Google Cloud Platform, and that should be considered the default way to use this backend.

By keeping credentials out of the configuration we can ensure that the Terraform configuration only describes what Terraform is managing, and not where Terraform is running and who is running it.

The terraform_remote_state data source passes through all of the configuration arguments for the underlying backends, which does unfortunately mean it can accept this credentials argument, which will then be written to the state because Terraform saves data source results in order to use them in future plans. For this reason, you should not set credentials here and should instead allow the Google Cloud Platform credentials to be detected from the environment in the standard way. By doing so, the credentials will not be in the configuration and will thus not be saved in the state.

As a general rule, you should avoid using credentials and other secrets within the Terraform configuration itself, unless you have taken measures to treat the resulting state as a secret artifact. Other providers and backends have similar mechanisms for obtaining credentials automatically from the environment, and so the in-configuration arguments for providing credentials should always be considered a last resort for complex environments where ambient credentials are infeasible.

@hashibot hashibot added the waiting-response An issue/pull request is waiting for a response from the community label Sep 25, 2019
@joe-boyce
Copy link
Author

Thanks this worked fine for google datasources, I omitted the credentials variable from the terraform_remote_state datasource and the API key was successfully used from the provider and not stored in the state file

On the AWS side we are using assume role for the provider, for example:

provider "aws" {
  version = ">= 1.60, < 2.0.0"
  region  = "${var.region}"
  profile = "${var.profile}"
  assume_role {
    role_arn     = "arn:aws:iam::123456789:role/${var.role}"
  }
}

This works fine but if I remove the accesskey & secretkey from the remote datasource it fails, for example:

data "terraform_remote_state" "iam" {
  backend = "s3"
  config {
    bucket     = "tf-state-bucket"
    key        = "path/to/iam/iam.tfstate"
    region     = "region"
  #  access_key = "${var.accesskey}"
  #  secret_key = "${var.secretkey}"
  }
}

Error is as folllows:

data.terraform_remote_state.iam: 1 error occurred:
   * data.terraform_remote_state.iam: data.terraform_remote_state.iam: error initializing backend: No valid credential sources found for AWS Provider.
   Please see https://terraform.io/docs/providers/aws/index.html for more information on
   providing credentials for the AWS Provider

@ghost ghost removed the waiting-response An issue/pull request is waiting for a response from the community label Oct 16, 2019
@mildwonkey
Copy link
Contributor

Hi @joe-boyce! Unfortunately your latest example is a known issue with the s3 backend. Here's one ticket, but I believe there are more open:
#22354

There was a recent PR which addressed some, but not all, assume_role-related issues: #22994

@joe-boyce
Copy link
Author

@mildwonkey do you know if this will make it into terraform v0.11.x as we haven't taken the leap onto 0.12.x as of yet, or will it be in the AWS provider?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants