Spring boot & Spring vault
To start Spring Boot with Spring Vault, we will use HashiCorp Vault.
HASHICORP vault
HashiCorp vault secures, stores and tightly controls access to tokens, passwords, certificates, API keys and other secrets.
Spring cloud vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, MongoDB, Consul, AWS, etc.
Installation:
If you are using a Mac with homebrew, this is as simple as:
$ brew install vault
Alternatively, download Vault for your operating system from https://www.vaultproject.io/downloads.html:
$ https://releases.hashicorp.com/vault/0.8.3/vault_0.8.3_darwin_amd64.zip$ unzip vault_0.8.3_darwin_amd64.zip
For other systems with package management, such as Redhat, Ubuntu, Debian, CentOS, and Windows, see instructions at https://www.vaultproject.io/docs/install/index.html.
Start Vault:
After you install Vault, launch it in a console window. This command also starts up a server process.
$ vault server –dev –dev-root-token-id=”00000000-0000-0000-0000-000000000000″
You should see the following as one of the last output lines:
==> Vault server configuration: Api Address: http://127.0.0.1:8200 Cgo: disabled Cluster Address: https://127.0.0.1:8201 Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "999999h0m0s", max_request_size: "33554432", tls: "disabled") Log Level: info Mlock: supported: false, enabled: false Storage: inmem Version: Vault v0.10.4 Version Sha: e21712a687889de1125e0a12a980420b1a4f72d3 WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory and starts unsealed with a single unseal key. The root token is already authenticated to the CLI, so you can immediately begin using Vault. You may need to set the following environment variable: $ export VAULT_ADDR='http://127.0.0.1:8200' The unseal key and root token are displayed below in case you want to seal/unseal the Vault or re-authenticate. Unseal Key: 8rxkH8z9XgmxS4cIdtAqNHt1vgIYB99A0bITSDgGymM= Root Token: 00000000-0000-0000-0000-000000000000 [INFO ] core: restoring leases [INFO ] rollback: starting rollback manager [INFO ] identity: entities restored [INFO ] identity: groups restored [INFO ] core: post-unseal setup complete
Insert/Update Vault Key/Values and Versioning
$ vault kv [options] [args]
This command has subcommands for interacting with Vault’s key-value
store. The new versioned K/V mounts (and the vault kv subcommand) support writing
multiple versions. Here are some simple examples, and more detailed examples are
available in the subcommands or the documentation.
Insert:
$ vault kv put secret/my-secret my-value=demoKey Value
— —–
created_time 2018-08-20T10:45:43.346121373Z
deletion_time n/a
destroyed false
version 1
Read:
$ vault kv get secret/my-secret====== Metadata ======
Key Value
— —–
created_time 2018-08-20T10:46:16.288468021Z
deletion_time n/a
destroyed false
version 1
====== Data ======
Key Value
— —–
my-value demo
Update (Version Update)
$ vault kv put -cas=1 secret/my-secret my-value=itsasecretKey Value
— —–
created_time 2018-08-20T10:46:16.288468021Z
deletion_time n/a
destroyed false
version 2
NOTE: If -cas=0 the write will only be performed if the key doesn’t exist. If the index is non-zero the write will only be allowed if the key’s current version matches the version specified in the cas parameter.
There is no way to update the value of current version. If value will get updated, so will the version.
Destroy:
There are two ways to delete versioned data with vault kv: vault kv delete and vault kv destroy.
vault kv delete performs a soft deletion that marks a version as deleted and creates a deletion_time timestamp. Data removed with vault kv delete can be un-deleted by using vault kv undelete
For example, the latest version of a secret can be soft-deleted by simply running vault kv delete. A specific version can be deleted using the -versions flag.
$ vault kv delete secret/my-secret
Success! Data deleted (if it existed) at: secret/my-secret
A version soft-deleted using vault kv delete can be restored with vault kv undelete
$ vault kv undelete -versions=2 secret/my-secretSuccess! Data written to: secret/undelete/my-secret
$ vault kv get secret/my-secret====== Metadata ======
Key Value
— —–
created_time 2018-03-30T22:18:37.124228658Z
deletion_time n/a
destroyed false
version 2
====== Data ======
Key Value
— —–
my-value itsasecret
However, data removed by vault kv destroy cannot be restored.
$ vault kv destroy -versions=2 secret/my-secretSuccess! Data written to: secret/destroy/my-secret
Spring Boot Dependency:
$ vault kv put secret/vaultdemo demo.username=demouser demo.password=demovault demo.url=notyetset $ vault kv put secret/vaultdemo/mysql demo.username=ankit demo.password=ankit demo.url="jdbc:mysql://localhost:3306/springboot1"
Typical POM dependencies would be:
org.springframework.cloud
spring-cloud-starter-vault-config
then configure your Vault endpoint and authentication
bootstrap.properties file:
spring.application.name= my-application
spring.cloud.vault.token=00000000-0000-0000-0000-000000000000
spring.cloud.vault.scheme=https
spring.cloud.vault.authentication=TOKEN (or AWS, anything).
boostrap.yaml file:
spring.application.name: my-application
spring.cloud.vault:
host: $HOST_NAMR (localhost or ipaddress)
port: 8200
scheme: https
token: 00000000-0000-0000-0000-000000000000
authentication: TOKEN (or AWS, anything).
DEMO:
Set 2 values in vault, one is default and other is of mysql
$ vault kv put secret/vaultdemo demo.username=demouser demo.password=demovault demo.url=notyetsetKey Value
— —–
created_time 2018-08-20T12:01:56.993249698Z
deletion_time n/a
destroyed false
version 6
$ vault kv put secret/vaultdemo/mysql demo.username=ankit demo.password=ankit demo.url="jdbc:mysql://localhost:3306/springboot1"Key Value
— —–
created_time 2018-08-20T12:02:12.010325622Z
deletion_time n/a
destroyed false
version 4
$ vault kv get secret/vaultdemo/mysql
====== Metadata ======
Key Value
— —–
created_time 2018-08-20T12:02:12.010325622Z
deletion_time n/a
destroyed false
version 4
======== Data ========
Key Value
— —–
demo.password ankit
demo.url jdbc:mysql://localhost:3306/springboot1
demo.username ankit
$ vault kv get secret/vaultdemo
====== Metadata ======
Key Value
— —–
created_time 2018-08-20T12:01:56.993249698Z
deletion_time n/a
destroyed false
version 6
======== Data ========
Key Value
— —–
demo.password demovault
demo.url notyetset
demo.username demouser
Gradle Dependencies:
Add this dependency in the dependencies list:
compile('org.springframework.cloud:spring-cloud-starter-vault-config')
ext {
springCloudVersion = ‘Finchley.SR1’
}dependencies {
compile(‘org.springframework.boot:spring-boot-starter-web’)
compile(‘org.springframework.cloud:spring-cloud-starter-vault-config’)compile(“org.jetbrains.kotlin:kotlin-stdlib-jdk8”)
compile(“org.jetbrains.kotlin:kotlin-reflect”)
providedRuntime(‘org.springframework.boot:spring-boot-starter-tomcat’)
testCompile(‘org.springframework.boot:spring-boot-starter-test’)compile(“org.springframework.boot:spring-boot-configuration-processor”)
}
Vault Configuration Model
Now, we will create the configuration model, as we had ran below command:
$ vault kv put secret/vaultdemo demo.username=demouser demo.password=demovault demo.url=notyetset
Here,
vaultdemo : It is name of application in bootstrap.yml
demo : it is the configuration properties
username, password & url: these are properties of configuration
Now in this command, we have set another reference:
$ vault kv put secret/vaultdemo/mysql demo.username=ankit demo.password=ankit demo.url="jdbc:mysql://localhost:3306/springboot1"
mysql: this is the active profile of application.
This way, we can set different passwords for different variables in vault and can use them as configuration property.
Below is the bootstrap.yml file and the configuration file
server:
port: 3040
spring:
application:
name: vaultdemo
cloud:
vault:
scheme: http
token: “12345”
host: 127.0.0.1
port: 8200
kv: # v0.10 of vault, comes with kv enabled. so this must needs to be set true
enabled: true
profiles:
active: mysql
VaultConfiguration.kt
// $ vault kv put secret/vaultdemo demo.username=demouser demo.password=demovault demo.url=notyetset
// ConfigurationProperties = demo
// as demo.username, demo.password, demo.url
//
@ConfigurationProperties(“demo”)
class VaultConfiguration(
var username:String=””,
var password:String=””,
var url:String=””
)
The source code is available here for demo.