# 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

```bash
gcloud services enable secretmanager.googleapis.com
```

### Create a Secret

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

### List Secrets

```bash
gcloud secrets list
```

### Delete a Secret

```bash
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](https://cloud.google.com/secret-manager/docs/access-control) for more information.

```bash
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](https://cloud.spring.io/spring-cloud-static/spring-cloud-gcp/current/reference/html/#secret-manager).

### Dependency

Add the Spring Cloud GCP Secret Manager starter:

{% tabs %}
{% tab title="Maven" %}

```markup
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
</dependency>
```

{% endtab %}

{% tab title="Gradle" %}

```groovy
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-secretmanager'
```

{% endtab %}
{% endtabs %}

### 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.

{% hint style="info" %}
Read [Spring Cloud GCP Secret Manager configuration](https://cloud.spring.io/spring-cloud-static/spring-cloud-gcp/current/reference/html/#configuration-10) documentation for more details.
{% endhint %}

### 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.

```java
@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.

{% code title="application.properties" %}

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

{% endcode %}

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:

{% code title="application.properties" %}

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

{% endcode %}

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

{% code title="application-prod.properties" %}

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

{% endcode %}

#### 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

{% code title="bootstrap.properties" %}

```
spring.cloud.gcp.secretmanager.enabled=false
```

{% endcode %}

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

{% code title="application.properties" %}

```
...
spring.datasource.password=admin
```

{% endcode %}

#### Production Profile

Configure the production profile to enable Secret Manager.

{% code title="bootstrap-prod.properties" %}

```
spring.cloud.gcp.secretmanager.enabled=true
```

{% endcode %}

Configure production profile to retrieve the credential from Secret Manager.

{% code title="application-prod.properties" %}

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

{% endcode %}

Start your application with the profile, for example:

```bash
# From Maven
./mvnw spring-boot:run -Dspring-boot.run.profiles=prod

# From Java startup command
java -jar target/...jar -Dspring.profiles.active=prod
```

### Samples

* [Spring Cloud GCP Secret Manager sample](https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-secretmanager-sample)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://spring-gcp.saturnism.me/app-dev/cloud-services/secret-management.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
