Property Sources
Vault can be used in many different ways. One specific use-case is using Vault to store encrypted properties. Spring Vault supports Vault as property source to obtain configuration properties using Spring’s PropertySource abstraction.
You can reference properties stored inside Vault in other property sources or use value injection with @Value(…) . Special attention is required when bootstrapping beans that require data stored inside of Vault. A VaultPropertySource must be initialized at that time to retrieve properties from Vault.
|
Spring Boot/Spring Cloud users can benefit from Spring Cloud Vault's configuration integration that initializes various property sources during application startup. |
Registering VaultPropertySource
Spring Vault provides a VaultPropertySource
to be used with Vault to obtain
properties. It uses the nested data
element to expose properties stored and
encrypted in Vault.
ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new VaultPropertySource(vaultTemplate, "secret/my-application"));
In the code above, VaultPropertySource
has been added with highest precedence
in the search. If it contains a ´foo` property, it will be detected and returned
ahead of any foo
property in any other PropertySource
.
MutablePropertySources
exposes a number of methods that allow for precise
manipulation of the set of property sources.
@VaultPropertySource
The @VaultPropertySource
annotation provides a convenient and declarative
mechanism for adding a PropertySource
to Spring’s Environment
to be used in conjunction with @Configuration
classes.
@VaultPropertySource
takes a Vault path such as secret/my-application
and exposes the data stored at the node in a PropertySource
.
@VaultPropertySource
supports lease renewal for secrets associated with a lease
(i. e. credentials from the mysql
backend) and credential rotation upon terminal
lease expiration. Lease renewal is disabled by default.
{
// …
"data": {
"database": {
"password": ...
},
"user.name": ...,
}
// …
}
@VaultPropertySource
@Configuration
@VaultPropertySource("secret/my-application")
public class AppConfig {
@Autowired Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setUser(env.getProperty("user.name"));
testBean.setPassword(env.getProperty("database.password"));
return testBean;
}
}
@VaultPropertySource
with credential rotation and prefix@Configuration
@VaultPropertySource(value = "aws/creds/s3-access",
propertyNamePrefix = "aws.",
renewal = Renewal.ROTATE)
public class AppConfig {
// provides aws.access_key and aws.secret_key properties
}
Secrets obtained from generic secret backends are associated with a TTL (refresh_interval ) but not a lease Id. Spring Vault’s PropertySource rotates generic secrets when reaching its TTL.
|
You can use @VaultPropertySource to obtain the newest secret version from the versioned Key-Value backend. Make sure to not include the data/ segment in the path.
|
Any ${…}
placeholders present in a @VaultPropertySource
path are resolved against the set of property sources already registered against the environment, as the following example shows:
@VaultPropertySource
path using placeholders@Configuration
@VaultPropertySource(value = "aws/creds/${my.placeholder:fallback/value}",
propertyNamePrefix = "aws.",
renewal = Renewal.ROTATE)
public class AppConfig {
}
Assuming that my.placeholder
is present in one of the property sources already registered (for example, system properties or environment variables), the placeholder is resolved to the corresponding value.
If not, then fallback/value
is used as a default.
If no default is specified and a property cannot be resolved, an IllegalArgumentException
is thrown.
In certain situations, it may not be possible or practical to tightly control
property source ordering when using @VaultPropertySource
annotations.
For example, if the @Configuration
classes above were registered via
component-scanning, the ordering is difficult to predict.
In such cases - and if overriding is important - it is recommended that the
user fall back to using the programmatic PropertySource API.
See ConfigurableEnvironment
and
MutablePropertySources
for details.