Search code examples
google-cloud-rungoogle-secret-manager

How to use a Google Secret in a deployed Cloud Run Service (managed)?


I have a running cloud run service user-service. For test purposes I passed client secrets via environment variables as plain text. Now since everything is working fine I'd like to use a secret instead.

In the "Variables" tab of the "Edit Revision" option I can declare environment variables but I have no idea how to pass in a secret? Do I just need to pass the secret name like ${my-secret-id} in the value field of the variable? There is not documentation on how to use secrets in this tab only a hint at the top:

Store and consume secrets using Secret Manager

Which is not very helpful in this case.


Solution

  • UPDATE 2021: There is now a Cloud Run preview for loading secrets to an environment variable or a volume. https://cloud.google.com/run/docs/configuring/secrets

    The question is now answered however I have been experiencing a similar problem using Cloud Run with Java & Quarkus and a native image created using GraalVM.

    While Cloud Run is a really interesting technology at the time of writing it lacks the ability to load secrets through the Cloud Run configuration. This has certainly added complexity in my app when doing local development.

    Additionally Google's documentation is really quite poor. The quick-start lacks a clear Java example for getting a secret[1] without it being set in the same method - I'd expect this to have been the most common use case!

    The javadoc itself seems to be largely autogenerated with protobuf language everywhere. There are various similarly named methods like getSecret, getSecretVersion and accessSecretVersion

    I'd really like to see some improvment from Google around this. I don't think it is asking too much for dedicated teams to make libraries for common languages with proper documentation.

    Here is a snippet that I'm using to load this information. It requires the GCP Secret library and also the GCP Cloud Core library for loading the project ID.

    public String getSecret(final String secretName) {
        LOGGER.info("Going to load secret {}", secretName);
    
        // SecretManagerServiceClient should be closed after request
        try (SecretManagerServiceClient client = buildClient()) {
            // Latest is an alias to the latest version of a secret
            final SecretVersionName name = SecretVersionName.of(getProjectId(), secretName, "latest");
            return client.accessSecretVersion(name).getPayload().getData().toStringUtf8();
        }
    }
    
    private String getProjectId() {
    
        if (projectId == null) {
            projectId = ServiceOptions.getDefaultProjectId();
        }
    
        return projectId;
    }
    
    private SecretManagerServiceClient buildClient() {
        try {
            return SecretManagerServiceClient.create();
        } catch(final IOException e) {
            throw new RuntimeException(e);
        }
    }
    

    [1] - https://cloud.google.com/secret-manager/docs/reference/libraries