DEV Community

Cover image for Safeguarding Secrets in Spring Boot with Vault
Shahab Ranjbary
Shahab Ranjbary

Posted on

Safeguarding Secrets in Spring Boot with Vault

When developing Spring Boot applications, we often encounter the need to manage sensitive information like database passwords, application keys, and other secrets. Typically, these secrets might reside in application.properties or application.yml. Pushing such sensitive information to repositories is risky. Thankfully, there's HashiCorp's Vault.

Understanding Vault

Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, or certificates. Vault provides a unified interface to any secret while providing tight access control and recording a detailed audit log.

Setting Up Vault with Docker Compose

For rapid deployment, especially during development, Docker Compose offers a convenient method to get Vault up and running.

1.Create a file named docker-compose.yml and add the following:

version: '3'

services:
  vault:
    image: vault:1.13.3
    container_name: vault_dev
    ports:
      - "8200:8200"
    environment:
      VAULT_DEV_ROOT_TOKEN_ID: myroot
      VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
    cap_add:
      - IPC_LOCK
    command: server -dev
Enter fullscreen mode Exit fullscreen mode

2.Run docker-compose up to start the Vault server.

3.Access the Vault UI at http://localhost:8200/ui and log in with the token myroot.

After logging in, you can view this page

Image description

Enable KV engine

Image description

Add the secrets in the specific path you want eg Postgresql settings

Image description

Integrating Vault with Spring Boot

Once Vault is up and running, the next step is integrating it with your Spring Boot application.

1.Setting Environments

export VAULT_URI=http://localhost:8200
export VAULT_TOKEN=myroot
Enter fullscreen mode Exit fullscreen mode

2.Spring Boot Initial Setup:
Set up a basic Spring Boot application. If you're new to this, Spring Initializr provides a quick way to bootstrap a new Spring Boot project.

3.Maven Dependency:
To integrate Spring Vault, add the following dependency to your Maven pom.xml:

<dependency>
    <groupId>org.springframework.vault</groupId>
    <artifactId>spring-vault-core</artifactId>
    <version>3.0.4</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

4.Integration Code:
First, define your Vault configuration:

public class VaultConfiguration {
    private static final String token;
    private static final String uri;

    static {
        token = System.getenv("VAULT_TOKEN");
        uri = System.getenv("VAULT_URI");
    }

    public static String getToken() {
        return token;
    }

    public static String getUri() {
        return uri;
    }
}
Enter fullscreen mode Exit fullscreen mode

Then, use a utility to read secrets from Vault:

public class VaultConfigReaderUtil {
    public static Properties read(String path) {
        String MAIN_VAULT_PATH = "kv/data/myapplication";
        VaultEndpoint endpoint;
        Properties properties = new Properties();

        try {
            endpoint = VaultEndpoint.from(new URI(VaultConfiguration.getUri()));
            VaultTemplate vaultTemplate = new VaultTemplate(endpoint, new TokenAuthentication(VaultConfiguration.getToken()));
            VaultResponse response = vaultTemplate.read("%s/%s".formatted(MAIN_VAULT_PATH, path));
            Map<String, Object> mapData = (Map<String, Object>) response.getRequiredData().get("data");
            properties.putAll(mapData);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        return properties;
    }
}
Enter fullscreen mode Exit fullscreen mode

Lastly, in your main application, use the utility to fetch secrets and feed them to Spring Boot:

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        Properties props = new Properties();
        Properties postgresProp = VaultConfigReaderUtil.read("postgres");
        props.putAll(postgresProp);

        SpringApplicationBuilder springApplication = new SpringApplicationBuilder(MyApplication.class);
        springApplication.properties(props).run(args);
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

In the ever-evolving landscape of software development, security remains paramount. Secrets management is a fundamental aspect of ensuring that our applications are robust against breaches and unforeseen vulnerabilities. As we've explored, Vault by HashiCorp offers a comprehensive solution to this challenge, seamlessly integrating with frameworks like Spring Boot.

Utilizing Docker Compose, we've streamlined the deployment of Vault, making it more accessible, especially during the development phase. However, it's essential to understand that while development configurations simplify processes, they aren't suitable for production environments. Always ensure a secure, production-ready configuration for Vault when deploying in live scenarios.

Spring Boot's flexibility and vast ecosystem, paired with Vault's secure secrets management capabilities, provide developers with powerful tools to build secure, scalable, and efficient applications. As we continue to innovate and build, let's prioritize the safety and integrity of our applications, ensuring that our secrets remain just that – secret.

Top comments (0)