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.