4. ConfigData API
Spring Boot provides since version 2.4 a ConfigData API that allows the declaration of configuration sources and importing these as property sources.
Spring Cloud Vault uses as of version 3.0 the ConfigData API to mount Vault’s secret backends as property sources. In previous versions, the Bootstrap context was used. The ConfigData API is much more flexible as it allows specifying which configuration systems to import and in which order.
You can enable the deprecated bootstrap context either by setting the configuration property spring.cloud.bootstrap.enabled=true or by including the dependency org.springframework.cloud:spring-cloud-starter-bootstrap .
|
4.1. ConfigData Locations
You can mount Vault configuration through one or more PropertySource
that are materialized from Vault.
Spring Cloud Vault supports two config locations:
-
vault://
(default location) -
vault:///<context-path>
(contextual location)
Using the default location mounts property sources for all enabled Secret Backends.
Without further configuration, Spring Cloud Vault mounts the key-value backend at /secret/${spring.application.name}
.
Each activated profile adds another context path following the form /secret/${spring.application.name}/${profile}
.
Adding further modules to the classpath, such as spring-cloud-config-databases
, provides additional secret backend configuration options which get mounted as property sources if enabled.
If you want to control which context paths are mounted from Vault as PropertySource
, you can either use a contextual location (vault:///my/context/path
) or configure a VaultConfigurer
.
Contextual locations are specified and mounted individually.
Spring Cloud Vault mounts each location as a unique PropertySource
.
You can mix the default locations with contextual locations (or other config systems) to control the order of property sources.
This approach is useful in particular if you want to disable the default key-value path computation and mount each key-value backend yourself instead.
spring.config.import: vault://first/context/path, vault://other/path, vault://
Property names within a Spring Environment
must be unique to avoid shadowing.
If you use the same secret names in different context paths and you want to expose these as individual properties you can distinguish them by adding a prefix
query parameter to the location.
spring.config.import: vault://my/path?prefix=foo., vault://my/other/path?prefix=bar.
secret: ${foo.secret}
other.secret: ${bar.secret}
Prefixes are added as-is to all property names returned by Vault. If you want key names to be separated with a dot between the prefix and key name, make sure to add a trailing dot to the prefix. |
4.2. Conditionally enable/disable Vault Configuration
In some cases, it can be required to launch an application without Vault. You can express whether a Vault config location should be optional or mandatory (default) through the location string:
-
optional:vault://
(default location) -
optional:vault:///<context-path>
(contextual location)
Optional locations are skipped during application startup if Vault support was disabled through spring.cloud.vault.enabled=false
.
Vault context paths that cannot be found (HTTP Status 404) are skipped regardless of whether the config location is marked optional. Vault Client Fail Fast allows failing on start if a Vault context path cannot be found because of HTTP Status 404. |
4.3. Infrastructure Customization
Spring Cloud Vault requires infrastructure classes to interact with Vault. When not using the ConfigData API (meaning that you haven’t specified spring.config.import=vault://
or a contextual Vault path), Spring Cloud Vault defines its beans through VaultAutoConfiguration
and VaultReactiveAutoConfiguration
.
Spring Boot bootstraps the application before a Spring Context is available. Therefore VaultConfigDataLoader
registers beans itself to propagate these later on into the application context.
You can customize the infrastructure used by Spring Cloud Vault by registering custom instances using the Bootstrapper
API:
InstanceSupplier<RestTemplateBuilder> builderSupplier = ctx -> RestTemplateBuilder
.builder()
.requestFactory(ctx.get(ClientFactoryWrapper.class).getClientHttpRequestFactory())
.defaultHeader("X-Vault-Namespace", "my-namespace");
SpringApplication application = new SpringApplication(MyApplication.class);
application.addBootstrapper(registry -> registry.register(RestTemplateBuilder.class, builderSupplier));
See also Customize which secret backends to expose as PropertySource and the source of VaultConfigDataLoader
for customization hooks.