Skip to content

Allow passphrase encryption of private key #664

Description

@globalpay-wafishe

Terraform CLI and Provider Versions

Terraform v1.11.4
hashicorp/tls v4.1.0

Use Cases or Problem Statement

It it our organization's policy for service accounts in Snowflake to authenticate using passphrase encrypted key pair authentication. We are using terraform to automate the creation of the user with the key pair and storing the private key in GCP secrets manager.

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    tls = {
      source  = "hashicorp/tls"
      version = ">= 4.0.0"
    }
    snowflake = {
      source                = "snowflakedb/snowflake"
      version               = ">= 2.0.0"
      configuration_aliases = [snowflake.useradmin]
    }
    google = {
      source  = "hashicorp/google"
      version = ">= 6.0.0"
    }
  }
}

resource "tls_private_key" "key_pair" {
  algorithm = "RSA"
  rsa_bits  = 2048
}

resource "snowflake_service_user" "user" {
  provider = snowflake.useradmin

  name           = var.name
  comment        = var.comment
  default_role   = "PUBLIC"
  rsa_public_key = tls_private_key.key_pair.public_key_pem
}

resource "snowflake_grant_account_role" "roles" {
  provider = snowflake.useradmin
  for_each = var.roles

  role_name = each.value
  user_name = snowflake_service_user.user.name
}

resource "google_secret_manager_secret" "private_key_secret" {
  secret_id = "snowflake_${snowflake_service_user.user.name}_private_key"
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "private_key_secret_version" {
  secret      = google_secret_manager_secret.private_key_secret.id
  secret_data = tls_private_key.key_pair.private_key_pem_pkcs8
}

resource "google_secret_manager_secret_iam_binding" "private_key_accessors" {
  secret_id = google_secret_manager_secret.private_key_secret.id
  members   = var.accessors
  role      = "roles/secretmanager.secretAccessor"
}

However, there is no option to encrypt the private key with a passphrase to be fully compliant with company policy. We would like the ability to provide a passphrase to the private key so we can automate user creation in a way that is fully compliant with company policy.

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    random = {
      source = "hashicorp/random"
      version = ">= 3.0.0"
    }
    tls = {
      source  = "hashicorp/tls"
      version = ">= 4.0.0"
    }
    snowflake = {
      source                = "snowflakedb/snowflake"
      version               = ">= 2.0.0"
      configuration_aliases = [snowflake.useradmin]
    }
    google = {
      source  = "hashicorp/google"
      version = ">= 6.0.0"
    }
  }
}

resource "random_password" "passphrase" {
  length = 16
}

resource "tls_private_key" "key_pair" {
  algorithm = "RSA"
  rsa_bits  = 2048
  passphrase = random_password.passphrase.result
}

resource "snowflake_service_user" "user" {
  provider = snowflake.useradmin

  name           = var.name
  comment        = var.comment
  default_role   = "PUBLIC"
  rsa_public_key = tls_private_key.key_pair.public_key_pem
}

resource "snowflake_grant_account_role" "roles" {
  provider = snowflake.useradmin
  for_each = var.roles

  role_name = each.value
  user_name = snowflake_service_user.user.name
}

resource "google_secret_manager_secret" "private_key_secret" {
  secret_id = "snowflake_${snowflake_service_user.user.name}_private_key"
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret" "passphrase_secret" {
  secret_id = "snowflake_${snowflake_service_user.user.name}_passphrase"
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "private_key_secret_version" {
  secret      = google_secret_manager_secret.private_key_secret.id
  secret_data = tls_private_key.key_pair.private_key_pem_pkcs8
}

resource "google_secret_manager_secret_version" "passphrase_secret_version" {
  secret      = google_secret_manager_secret.passphrase_secret.id
  secret_data = random_password.passphrase.result
}

resource "google_secret_manager_secret_iam_binding" "private_key_accessors" {
  secret_id = google_secret_manager_secret.private_key_secret.id
  members   = var.accessors
  role      = "roles/secretmanager.secretAccessor"
}

resource "google_secret_manager_secret_iam_binding" "passphrase_accessors" {
  secret_id = google_secret_manager_secret.passphrase_secret.id
  members   = var.accessors
  role      = "roles/secretmanager.secretAccessor"
}

Proposal

Add a new parameter "passphrase" to the "tls_private_key" resource. If null (the default), it will function like it currently does. However, if a passphrase is provided, the private key will be encrypted with the passphrase.

How much impact is this issue causing?

Medium

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions