HashiCorp Vault authentication with Spring Cloud and Spring Boot

This article explains HashiCorp Vault setup and usage with Spring Cloud and Spring Boot. Vault supports multiple authentication methods, in this article we will discuss 2 of those methods

  1. Token based authentication
  2. AppRole authentication

Update: Starting with Spring Boot 2.4.x, spring boot changed the way config files are processed. Updated the article to reflect the same.

Technologies

  1. Spring Boot 2.4.x
  2. Spring Cloud Vault Config 3.0.0-SNAPSHOT
  3. Java 11

Vault setup – Standalone

1. Create a directory named HashiCorpVault and store all the setup files, config files there
2. Download vault library from Vault and add it to the PATH
3. Execute the following command to enable vault commands to autocomplete

$ vault -autocomplete-install

4. Create config.hcl file in HashiCorpVault directory

storage “consul” {
address = “127.0.0.1:8500”
path = “vault/”
}

ui = true

listener “tcp” {
address = “127.0.0.1:8200”
tls_disable = 1
}

6. Start consul with the following command
$ consul agent -dev

5. Download consul binary file from https://www.consul.io/downloads.html and add it to the PATH

7. Open a new terminal and execute the following command to start vault
$ vault server -config=<path_to_file>/config.hcl

8. Open one more terminal and execute the following command
$ export VAULT_ADDR=http://127.0.0.1:8200

9. Initialize the vault with the following command and copy the keys somewhere safe

$ vault operator init
Unseal Key 1: E4GnjX+VP9G50uWQNcwpCflzGAMKGR38BbQywgq4I6L8
Unseal Key 2: PYMxcCOswEYMNz7N6UW53Up6nu6y+SjAPwTJOTtkju3d
Unseal Key 3: yuJ5cSxC7tSBR5mMVJ/WJ9bfhhfGb+uwWw9FQR0JKILh
Unseal Key 4: 0vdvEFHM9PHEGMctJrl2ylHqoKQK8DLkfMU6ntmDz6jv
Unseal Key 5: cI8yglWJX+jPf/yQG7Sg6SPWzy0WyrBPvaFTOAYkPJTx

Initial Root Token: 62421926–81b9-b202–86f8–8850176c0cf3

10. Begin unsealing the Vault with the following command. Execute this 3 times, each time enter different keys from step 9
$ vault operator unseal

11. Go to http://localhost:8200/ui/ to see the vault UI

Enable Secret Engine

  1. Go to http://127.0.0.1:8200/ui/vault/secrets and click on ‘Enable Secret Engine’ and select ‘KV’ under generic(shown below)
Enable KV Engine

2. In the next screen at the path field, enter ‘secrets’ or ‘vaultdemo’(or any name of your choice)

3. Now go to main screen http://127.0.0.1:8200/ui/vault/secrets and select vaultdemo engine and create new secret. It has to be the format <application_name>/<profile>.

pres/dev
pres/test
pres/prod

4. The application name can also be the format <sub_domain>/<application_name>/<profile>

Ex: vaultdemo/app/pres/dev

5. Click on Create New Version and enter the following passwords

Dev: username=root password=bcmc1234 url=”jdbc:mysql://localhost:3306/bookstore_dev”

Test: username=sa password=”” url=”jdbc:h2:mem:bookstore_test”

Prod: username=root password=bcmc1234 url=”jdbc:mysql://localhost:3306/bookstore_prod”

6. Go to http://localhost:8200/ui/vault/policies/acl and create the ACL policy named vault-demo-policy that controls access to our secret engine (will be created in later steps)

path “vaultdemo/pres/*” {
capabilities = [“read”,”create”,”update”,"list"]
}

Configure Spring boot project — Token authentication

Go to spring boot project src/main/resources directory and create application.yml file with the following content

spring:
application:
name: pres
cloud:
vault:
authentication: TOKEN
token: ${token}
scheme: http
host: localhost
port: 8200
kv:
enabled: true
backend: vaultdemo
config:
import: vault://secret/app/pres/

7. Use the following syntax to export token to Linux machine environment variable
$ export VAULT_TOKEN=<Your token>

7. Spring uses bootstrap.yml file to load vault config and key-value pairs required by the spring profiles before initializing the context. The ${VAULT_TOKEN} value will be taken from machine environmental variables.
8. Make sure to include all the profiles in include attribute. This instructs Spring to load those profiles before initializing the context
9. Now create application-dev.yml file with the following content. The keys from the vault should match here i.e ${username},${password},${url}

## Server Properties
server:
port: 8081

spring:
config:
import: vault://secret/app/pres/dev
activate:
on-profile: "dev"
datasource:
username: ${username}
password: ${password}
url: ${url}

10. Create application-test.yml and application-prod.yml config files for Test and Prod environments

11. Create maven profiles in pom.xml that will be used to activate the profile. See pom.xml for reference

## Select profile
spring:
profiles:
active: @activatedProperties@

AppRole authentication

  1. Go to http://127.0.0.1:8200/ui/vault/access and click on ‘Enable New Method’ and select ‘AppRole’
Enable AppRole authentication method

2. Create new app role for your project

$ vault write auth/approle/role/your-app-name-read \secret_id_num_uses=0 \secret_id_ttl=0 \token_num_uses=0 \token_ttl=10m \token_max_ttl=10m \policies=approle-your-app-name-read

3. Retrie the role ID

$ vault read auth/approle/role/your-app-name-read/role-id

4. Get secret ID

$ vault write -f auth/approle/role/your-app-name-read/secret-id

5. Configure Spring Boot project to use App Role authentication. Create application.yml file

spring:
cloud:
vault:
authentication: APPROLE
app-role:
role-id: ${role-id}
secret-id: ${secret-id}
role: pres-read
app-role-path: approle
uri: http://localhost:8200
connection-timeout: 5000
read-timeout: 15000
kv:
enabled: true
backend
: vaultdemo
application-name: pres
config:
import: vault://secret/app/pres/

6. During application startup provide role-id and secret-id, which helps Spring Boot app to get username and password from the vault

Build and Run the project

  1. Clone this project and build it using maven. Make sure to pass -Ddev or -Dtest parameter to maven command, which selects spring profile id and passes to application.yml file

    $ mvn clean package -Dtest -DskipTests
  2. Now run the project with the java command. This should start my project using the profile from the previous step

    java -jar target/vaultdemo-0.0.1.jar
  3. Go to http://localhost:8081/api/v1/book/list to see list of books retrieved from the database whose credentials retrieved from Vault

Code uploaded to Github for reference. Happy Coding 🙂

Pavan Kumar Jadda
Pavan Kumar Jadda
Articles: 36

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.