Spring Vault

1. Overview

HashiCorp’s Vault is a tool to store and secure secrets. Vault, in general, solves the software development security problem of how to manage secrets. To learn more about it, check out our article here.

Spring Vault provides Spring abstractions to the HashiCorp’s Vault.

In this tutorial, we’ll go over an example on how to store and retrieve secrets from the Vault.

2. Maven Dependencies

To start with, let’s take a look at the dependencies we need to start working with Spring Vault:

<dependencies>
    <dependency>
        <groupId>org.springframework.vault</groupId>
        <artifactId>spring-vault-core</artifactId>
        <version>2.0.1.RELEASE</version>
    </dependency>
</dependencies>

The latest version of spring-vault-core can be found on Maven Central.

3. Configuring Vault

Let’s now go through the steps needed to configure Vault.

3.1. Creating a VaultTemplate

To secure our secrets, we’ll have to instantiate a VaultTemplate for which we need VaultEndpoint and TokenAuthentication instances:

VaultTemplate vaultTemplate = new VaultTemplate(new VaultEndpoint(),
  new TokenAuthentication("00000000-0000-0000-0000-000000000000"));

3.2. Creating a VaultEndpoint

There’re a few ways to instantiate VaultEndpoint. Let’s take a look at some of them.

The first one is to simply instantiate it using a default constructor, which will create a default endpoint pointing to http://localhost:8200:

VaultEndpoint endpoint = new VaultEndpoint();

Another way is to create a VaultEndpoint by specifying Vault’s host and port:

VaultEndpoint endpoint = VaultEndpoint.create("host", port);

And finally, we can also create it from the Vault URL:

VaultEndpoint endpoint = VaultEndpoint.from(new URI("vault uri"));

There are a few things to notice here – Vault will be configured with a root token of 00000000-0000-0000-0000-000000000000 to run this application.

In our example, we’ve used the TokenAuthentication, but there are other authentication methods supported as well.

4. Configuring Vault Beans Using Spring

With Spring, we can configure the Vault in a couple of ways. One is by extending the AbstractVaultConfiguration, and the other one is by using EnvironmentVaultConfiguration which makes use of Spring’s environment properties.

We’ll now go over both ways.

4.1. Using AbstractVaultConfiguration

Let’s create a class which extends AbstractVaultConfiguration, to configure Spring Vault:

@Configuration
public class VaultConfig extends AbstractVaultConfiguration {

    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("00000000-0000-0000-0000-000000000000");
    }

    @Override
    public VaultEndpoint vaultEndpoint() {
        return VaultEndpoint.create("host", 8020);
    }
}

This approach is similar to what we’ve seen in the previous section. What’s different is that we’ve used Spring Vault to configure Vault beans by extending the abstract class AbstractVaultConfiguration.

We just have to provide the implementation to configure VaultEndpoint and ClientAuthentication.

4.2. Using EnvironmentVaultConfiguration

We can also configure Spring Vault using the EnviromentVaultConfiguration:

@Configuration
@PropertySource(value = { "vault-config.properties" })
@Import(value = EnvironmentVaultConfiguration.class)
public class VaultEnvironmentConfig {
}

EnvironmentVaultConfiguration makes use of Spring’s PropertySource to configure Vault beans. We just need to supply the properties file with some acceptable entries.

More information on all of the predefined properties can be found in the official documentation.

To configure the Vault, we need at least a couple of properties:

vault.uri=https://localhost:8200
vault.token=00000000-0000-0000-0000-000000000000

5. Securing Secrets

We’ll create a simple Credentials class that maps to username and password:

public class Credentials {

    private String username;
    private String password;

    // standard constructors, getters, setters
}

Now, let’s see how we can secure our Credentials object using the VaultTemplate:

Credentials credentials = new Credentials("username", "password");
vaultTemplate.write("secret/myapp", credentials);

With these lines completed, our secrets are now stored.

Next, we’ll see how to access them.

6. Accessing Secrets

We can access the secured secrets using the read() method in VaultTemplate, which returns the VaultResponseSupport as a response:

VaultResponseSupport<Credentials> response = vaultTemplate
  .read("secret/myapp", Credentials.class);
String username = response.getData().getUsername();
String password = response.getData().getPassword();

Our secret values are now ready.

7. Conclusion

In this article, we’ve learned about the basics of Spring Vault with an example showing how the Vault works in typical scenarios.

As usual, the source code presented here can be found over on GitHub.

Leave a Reply

Your email address will not be published.