A simple solution to securely storing client and application secrets when using Google Cloud Platform
Recently, we have been developing a Slack app that imports data to Google Sheets and uses Google Cloud Platform as the backend. In order for this to happen there are several secrets involved. We have made a distinction between the two types of secrets we deal with. User-level secrets are those that are unique to the user, whereas application-level secrets are those that are specific to the app that we are writing. We classify the following secrets into the different aforementioned categories:
The user-level secrets are used to allow the app to act on behalf of the authorised user; The GSuite OAuth tokens are required to read and write to the Google Sheets reporting spreadsheet. The Slack OAuth token is required to allow the app to send Slack messages to users.
The app-level secrets are used to verify the app has the rights to access the required APIs; The GSuite API secrets are required to make calls to the Google Sheets API. The Slack Client Id and Client Secret are used to validate the authenticity of the Slack app when requesting a Slack OAuth token. The Slack App Signing Secret is used to verify messages received by the app from Slack are valid.
Once the user completes the OAuth flow we store their secret in a Firestore Database, however the secret is encrypted using GoogleKMS. In order to do this, we first need to create an encryption key. Before we can do this we need to create keyring. You can do this in the Google Cloud Console (by search KMS) or using the following code:
Then we can create a key (in this example we will be creating a symmetric key), again in the Google Cloud Console or using the following code:
Once you receive the token from the OAuth you can encrypt it as follows:
Then you can decrypt when needed:
The above examples are receiving Google OAuth tokens, so the fields might not match exactly but the principle is the same.
In order to ensure security you should rotate the keys used. You probably should do this automatically following this guide. Although you can also do this manually to rotate a suspected compromised key. Reasons for rotating a key include:
The handling of app-level secrets is far less complex. We use Secret Manager. To store a secret use this code:
Then to use that secret:
Voila you are set to store secrets securely using GCP.
Search over 300 blog posts from our team
Subscribe to our monthly digest of blogs to stay in the loop and come with us on our journey to make things better!