HashiCorp Vault
Overview
HashiCorp Vault is a commonly used Vault in many microservices. The APIs are REST-based and Helidon implements them using WebClient.
Maven Coordinates
To enable HashiCorp Vault, add the following dependency to your project’s
pom.xml (see Managing Dependencies).
<dependency>
<groupId>io.helidon.integrations.vault</groupId>
<artifactId>helidon-integrations-vault-cdi</artifactId>
</dependency>
The following is a list of maven coordinates of all Vault modules available:
<dependencies>
<dependency>
<groupId>io.helidon.integrations.vault.auths</groupId>
<artifactId>helidon-integrations-vault-auths-token</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.auths</groupId>
<artifactId>helidon-integrations-vault-auths-approle</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.auths</groupId>
<artifactId>helidon-integrations-vault-auths-k8s</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.secrets</groupId>
<artifactId>helidon-integrations-vault-secrets-kv1</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.secrets</groupId>
<artifactId>helidon-integrations-vault-secrets-kv2</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.secrets</groupId>
<artifactId>helidon-integrations-vault-secrets-cubbyhole</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.secrets</groupId>
<artifactId>helidon-integrations-vault-secrets-transit</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.secrets</groupId>
<artifactId>helidon-integrations-vault-secrets-database</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.integrations.vault.sys</groupId>
<artifactId>helidon-integrations-vault-sys</artifactId>
</dependency>
</dependencies>
Usage
Vault integration supports the following:
- Secret Engines: Key/Value version 2, Key/Value version 1, Cubbyhole, PKI, Transit, Database
- Authentication Methods: Token, Kubernetes (k8s), AppRole
- Other Sys Operations and Configurations
Each of these features is implemented as a separate module, with the Vault class binding them together. In Helidon MP, with injection, this binding is done automatically, and you can simply inject your favorite secret engine.
The following classes can be injected into any CDI bean (if appropriate module is on the classpath):
- Kv2Secrets - Key/Value Version 2 Secrets (versioned secrets, default)
- Kv1Secrets - Key/Value Version 1 Secrets (un-versioned secrets, legacy)
- CubbyholeSecrets - Cubbyhole secrets (token bound secrets)
- DbSecrets - Database secrets (for generating temporary DB credentials)
- PkiSecrets - PKI secrets (for generating keys and X.509 certificates)
- TransitSecrets - Transit operations (encryption, signatures, HMAC)
- AppRoleAuth - AppRole authentication method (management operations)
- K8sAuth - Kubernetes authentication method (management operations)
- TokenAuth - Token authentication method (management operations)
- Sys - System operations (management of Vault - enabling/disabling secret engines and authentication methods)
In addition to these features, Vault itself can be authenticated as follows:
- Token authentication - token is configured when connecting to Vaultapplication.yaml
vault.address=http://localhost:8200 vault.token=my-token - AppRole authentication - AppRole ID and secret ID are configured, integration
exchanges these for a temporary token that is used to connect to Vaultapplication.yaml
vault.auth.app-role.role-id=app-role-id vault.auth.app-role.secret-id=app-role-secret-id - K8s authentication - the k8s JWT token is discovered on current node and used
to obtain a temporary token that is used to connect to Vault
Extensibility
New secret engines and authentication methods can be implemented quite easily, as the integration is based on service providers (using ServiceLoader). This gives us (or you, as the users) the option to add new secret engines and/or authentication methods without adding a plethora of methods to the Vault class.
See the following SPIs:
io.helidon.integrations.vault.spi.AuthMethodProvider
io.helidon.integrations.vault.spi.SecretsEngineProvider
io.helidon.integrations.vault.spi.SysProvider
io.helidon.integrations.vault.spi.VaultAuth
io.helidon.integrations.vault.spi.InjectionProvider
Examples
The following example shows usage of Vault to encrypt a secret using the default Vault configuration (in a JAX-RS resource):
@Path("/transit")
class TransitResource {
private final TransitSecrets secrets;
@Inject
TransitResource(TransitSecrets secrets) {
this.secrets = secrets;
}
@Path("/encrypt/{secret: .*}")
@GET
public String encrypt(@PathParam("secret") String secret) {
return secrets.encrypt(Encrypt.Request.builder()
.encryptionKeyName(ENCRYPTION_KEY)
.data(Base64Value.create(secret)))
.encrypted()
.cipherText();
}
}
Cubbyhole secrets
Cubbyhole example:
KV1 secrets
Key/Value version 1 secrets engine operations:
KV2 secrets
Key/Value version 2 secrets engine operations:
Transit secrets
Transit secrets engine operations:
Local Testing
Vault is available as a docker image, so to test locally, you can simply:
docker run -d \
-e VAULT_DEV_ROOT_TOKEN_ID=my-token \
--name=vault \
-p 8200:8200 \
vault
This will create a Vault docker image, run it in background and open it on
localhost:8200 with a custom root token my-token, using name vault. This is of
course only suitable for local testing, as the root token has too many rights,
but it can be easily used with the examples below.