2

I am running a Docker Vault container in dev mode, and I can't read a secret located at /secret/mobsters/ called password.

Here are Spring logs.

Running vault kv get secret/mobsters returns the password key value pair. I can also access the vault server locally.

Here is how I am referencing the secret:

@Value("${password}")
String password;

@PostConstruct
private void postConstruct() {
    System.out.println("My password is: " + password);
}

The Spring Cloud Vault configuration is setup using a bootstrap.yml file:

spring.application.name: mobsters
spring.cloud.vault:
host: localhost
port: 8200
scheme: http
authentication: TOKEN
token: ...

I am getting an exception with the message (full exception here):

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'password' in value "${password}"`

From Vault UI:

enter image description here

M. Volf
  • 1,259
  • 11
  • 29
Adrian Elder
  • 1,993
  • 3
  • 19
  • 38
  • Looks like as if you were using Vault 0.10.0. If so, see https://github.com/spring-cloud/spring-cloud-vault/issues/209. – mp911de Apr 23 '18 at 09:42
  • I downgraded the docker container to v0.9.5 and it worked! You should post this as an answer. – Adrian Elder Apr 23 '18 at 22:18

2 Answers2

2

Using Spring Vault/Spring Cloud Vault with HashiCorp Vault 0.10.0 does not work as the key/value backend is mounted with versioning enabled by default. This has some significance as the versioned API has changed entirely and breaks existing client implementations. Context paths and response structure are different.

You have two options:

  1. Use an older Vault version (such as 0.9.5)
  2. Try to cope with API changes until Spring Cloud Vault finds an approach to use the new API. You need to:
    • Set spring.cloud.vault.generic.backend=secret/data in your bootstrap configuration.
    • Prefix property names with data. so @Value("${hello.world}") becomes @Value("${data.hello.world}").
mp911de
  • 17,546
  • 2
  • 55
  • 95
  • In my case, I set spring.cloud.config.server.vault.backend=secret/data and prefaced my property names with "data." -- works! Looks like I have Vault v1.0.1 – unigeek Jan 07 '19 at 03:08
0

It looks like there is a way to fix this.

In your bootstrap.yml, make sure that generic.enabled is false and kv.enabled is true.

spring:
  ...
  cloud.vault:
      ...
      kv.enabled: true
      generic.enabled: false

According to this answer on GitHub:

The main difference between those two is that kv injects the data segment in the context path and unwraps nested data responses.

If you're running a [springboot] version before 2.0, then you need to implement an org.springframework.cloud.vault.config.VaultConfigurer bean that is exposed to the bootstrap context. SecretBackendConfigurer accepts a path and a PropertyTransformer that transforms properties before exposing these as PropertySource.

patrickjm
  • 147
  • 1
  • 11