This sample project demonstrates...
What this is not?
[TBD]
This example just uses the Vault sample dev server.
To start up the Vault Server:
vault server -dev
Input some secrets:
As an example...
vault kv put secret/app-secrets temp_pwd=ik1ahTho$a0eim8a api_key=a4db08b7-5729-4ba9-8c08-f2df493465a1 generic_secret=s3cr3t
Note:* Above secrets are NOT real secrets. They are secret for purposefully for this demo repo.
See SecretsService.java
:
All it does is it makes a REST API call to the Vault Server at the location of VAULT_ADDR and authentication with the VAULT_TOKEN. It fetches back the secret at the predefined path as for the purpose of this demo:
private static final String SECRET_URL_PATH = "/v1/secret/data/app-secrets";
We then lastly, filter out the required field of the secret we are after by navigating through the JSON tree via the external JSON Jackson Library.
Note that for the simplicity of this particular demo I just fetch a string JSON response back rather than complicating things in mapping the returned JSON response into a POJO (which is probable but given that most of the data returned back are metadata which we are not really concerned about i just didn't feel it warrants that approach).
Essentially what it is doing is making a curl request:
curl -H "X-VAULT-TOKEN: $VAULT_TOKEN" $VAULT_ADDR/v1/secret/data/app-secrets
And it returns the following HTTP response body:
as an example:
{
"request_id": "cd60061c-e16c-b7c4-3769-12b6e1a55e24",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": {
"data": {
"api_key": "a4db08b7-5729-4ba9-8c08-f2df493465a1",
"generic_secret": "s3cr3t",
"temp_pwd": "ik1ahTho"
},
"metadata": {
"created_time": "2021-12-28T13:18:43.767322Z",
"custom_metadata": null,
"deletion_time": "",
"destroyed": false,
"version": 1
}
},
"wrap_info": null,
"warnings": null,
"auth": null
}
So the Java code is merely a wrapper around the above.
Ensure the the demo.mode
property is set to APP-CONFIG
demo:
mode: APP-CONFIG
Configuration
In the application.yaml
configuration file we define the connection details to Vault:
e.g.
vault:
addr: http://127.0.0.1:8200
token: your-token
RestTemplate Configuration
The base path of the "Vault Address" is wired into the configuration of the RestTemplate Spring Bean:
@Configuration
public class RestTemplateConfig {
@Value("${vault.addr}")
private String vaultAddr;
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
RestTemplate restTemplate = restTemplateBuilder.build();
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(vaultAddr));
return restTemplate;
}
}
In the SecretsService.java
class:
@Service
public class SecretsService {
// other code omitted for brevity
@Value("${vault.token}")
private String vaultToken;
// other code omitted for brevity
We autowire the Vault Token
that is used for authentication to Vault.
Rather than hardcode the Vault details (especially the VAULT TOKEN which is a secret itself), we can inject these properties into the application via the following Environment Variables:
VAULT_ADDR VAULT_TOKEN
Ensure the the demo.mode
property is set to ENV-VAR
demo:
mode: ENV-VAR
Export the VAULT_ADDR and VAULT_TOKEN environment variables respectively.
As can be seen in the following code:
if (demoMode.equals(DemoMode.ENV_VAR.getDemoModeConf())){
headers.set("X-VAULT-TOKEN", System.getenv("VAULT_TOKEN"));
} else if (demoMode.equals(DemoMode.APP_CONFIG.getDemoModeConf())){
headers.set("X-VAULT-TOKEN", vaultToken);
}
We switch the method we obtain the VAULT_TOKEN accordingly.
Colin But