How to get secrets from the Google Secret Manager into your container

On Google Cloud Platform, we use the Google Secret Manager to keep our secrets safe. But accessing the secrets from an existing application is intrusive. You either have to call the API in the application or use the secrets cli in the entry point script of the container. In this blog, I introduce you to the utility gcp-get-secret.This utility changes references to secrets into environment variable values.

How does it work?

The utility will inspect all environment variables. If an environment variable starts with gcp:, it assumes it is a URL to a secret in Google Secret Manager. The following snippet shows the simplest use:

export MYSQL_PASSWORD=gcp:///mysql_root_password'
gcp-get-secret bash -c 'echo $MYSQL_PASSWORD'
password

This will look up the value of mysql_root_password in the secret manager and replace it with its value. The program on the command line is executed and run with MYSQL_PASSWORD set, and echoes the actual value.

referencing secret names

You reference the secret in any of the following formats:

  • gcp:///<name>
  • gcp:///<name>/<version>
  • gcp:///<project>/<name>
  • gcp:///<project>/<name>/<version>
  • gcp:///projects/<project>/secrets/<name>/versions/<version>

This allows you to specify both the project and the version of the secret to retrieve. By default, it retrieves the latest version.

query parameters

The utility supports the following parameters for your secret reference:

  • default – value if the value could not be retrieved from the parameter store.
  • destination – the filename to write the value to. value replaced with file: url.
  • chmod – file permissions of the destination, left to default if not specified. recommended 0600.
  • template – the template to use for writing the value, defaults to ‘{{.}}’

If no default nor destination is specified and the parameter is not found, the utility will return an error. If a default value is specified and the parameter is not found, the utility will use the default. If a destination file exists and no default is specified, the file will be read as the default value.

For example:

$ export ORACLE_PASSWORD='gcp://oracle_scott_password?default=tiger&destination=/tmp/password'
$ gcp-get-secret bash -c 'echo $ORACLE_PASSWORD'
/tmp/password
$ cat /tmp/password
tiger

template formatting

To format the result, you can use the template query parameter. For example:

$ export PGPASSFILE=gcp://postgres_kong_password?template='localhost:5432:kong:kong:{{.}}%0A&destination=/etc/.pgpass'
$ gcp-get-secret bash -c 'cat $PGPASSFILE'
localhost:5432:kong:kong:@CypJqmqZ@TYQ2GDnUD@MQGuKyhrl!

Environment substitution

The URI may contain an environment variable references itself. For example:

$ export ENV=dev
$ export PASSWORD='gcp:///${ENV}_mysql_root_password'
$ gcp-get-secret bash -c 'echo $PASSWORD'

will print out the value of dev_mysql_root_password.

Dockerfile usage

The natural way to use the utility in a container is as follows:

FROM binxio/gcp-get-secret

FROM alpine:3.6
COPY --from=0 /gcp-get-secret /usr/local/bin/

ENV PGPASSWORD=gcp:///postgres_root_password?default=postgres

ENTRYPOINT [ "/usr/local/bin/gcp-get-secret"]
CMD [ "/bin/bash", "-c", "echo $PGPASSWORD"]

You make the utility the entrypoint, and you move the original entrypoint to the command section.

installation

If you have Golang installed, type:

go get github.com/binxio/gcp-get-secret

installation in Docker

To get the utility into your container, use the multi-stage build:

FROM binxio/gcp-get-secret

FROM alpine:3.6
COPY --from=0 /gcp-get-secret /usr/local/bin/

Conclusion

With gcp-get-secret, you have a non-intrusive way of retrieving secrets from the secret manager. You can use them as an environment variable or save them to a file. By specifying default values, you can run your container in an integration test on your local desktop or in a CI environment.

If you are looking for the same thing in AWS, read how to get secrets from the AWS Parameter Store into containers.

Photo by JJ Jordan on Unsplash

Mark van Holsteijn is a senior software systems architect, and CTO of binx.io. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Share this article: Tweet this post / Post on LinkedIn