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.