Secret Management

Cloud Secret Manager

Secret Manager is a secure and convenient storage system for API keys, passwords, certificates, and other sensitive data. Secret Manager provides a central place and single source of truth to manage, access, and audit secrets across Google Cloud.

Enable API

gcloud services enable secretmanager.googleapis.com

Create a Secret

echo -n "qwerty" | \
gcloud secrets create order-db-password --data-file=- --replication-policy=automatic

List Secrets

gcloud secrets list

Delete a Secret

gcloud secrets delete order-db-password

Assign IAM Permission

You can finely control CRUD permissions for an account (user account, service account, a Google Group) to a secret. See the Secret Manager IAM access control for more information.

gcloud secrets add-iam-policy-binding --help

Spring Cloud Secret Manager

You can easily get value from Secret Manager by using Spring Cloud GCP's Secret Manager starter.

Dependency

Add the Spring Cloud GCP Secret Manager starter:

Maven
Gradle
Maven
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
</dependency>
Gradle
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-secretmanager'

Configuration

Secret Manager can be configured during Bootstrap phase, via bootstrap.properties. The starter automatically enables Secret Manager integration. But you can also disable it by configuring spring.cloud.gcp.secretmanager.enabled=false in a different Spring Boot profile.

Read Spring Cloud GCP Secret Manager configuration documentation for more details.

Property Source

You can access individual secrets in stored in Secret Manager by looking up property keys with the sm:// prefix.

@Value Annotation

You can inject the secret value by using the Value annotation.

@Value("sm://order-db-password") String databasePassword;

Properties Mapping

You can refer to the secret value like any other properties, and reference the secret values in a properties file.

application.properties
spring.datasource.password=${sm://order-db-password}

Mapping properties this way, rather than hard-coding the Secret Manager property key using @Value annotation can be help you utilize multiple profiles.

For example, you can have application-dev.properties with:

application.properties
spring.datasource.password=${sm://order-db-dev-password}

And, for production, create an application-prod.properties with:

application-prod.properties
spring.datasource.password=${sm://order-db-prod-password}

Property Key Syntax

Form

Example

Short

sm://order-db-password

Short - Versioned

sm://order-db-password/1

Short - Project Scoped and Versioned

sm://your-project/order-db-password/1

Long - Project Scoped

sm://projects/your-project/order-db-password/1

Long - Fully Qualified

sm://projects/your-project/secrets/order-db-password/versions/1

Local Development

Use Spring Boot Profile to differentiate local development profile vs deployed environments. For example, for local development, you can hard-code test credentials/values, but for the cloud environment, you can use a different profile.

Default Profile

Configure the default profile to disable Secret Manager

bootstrap.properties
spring.cloud.gcp.secretmanager.enabled=false

Hard-code the local test credentials with the value as usual.

application.properties
...
spring.datasource.password=admin

Production Profile

Configure the production profile to enable Secret Manager.

bootstrap-prod.properties
spring.cloud.gcp.secretmanager.enabled=false

Configure production profile to retrieve the credential from Secret Manager.

application-prod.properties
...
spring.datasource.password=${sm://order-db-prod-password}

Start your application with the profile, for example:

# From Maven
./mvnw spring-boot:run -Dspring-boot.run.profiles=prod
# From Java startup command
java -jar target/...jar -Dspring.profiles.active=prod

Samples