Skip to main content

Managing secrets in Spring Boot with Vault

By July 15, 2021No Comments

Managing secrets in Spring Boot with Vault

In this blog I will be showcasing the Spring Cloud Vault framework which uses HashiCorp Vault to pull dynamic secrets into Spring Boot applications. I will be running this demo on GKE and OpenShift and all manifests will be available in this GitHub repo.

What is Vault?

Vault is a tool for securely accessing secrets.Vault allows users to store, manage and control access to tokens, username password, database credentials and TLS certificates. There are many secrets management tools out there but Vault has gained a lot of popularity thanks to it’s flexible API and providing encryption at rest and in flight.

There have been cases of applications leaking credentials through logs, diagnostic output, external logging to a logging stack. Vault can provide dynamic secrets which help provide short-lived ephemeral credentials to applications instead of long live credentials. With dynamic secrets, even if an application writes it to an external system, it is valid for a specific period of time.

What is Spring Cloud Vault?

Spring Cloud Vault Config provides client-side support for externalized configuration in a distributed system. Instead of hard coding IPs or username/passwords, Spring Vault Cloud allows the user to simply add the Vault URL for grabbing passwords. This puts the control in the hands of the security team who are responsible for providing the application team with a token and the Vault end point.

How to configure Spring Cloud Vault for Kubernetes

For demo purposes, I used the application provided by the Spring Cloud Vault getting started guide and customized it to run as pods on Google Kubernetes Engine and for OpenShift Container Platform.

Here’s my Dockerfile:

FROM maven:3.5-jdk-8-alpine ENV MVN_PROFILE=placeholder ENV ROLE_ID=69907c2e-b6fe-0daf-4ea5-dc8b9cdfa85c ENV SECRET_ID=placeholder COPY app/ . CMD ./mvnw spring-boot:run${MVN_PROFILE} ; tail -f /dev/null

The important role of Maven profile

Notice the last line containing MVN_PROFILE. I will be passing the maven profile as an environment variable in my kubernetes manifests. The maven profile is used to specify the endpoint in Vault the application will point to retrieve the secrets.

Here’s my .properties file:     uri:     application-name: weirdscience     authentication: APPROLE     app-role:         role-id: ${ROLE_ID}         secret-id: ${SECRET_ID}

In our example a mvnw run <MVN-PROFILE> will point our spring application to retrieve a secret from<MVN-PROFILE>

Run the example on Kubernetes

  • Create Secret ID as a kubernetes secret:

Next step is to create a secret in your kubernetes namespace which will contain the Secret ID for Vault. The docker image has the Role ID baked into the image. We will externalize the Secret ID to create a two-factor mechanism to log in to Vault. This Secret ID will be managed by the security team and the security team has the ability to revoke this and to limit how many times this Secret ID can be used.

Here’s the manifest for my secret:

apiVersion: v1 kind: Secret metadata:   name: secret-id type: data:   password: "<secret-id>" ## add your secret-id here
  • Create the pod:

After the docker image has been built and stored in a registry where both GKE and OpenShift can pull from, it is time to run the example. Here’s the manifest for my pod:

apiVersion: v1 kind: Pod metadata:   name: spring-vault spec:   containers:   - name: spring-vault     image: ## replace the endpoint with your registry     env:       - name: MVN_PROFILE         value: <MAVEN-PROFILE> ## add your Maven Profile       - name: SECRET_ID         valueFrom:           secretKeyRef:             name: secret-id             key: password   restartPolicy: Never

In the above, I can change the maven profile to GKE or OpenShift to retrieve the secret. Here it is in action:

For OpenShift:

<img src="" %}

The above outputs the username as "redhat" and the password as "IamRunningOnOpenShift" with the MAVEN_PROFILE set to OpenShift

For GKE:

<img src="" %}

The above outputs the username as "google" and the password as "IamRunningOnGKE" with the MAVEN_PROFILE set to GKE.

And there you have it! This example showcases the underlying functionality of Vault with Spring Boot. This framework can be built into complex microservices which could be running on GKE and/or OpenShift.

The above code is in this public repo here.

This demo was also recorded live at one of Arctiq’s event. A recap can be seen here.

Interested in finding out more about Hashicorp Vault, Google Kubernetes Engine and RedHat OpenShift? We would love to hear from you!

//take the first step