Google Cloud Services - Secret Manager

This extension allows to use the Google Cloud Platform Secret Manager client library inside your Quarkus application.The current implementation is focused on accessing the secrets, but extending the implementation into also allowing to create or edit a secret might be a natural next step.

It also allows to use secrets from the secret manager directly inside your application.properties.

Be sure to have read the Google Cloud Services extension pack global documentation before this one, it contains general configuration and information.

Bootstrapping the project

First, we need a new project.Create a new project with the following command (replace the version placeholder with the correct one):

mvn io.quarkus:quarkus-maven-plugin:${quarkusVersion}:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=secretmanager-quickstart \
    -Dextensions="resteasy-reactive-jackson,quarkus-google-cloud-secret-manager"
cd secretmanager-quickstart

This command generates a Maven project, importing the Google Cloud Secret Manager extension.

If you already have your Quarkus project configured, you can add the quarkus-google-cloud-secret-manager extension to your project by running the following command in your project base directory:

./mvnw quarkus:add-extension -Dextensions="quarkus-google-cloud-secret-manager"

This will add the following to your pom.xml:

<dependency>
    <groupId>io.quarkiverse.googlecloudservices</groupId>
    <artifactId>quarkus-google-cloud-secret-manager</artifactId>
</dependency>

Client Usage Example

This is an example fetching a single secret from GCP Secret Manager.

First, you’ll have to create the secret in the GCP Secret Manager, as described in Google’s documentation at https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets.

The following gcloud commands will create a secret named test-secret with the value s3cr3t in it.

gcloud secrets create test-secret --replication-policy="automatic"
printf "s3cr3t" | gcloud secrets versions add integration-test --data-file=-

The secretName parameter in the examples below refer to the name you give your secret, whereas the injected secretManagerProjectId refers to the name of your project on GCP.

import com.google.cloud.secretmanager.v1.AccessSecretVersionResponse;
import com.google.cloud.secretmanager.v1.SecretManagerServiceClient;
import com.google.cloud.secretmanager.v1.SecretVersionName;
import org.eclipse.microprofile.config.inject.ConfigProperty;

@RequestScoped
public class GCPSecretManager {

    @Inject
    SecretManagerServiceClient client;

    @ConfigProperty(name = "quarkus.google.cloud.project-id")
    String projectId;

    public String getSecretFromSecretManager(String secretName) throws IOException {
        SecretVersionName secretVersionName = SecretVersionName.of(projectId, secretName, "latest");
        AccessSecretVersionResponse response = client.accessSecretVersion(secretVersionName);
        return response.getPayload().getData().toStringUtf8();
    }
}

Reading Secrets as Properties

You can also load and reference secrets from GCP Secret Manager in your application.properties file by using the following syntax:

# 1. Long form - specify the project ID, secret ID, and version
${sm//projects/<project-id>/secrets/<secret-id>/versions/<version-id>}

# 2. Long form - specify project ID, secret ID, and use latest version
${sm//projects/<project-id>/secrets/<secret-id>}

# 3. Short form - specify project ID, secret ID, and version
${sm//<project-id>/<secret-id>/<version-id>}

# 4. Short form - default project; specify secret + version
#
# The default project is inferred from the "quarkus.google.cloud.project-id" property
# in your application.properties, or from application-default credentials if
# this is not set.
${sm//<secret-id>/<version>}

# 5. Shortest form - specify secret ID, use default project and latest version.
${sm//<secret-id>}

You can use this syntax to load secrets directly from application.properties:

quarkus.database.password=${sm//my-secret-id/latest}

Alternatively, you can also reference the secret value as a @ConfigProperty without specifying it from application.properties.

@ConfigProperty(name = "${sm//my-secret-id}")
String secret;
When using secrets directly on your application.properties, the Google Cloud authentication is made early so access token based authentication cannot be used.