Skip to content

Feature Request: Ephemeral google_service_account_key that creates keys with private_key export #25755

@jorgensandhaug

Description

@jorgensandhaug

Summary

Request write-only attributes for google_service_account_key to enable uploading user-managed keys without storing sensitive data in Terraform state.

Use Case

For SOC2 compliance, we generate key pairs locally and:

  1. Store private key in Secret Manager (using existing secret_data_wo)
  2. Upload public key to GCP service account

This follows GCP's recommended approach: "Instead of letting Google Cloud generate a key pair, you can create your own key pair, then upload only the public key. Google never sees the private key."

Problem

public_key_data is not write-only, so:

  • Cannot accept ephemeral values (from ephemeral "tls_private_key")
  • Value must be stored in state for drift detection

Proposed Solution

Add write-only attributes:

resource "google_service_account_key" "example" {
  service_account_id         = google_service_account.sa.name
  public_key_data_wo         = base64encode(tls_self_signed_cert.sa.cert_pem)
  public_key_data_wo_version = var.key_version  # bump to rotate
}

This mirrors the existing pattern in google_secret_manager_secret_version:

  • secret_data_wo
  • secret_data_wo_version

Complete Flow

ephemeral "tls_private_key" "sa" {
  algorithm = "RSA"
  rsa_bits  = 2048
}

resource "tls_self_signed_cert" "sa" {
  private_key_pem = ephemeral.tls_private_key.sa.private_key_pem  # needs TLS provider change
  subject { common_name = "service-account" }
  validity_period_hours = 87600
  allowed_uses = ["digital_signature"]
}

resource "google_secret_manager_secret_version" "sa_private_key" {
  secret                 = google_secret_manager_secret.key.id
  secret_data_wo         = ephemeral.tls_private_key.sa.private_key_pem
  secret_data_wo_version = var.key_version
}

resource "google_service_account_key" "sa" {
  service_account_id         = google_service_account.sa.name
  public_key_data_wo         = base64encode(tls_self_signed_cert.sa.cert_pem)
  public_key_data_wo_version = var.key_version
}

Result: Private key never in state. Only non-sensitive cert metadata stored.

Environment

  • Terraform: 1.13.3
  • Google Provider: 7.7.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions