Learn how to securely store and dynamically reload secrets using Spring Cloud Vault. Configure a Spring Boot 3.4.1 microservice to retrieve sensitive configuration data (e.g., database credentials) from HashiCorp Vault, and refresh them at runtime without restarting the application.
-
Download the Vault binary.
- Visit Vault Downloads and download the latest Vault binary for your operating system.
-
Extract the Vault binary.
- Windows:
- Unzip (e.g.,
vault_<version>_windows_amd64.zip
) to a folder likeC:\HashiCorp\Vault
.
- Unzip (e.g.,
- macOS/Linux:
- Extract with:
unzip vault_<version>_<platform>.zip -d ~/HashiCorp/Vault
- Extract with:
- Windows:
-
Add Vault to the system PATH.
- Windows:
- Add the folder with
vault.exe
to Path via Environment Variables.
- Add the folder with
- macOS/Linux:
- Update your shell config (e.g.,
~/.bashrc
or~/.zshrc
):export PATH=$PATH:~/HashiCorp/Vault
- Update your shell config (e.g.,
- Windows:
-
Start Vault in development mode.
- From a terminal:
vault server -dev
- Copy the displayed Root Token (e.g.,
root
ors.xxxxx...
).
- From a terminal:
-
Set Vault environment variables.
- Windows (Command Prompt):
set VAULT_ADDR=http://127.0.0.1:8200 set VAULT_TOKEN=<your-root-token>
- macOS/Linux:
export VAULT_ADDR=http://127.0.0.1:8200 export VAULT_TOKEN=<your-root-token>
- Windows (Command Prompt):
-
Enable the KV secrets engine in Vault.
- Run:
vault secrets enable -path=secret kv
- This creates a secret engine at
secret/
.
- Run:
-
Add secrets to Vault.
- For example, store user-service credentials:
vault kv put secret/user-service username=root password=root123
- This creates a secret at
secret/user-service
with two key-value pairs:username=root
password=root123
- For example, store user-service credentials:
-
Verify the stored secret.
- Run:
vault kv get secret/user-service
- Confirm the displayed data matches what you stored.
- Run:
-
Generate a new Spring Boot project for
UserService
.- Visit https://start.spring.io/.
- Configure:
- Spring Boot Version: 3.4.1
- Group Id:
com.microservices
- Artifact Id:
user-service
- Name:
UserService
- Package Name:
com.microservices.userservice
- Dependencies:
- Spring Web
- Spring Cloud Vault Config
- Spring Boot Actuator
- Download and extract into a folder named
UserService
.
-
Import
UserService
into your IDE. -
Add Spring Cloud Vault configurations.
- In
src/main/resources/application.properties
:spring.application.name=user-service # Vault connection spring.cloud.vault.uri=http://127.0.0.1:8200 spring.cloud.vault.token=<your-root-token> spring.cloud.vault.kv.enabled=true spring.cloud.vault.kv.backend=secret spring.cloud.vault.kv.application-name=user-service
- In
-
Create a configuration class to map secrets.
- In
src/main/java/com/microservices/userservice
, createVaultConfig.java
:package com.microservices.userservice; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "vault") public class VaultConfig { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
- In
-
Expose secrets via a REST controller.
- In
VaultController.java
:package com.microservices.userservice; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class VaultController { @Autowired private VaultConfig vaultConfig; @GetMapping("/secrets") public String getSecrets() { return "Username: " + vaultConfig.getUsername() + ", Password: " + vaultConfig.getPassword(); } }
- In
-
Run the application.
- From the
UserService
directory:./mvnw spring-boot:run
- From the
-
Test the
/secrets
endpoint.- Go to:
http://localhost:8080/secrets
- Confirm it returns Username: root, Password: root123 (from Vault).
- Go to:
-
Add Actuator for dynamic refresh.
- In
pom.xml
:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
- In
-
Expose the refresh endpoint.
- In
application.properties
:management.endpoints.web.exposure.include=refresh
- In
-
Update secrets in Vault.
- For example:
vault kv put secret/user-service username=admin password=admin123
- For example:
-
Trigger a configuration refresh.
- Use:
curl -X POST http://localhost:8080/actuator/refresh
- Use:
-
Verify the updated secrets.
- Re-check
http://localhost:8080/secrets
. - Confirm Username: admin, Password: admin123 is displayed.
- Re-check
In this lab, you successfully:
- Installed and started Vault in development mode.
- Stored secrets (username/password) in Vault under
secret/user-service
. - Configured a Spring Boot 3.4.1 microservice (
UserService
) to fetch and map those secrets dynamically using Spring Cloud Vault. - Enabled Actuator to refresh secrets at runtime without restarting the application.
This approach ensures secure management of sensitive information (like credentials) and makes secret rotation and updating seamless.