This document describes how the integration of Hashicorp Vault with Micronaut works.

Workflow

At initialisation, the Micronaut framework will resolve, when enabled, external properties from sources like Hashicorp Vault, where it’ll look for four secrets, in the following order :

1. application

2. [app-name]

3. application/[micronaut-env]

4. [app-name]/[micronaut-env]

And merge their key/value pairs, the next one overwriting the previous, and make them available to the application the same way regular properties are.

In order to take new Vault values into account, such a Micronaut application has to be restarted.

The successful process completion is confirmed as follows :

11:39:58.573 [main] INFO  i.m.context.DefaultBeanContext - Reading bootstrap environment configuration
11:39:59.151 [main] INFO  i.m.d.c.c.DistributedPropertySourceLocator - Resolved 4 configuration sources from client: compositeConfigurationClient(vault-config-client-v2)
11:39:59.216 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 796ms. Server Running: http://localhost:8080

Precedence

Precedence

Source

Secret Path

Scope

environments refer here to Micronaut ones

1

Vault

[service-name]/[environment]

A specific MS in a specific environment

2

Vault

[service-name]

A specific MS in all environments

3

Vault

application/[environment]

All MS in a specific environment

4

Vault

application

All MS in all environments

5

application.yml

root

Application instance

6

ENV vars

N/A

OS

Since we do not use Micronaut Environments, the framework will fetch the [service-name] and application secrets only.

Vault Kubernetes Authentication

To have secrets management meeting industry standards, we chose to use the Kubernetes Service account token to authenticate to Vault.

However, Micronaut consumes a Vault token, and we needed to add an authentication layer to the applications.

This has been done using an init container in the kotlin helm chart, which queries the Vault API, sets a temporary Kubernetes opaque secret containing the VAULT_ADDR and VAULT_TOKEN environment variables which are then consumed by the Micronaut application.

Helm chart configuration

In oder to enable the Vault integration, the following needs to be added to the application’s Helm chart.

kotlin:
  micronaut:
    vault:
      endpoint: https://vault.hcv.dev.safibank.online:8200
      kubernetesAuthentication: true

Enable Micronaut to Support Hashicorp Vault

Refer to How to Integrate a Micronaut application with Hashicorp Vault for details. After enabling Hashicorp Vault, Micronaut will get configuration values from Vault automatically and replace placeholders in application.yml automatically.

Structure/Layout of Hashicorp Vault Configuration Values

We use the default KV secret engine - version 2, and the engine path secrets/app-properties.

All environment variables are listed in Environment variables.

Action Items

  • discuss with Devops team to align on this
  • update all microservices of the Common squad to verify it
  • create Jira tickets to ask other squads to follow it