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:0.4.1
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", "--use-default-credentials"]
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:0.4.1
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.