Road sign Oulu Finland

Using Secret Manager in a Google Cloud Function with Python

When you write a cloud function, you need to protect an API key, account information user id and password, or other sensitive data. In the Google Cloud Platform (GCP) you can use the Secret Manager a secure and convenient storage system that provides a central place and single source of truth to manage access, and audit secrets across the Google Cloud Platform.

Let’s get started with the Google Secret Manager as I will explain how I use Google Secret Manager in Google Cloud Functions that I have created. Using the Google Secret Manager you can automatically rotate your secrets, meaning you do not need to change your code when you update a secret. Google Secret Manager also provides a life cycle management with versioning and pin requests to the latest version of a secret.

The GCP Architect Services

In the GCP I’m using the following services as shown in the diagram below:

Enable the Secret manager API

To use the secret manager you need to enable the GCP API for the secret manager, in the Google Cloud Platform Console goto APIs & Service to Enable Secret Manager

Secret Manager API
Secret Manager API

Create your Secrets

To create the secrets navigate in the Google Cloud Platform Console menu to Security -> Secret Manager

Secret Manager Menu
Secret Manager Menu

Now you can start to create your secrets, In my case, I created a few – for this example, I’m only describing the slack_hook_key, as mentioned earlier you can create secrets for all different purposes that you can use in your code.

Secret Manager secrets
Secret Manager secrets

For more details about the Secret Manager visit the documentation

Python Code Snippet for Secret Manager

To use the secret manager with Python you need to install the Google Cloud Secret Manager for Python, first, you have to install it in your environment.

pip install google-cloud-secret-manager

Creating the Cloud Function

Now you have the Secret Manager for Python installed in your environment, next you have to create your requirements.txt. It would be best if you had this when you publish your Cloud Function to GCP.

google-cloud-secret-manager==1.0.0

Next, we will write the Python code, the secret that I have in the Secret Manager is the webhook for Slack, as the Python code is about how to publish data to a Slack webhook.

import logging
import os
import requests

# Install Google Libraries
from google.cloud import secretmanager

# Setup the Secret manager Client
client = secretmanager.SecretManagerServiceClient()
# Get the sites environment credentials
project_id = os.environ["PROJECT_NAME"]

# Get the secret for Slack
secret_name = "slack-hook-key"
resource_name = f"projects/{project_id}/secrets/{secret_name}/versions/latest"
response = client.access_secret_version(resource_name)
slackhookkey = response.payload.data.decode('UTF-8')

# Request Header
headers = {
    'Content-Type': 'application/json'
}

def getExample_http(request):
    logging.info('Just an Example Secret manager'
    payload = '{{"text":"Just an Example Secret Manager"}}'
    response = requests.request("POST", slackhookkey, headers=headers, data=payload)

As you can see from the code, project_id = os.environ[“PROJECT_NAME”] I have created my environment variable in my Cloud Function environment like this.

Cloud Function Environment Variable
Cloud Function Environment Variable

Update

As of version 2.0 of google-cloud-secret-manager==2.0.0, the way you request the secret manager has changed from

response = client.access_secret_version(resource_name)

to

response = client.access_secret_version(request={"name": resource_name})

You can read more on how to migrate to version 2.0 here: https://googleapis.dev/python/secretmanager/latest/UPGRADING.html

Conclusion

This is just a simple example of how you can use Google Secret Manager to protect and version the secrets you use in your Cloud Functions or any other applications. I hope this gives you some ideas on how you can work with Secret Manager. I always appreciate any feedback that you can submit in the comment box below.

Read more on how to use Google Secret Manager – https://cloud.google.com/secret-manager/docs/reference/libraries

Comments

8 responses to “Using Secret Manager in a Google Cloud Function with Python”

  1. […] I store all my secrets for the Cloud Function with the Secret Manager, you can read how to use the Secret Manager in this article Using Secret Manager in a Google Cloud Function with Python […]

  2. […] Security is a big issue when your create a Cloud Functions, you can read more about Securing HTTP trigger in Google Cloud Functions and Using Secret Manager in a Google Cloud Function […]

  3. […] Secret manager. If you want to learn how to use the Google Secret Manager you can read this article Using Secret Manager, the example in the Article is for Python. I will show I did it with […]

  4. Anmol More Avatar
    Anmol More

    Hi Torbjorn,
    This was a really helpful writeup. Seems like google-cloud-secret-manager 2.0 constructors have changed, and unable to find updated documentation.

    Incase you have some pointers to updated version of client.access_secret_version(resource_name) kindly reply. With 2.0 it gives an error

    1. Torbjorn Zetterlund Avatar
      Torbjorn Zetterlund

      What is your exact problem and is it this library you referring to = https://pypi.org/project/google-cloud-secret-manager/

    2. momshomecooking Avatar
      momshomecooking

      Instead of response = client.access_secret_version(name=resource_name) you need to use response = client.access_secret_version(request={"name": resource_name}) if you using the python library google-cloud-secret-manager 2.0 or higher

  5. Christophe GUERNION Avatar
    Christophe GUERNION

    Hi Torbjorn,
    following your helpful article, I notice that the following is expected in my environment (google-cloud-secret-manager==2.6.0):
    response = client.access_secret_version(name=resource_name)
    where name parameter shall explicitly be stated when calling access_secret_version() function.

    I guess this was probably the point reported by Anmol on Sept’18th’20.

    Thanks and Regards
    Christophe

    1. momshomecooking Avatar
      momshomecooking

      When you use "response = client.access_secret_version(name=resource_name)" you need to define in requirements.txt the version to use of the library google-cloud-secret-manager as of version 2.0.0 changes was introduced especially to how to request secrets, here is how it should look
      response = client.access_secret_version(request={"name": resource_name})

      You can read more – 2.0.0 Migration Guide

Leave a Reply to momshomecooking Cancel reply

Your email address will not be published. Required fields are marked *