Using Google Cloud Platform’s Cloud Key Management Service (KMS) to Encrypt / Decrypt Secrets

Raj Chaudhary
Mar 19, 2018 · 3 min read

I am trying to get rid of all plain text GCP Service Account JSON credential files from my source code such that no developer has access to these at any stage in the dev lifecycle (development, testing, staging and production).

While I still haven’t figured out the best practices for implementing this at an enterprise level, one easy way of achieving this is by encrypting these files at rest and decrypting them via an additional build step via my favorite CI / CD tool upon every code deployment.

That’s where GCP’s Cloud Key Management Service (KMS) can be used beautifully and it’s surprisingly easy to implement. This blog post is restricted to using KMS for encrypting / decrypting secrets, i.e., GCP Service Account JSON credential files in this case.

Another blog post which builds upon this one and explains the best practices for achieving enterprise level security including separation of developer duties, GCP Projects, GCP Users and / or GCP Service Accounts, etc soon once I have figured all of it out.

Time for some code! Key rings group keys together to keep them organized. Create a new key ring by the name “development-key-ring” in location “global”:

gcloud kms keyrings create development-key-ring --location global

Create a new key by the name “datastore-key” in location “global” in key ring “development-key-ring” for a default “90” days rotation period:

gcloud kms keys create datastore-key --location global --keyring development-key-ring --purpose encryption

Encrypt the GCP Service Account JSON credential file using above created key ring and key:

gcloud kms encrypt \
--location=global \
--keyring=development-key-ring \
--key=datastore-key \
--plaintext-file=C:\datastore.json \
--ciphertext-file=C:\datastore.json.enc

You can safely delete the plain text GCP Service Account JSON credential file at C:\datastore.json now.

Decrypt the encrypted GCP Service Account JSON credential file using above created key ring and key:

gcloud kms decrypt \
--location=global \
--keyring=development-key-ring \
--key=datastore-key \
--ciphertext-file=C:\datastore.json.enc \
--plaintext-file=C:\datastore.json

All that’s pending is to include a build step in your favorite CI / CD tool to replace the encrypted datastore.json.enc file with the decrypted one by calling the above decrypt command upon every code deployment.

To wrap up, it might be a good idea to:

Having said that, fine tune your strategy to your unique environment. There is no one size fits all approach here.

You can apply above concept to any secret that requires encryption / decryption, not just GCP Service Account JSON credential files. But you do have to factor in performance and costs in your architecture.

NB this post only scratches the surface of what KMS can do as far as encryption / decryption of secrets are concerned. Also, key rings and keys once created cannot be deleted in GCP and active key versions as well as encryption / decryption operations are chargeable although minimal. Therefore, it is recommended that you spend about half a day reading about KMS extensively before implementing it in production. Check the links in the Resources section at the end of this post for more info.

Resources:

Happy Coding!

Google Cloud Platform - Community

A collection of technical articles published or curated by Google Cloud Platform Developer Advocates. The views expressed are those of the authors and don't necessarily reflect those of Google.

Raj Chaudhary

Written by

chasing excellence…

Google Cloud Platform - Community

A collection of technical articles published or curated by Google Cloud Platform Developer Advocates. The views expressed are those of the authors and don't necessarily reflect those of Google.