=== Vault Config Store

The Vault Store extends the Vert.x Configuration Retriever and provides support for Vault (https://www.vaultproject.io/).

So, configuration (secrets) is retrieved from Vault.

==== Using the Vault Config Store

To use the Vault Config Store, add the following dependency to the
_dependencies_ section of your build descriptor:

* Maven (in your `pom.xml`):

[source,xml,subs="+attributes"]
----
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-vault</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>3.5.3</version>
</dependency>
----

* Gradle (in your `build.gradle` file):

[source,groovy,subs="+attributes"]
----
compile 'io.vertx:vertx-config:3.5.3'
compile 'io.vertx:vertx-config-vault:3.5.3'
----

==== Configuring the store

Once added to your classpath or dependencies, you need to configure the
`link:../../apidocs/io/vertx/config/ConfigRetriever.html[ConfigRetriever]` to use this store:

[source, kotlin]
----
var store = ConfigStoreOptions(
  type = "vault",
  config = config)

var retriever = ConfigRetriever.create(vertx, ConfigRetrieverOptions(
  stores = listOf(store)))

----

To use the Vault config store, set the `type` to `vault`. The configuration is provided as Json. It configures the
access to Vault, authentication and the path of the secret to retrieve:

[source, kotlin]
----
Code not translatable}
----

The `vault_config` object can contain the HTTP client / Web client configuration such as trust stores, timeout,
certificates, port and host. The `path` and `host` entries are mandatory. The `path` indicates the secret to
retrieve. The `host` is the hostname of the Vault server. By default the port 8200 is used. SSL is disabled by
default, but you should enable it for production settings.

Then, you need to use one of the following method to configure the token to use or the authentication mechanism.

==== Using an existing token

If you know the token to use, set the `token` entry in the configuration:

[source, kotlin]
----
var vault_config = json {
  obj()
}

// ...

// Path to the secret to read.
vault_config.put("path", "secret/my-secret")

// The token
vault_config.put("token", token)

var store = ConfigStoreOptions(
  type = "vault",
  config = vault_config)

var retriever = ConfigRetriever.create(vertx, ConfigRetrieverOptions(
  stores = listOf(store)))

----

You can use the root token, but it's not recommended. When the token is revoked, the access to the secret is
blocked. If the token is renewable, the token is renewed when it expires.

==== Generating a token

If you have a token allowing you to generate new token, you can request the token generation:

[source, kotlin]
----
var vault_config = json {
  obj()
}

// ...

// Path to the secret to read.
vault_config.put("path", "secret/my-secret")

// Configure the token generation

// Configure the token request (https://www.vaultproject.io/docs/auth/token.html)
var tokenRequest = json {
  obj(
    "ttl" to "1h",
    "noDefault" to true,
    "token" to token
  )
}

vault_config.put("auth-backend", "token").put("renew-window", 5000L).put("token-request", tokenRequest)

var store = ConfigStoreOptions(
  type = "vault",
  config = vault_config)

var retriever = ConfigRetriever.create(vertx, ConfigRetrieverOptions(
  stores = listOf(store)))

----

When using this approach, no token must be provided in the root configuration, the the token use to request the
generation is passed in the nested JSON structure. If the generated token is renewable, it will be
renewed automatically upon expiration. The `renew-window` is the time window to add to the token validity to renew
it. If the generated token is revoked, the access to the secret is blocked.

==== Using certificates

You can use TLS certificates as authentication mechanism. So, you don't need to know a token, the token is
generated automatically.

[source, kotlin]
----
Code not translatable
----

Check out the HTTP client and Web client configuration to pass the certificates. If the generated token is
renewable, it will be renewed. If not, the store attempts to authenticate again.

==== Using AppRole

`AppRole` is used when your application is known by Vault and you have the `appRoleId` and `secretId`. You don't
need a token, the token being generated automatically:

[source, kotlin]
----
var vault_config = json {
  obj()
}

// ...

vault_config.put("auth-backend", "approle").put("approle", json {
  obj(
    "role-id" to appRoleId,
    "secret-id" to secretId
  )
})

// Path to the secret to read.
vault_config.put("path", "secret/my-secret")

var store = ConfigStoreOptions(
  type = "vault",
  config = vault_config)

var retriever = ConfigRetriever.create(vertx, ConfigRetrieverOptions(
  stores = listOf(store)))

----

If the generated token is renewable, it will be renewed. If not, the store attempts to authenticate again.

==== Using username and password

The `userpass` auth backend is used when the user / app is authenticated using a username/password. You don't need a
token as the token is generated during the authentication process:

[source, kotlin]
----
var vault_config = json {
  obj()
}

// ...

vault_config.put("auth-backend", "userpass").put("user-credentials", json {
  obj(
    "username" to username,
    "password" to password
  )
})

// Path to the secret to read.
vault_config.put("path", "secret/my-secret")

var store = ConfigStoreOptions(
  type = "vault",
  config = vault_config)

var retriever = ConfigRetriever.create(vertx, ConfigRetrieverOptions(
  stores = listOf(store)))

----

If the generated token is renewable, it will be renewed. If not, the store attempts to authenticate again.