Upload public keys for GCP service accounts with terraform

Aleksandr Averbukh
Google Cloud - Community
3 min readJun 28, 2022

Hope you already came across a great article by Ryan Canty Stop Downloading Google Cloud Service Account Keys, today there are a plenty of alternatives to creating service account keys.

But imagine you are at an early cloud adoption stage, you are not yet ready to involve OIDC providers and Workload Identity Pools. The same time on-prem applications/servers require a way to authenticate against Google Cloud APIs. The most insecure way to go about it is to allow engineers to generate service account keys which may lead to these keys flying around from one user to another via internal messengers or mailbox. A slightly better way is to centralize key generation and allow key provisioning only via GitOps + Terraform, so you have a clean history of “integration” service account management. But this approach still has a few caveats:

  • key has no expiration time
  • key material is written in the terraform state
  • key needs to be transferred to the end application/server
  • everyone with access to the terraform pipeline has access to the key

There is a better way which can handle all the above!

Managing service account keys by uploading public RSA keys via terraform

This example shows how to manage IAM Service Account Keys by manually generating a key pair with OpenSSL and uploading the public part of the key to GCP. It has the following benefits:

Deployment

To run the example, start by cloning the repository and changing to the example folder. If you prefer using Cloud Shell, this link will run the Git clone for you, and switch to the correct folder so that you can skip the initial step below.

git clone https://github.com/GoogleCloudPlatform/cloud-foundation-fabric.git
cd cloud-foundation-fabric/examples/cloud-operations/onprem-sa-key-management

Cleaning up example keys.

rm -f /public-keys/data-uploader/
rm -f /public-keys/prisma-security/

Generate new keys for the service accounts.

mkdir keys && cd keys
openssl req -x509 -nodes -newkey rsa:2048 -days 30 \
-keyout data_uploader_private_key.pem \
-out ../public-keys/data-uploader/public_key.pem \
-subj "/CN=unused"
openssl req -x509 -nodes -newkey rsa:2048 -days 30 \
-keyout prisma_security_private_key.pem \
-out ../public-keys/prisma-security/public_key.pem \
-subj "/CN=unused"

Deploy service accounts and keys.

Note: We only use the public part of the keys for deployment, ideally private part of the key should never leave the server where it’s generated and going to be consumed.

cd ..
terraform init
terraform apply -var project_id=$GOOGLE_CLOUD_PROJECT

Extract JSON credentials templates from terraform output and put the private part of the keys into the templates.

terraform show -json | jq '.values.outputs."sa-credentials".value."data-uploader"."public_key.pem" | fromjson' > data-uploader.json
terraform show -json | jq '.values.outputs."sa-credentials".value."prisma-security"."public_key.pem" | fromjson' > prisma-security.json

contents=$(jq --arg key "$(cat keys/data_uploader_private_key.pem)" '.private_key=$key' data-uploader.json) && echo "$contents" > data-uploader.json
contents=$(jq --arg key "$(cat keys/prisma_security_private_key.pem)" '.private_key=$key' prisma-security.json) && echo "$contents" > prisma-security.json

Testing

Validate that service accounts json credentials are valid.

gcloud auth activate-service-account --key-file prisma-security.json
gcloud auth activate-service-account --key-file data-uploader.json

Cleaning up.

terraform destroy -var project_id=$GOOGLE_CLOUD_PROJECT

It’s always better to avoid service account keys, but in real life scenarios we are still forced to rely on them. With the approach shown in the article we mitigate a big part of security issues related to service account key management, such as:

  • keys are generated and stored on the consumer server and never leave it
  • keys have expiration time set by user
  • private part of the key is not stored in the terraform state or code
  • GitOps and terraform provides a central plane of glass on the “integration” key management

--

--