Show List
Java Spring Boot Application to Write and Read Secrets from Vault
In this demo we are going to create a Spring Boot application to write secret to local running Vault instance and then read the secret.
Go to Spring initializr website "https://start.spring.io/" and create a Java Project with dependencies: spring-boot-starter-web and spring-cloud-starter-vault-config. Download the project zip and extract to a folder.
We have selected gradle as the build tool for the project. Here is the build.gradle file:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.7'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'vault.secrets'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2021.0.5")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-vault-config'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
Here is the project structure
Update the DemoApplication.java file as below. Spring provides libraries to integrate with Hashicorp vault. We are using command line runner interface to perform the Vault operations when the application starts.
- The application connects to local Vault server at port 8200 running in dev mode.
- For this demo, you can use the root token or the token for a role id.
- The secrets are going to be stored at and read from path secret/mysecretslocation/creds
package vault.secrets.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Map;
import java.util.HashMap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.support.Versioned;
import org.springframework.vault.core.VaultTemplate;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
context.close();
}
@Override
public void run(String... strings) throws Exception {
VaultEndpoint vaultEndpoint = new VaultEndpoint();
//Local running instance of Vault
vaultEndpoint.setHost("127.0.0.1");
vaultEndpoint.setPort(8200);
vaultEndpoint.setScheme("http");
// Authenticate with the token. This token should be valid.
VaultTemplate vaultTemplate = new VaultTemplate(
vaultEndpoint,
new TokenAuthentication("hvs.Z8swD4DRYQDtuHGlkkxFkTRG"));
// Writing the secret to Vault
Map<String, String> data = new HashMap<>();
data.put("password", "top_secret_password");
vaultTemplate
.opsForVersionedKeyValue("secret")
.put("mysecretslocation/creds", data);
System.out.println("Secret written successfully.");
// Reading the secret from Vault
Versioned<Map<String, Object>> secret = vaultTemplate
.opsForVersionedKeyValue("secret")
.get("mysecretslocation/creds");
String password = "";
if (secret != null && secret.hasData()) {
password = (String) secret.getData().get("password");
}
if (!password.equals("top_secret_password")) {
throw new Exception("Unexpected password");
}
System.out.println("Secret read successfully");
}
}
When the Spring Boot application is run, the results can be viewed on the console confirming that the secret was written and read successfully.
8:04:31 AM: Executing task ':DemoApplication.main()'... > Task :compileJava > Task :processResources UP-TO-DATE > Task :classes > Task :DemoApplication.main() . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.7) 2022-12-27 08:04:35.727 INFO 14328 --- [ main] vault.secrets.demo.DemoApplication : Starting DemoApplication using Java 11.0.15 on sm15 with PID 14328 (C:\Users\mail2\Downloads\demo\build\classes\java\main started by mail2 in C:\Users\mail2\Downloads\demo) 2022-12-27 08:04:35.730 INFO 14328 --- [ main] vault.secrets.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default" 2022-12-27 08:04:36.579 INFO 14328 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=83794b8e-03e1-3bf4-aa53-130e4a37486a 2022-12-27 08:04:37.300 INFO 14328 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2022-12-27 08:04:37.301 INFO 14328 --- [ main] o.a.catalina.core.AprLifecycleListener : An older version [1.2.28] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum version of [1.2.30] 2022-12-27 08:04:37.302 INFO 14328 --- [ main] o.a.catalina.core.AprLifecycleListener : Loaded Apache Tomcat Native library [1.2.28] using APR version [1.7.0]. 2022-12-27 08:04:37.302 INFO 14328 --- [ main] o.a.catalina.core.AprLifecycleListener : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true]. 2022-12-27 08:04:37.302 INFO 14328 --- [ main] o.a.catalina.core.AprLifecycleListener : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] 2022-12-27 08:04:37.305 INFO 14328 --- [ main] o.a.catalina.core.AprLifecycleListener : OpenSSL successfully initialized [OpenSSL 1.1.1k 25 Mar 2021] 2022-12-27 08:04:37.315 INFO 14328 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-12-27 08:04:37.316 INFO 14328 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.70] 2022-12-27 08:04:37.502 INFO 14328 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-12-27 08:04:37.502 INFO 14328 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1690 ms 2022-12-27 08:04:39.469 INFO 14328 --- [ main] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 2022-12-27 08:04:39.817 INFO 14328 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2022-12-27 08:04:41.294 INFO 14328 --- [ main] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 2022-12-27 08:04:41.310 INFO 14328 --- [ main] vault.secrets.demo.DemoApplication : Started DemoApplication in 7.631 seconds (JVM running for 8.126) Secret written successfully. Secret read successfully
We can also verify the secret from the Vault UI:
Source Code:
https://github.com/it-code-lab/vault_secrets_demo
Leave a Comment