Spring Vault: Why @VaultPropertySource not getting highest precedence?
Image by Rya - hkhazo.biz.id

Spring Vault: Why @VaultPropertySource not getting highest precedence?

Posted on

In Spring-based applications, @VaultPropertySource is a powerful annotation that allows developers to externalize configuration properties from HashiCorp’s Vault. However, there have been instances where @VaultPropertySource does not get the highest precedence, leading to unexpected behavior in the application.

Understanding Property Source Ordering in Spring

In Spring, property sources are ordered based on their precedence. The order of precedence determines which property source takes priority over others. By default, Spring uses the following order:

  1. CommandLine property sources
  2. System property sources
  3. Environment property sources
  4. application.properties files
  5. application.yml files
  6. Profile-specific application.properties files
  7. Profile-specific application.yml files

The Role of @VaultPropertySource in Property Source Ordering

@VaultPropertySource is a custom property source that allows Spring to retrieve properties from Vault. However, by default, @VaultPropertySource has a lower precedence than the default property sources listed above. This means that if there are duplicate properties in both the Vault and the default property sources, the default property sources will take precedence.

Solution: Overriding the Precedence of @VaultPropertySource

To give @VaultPropertySource the highest precedence, you need to explicitly configure the property source ordering in your Spring application. You can do this by creating a custom PropertySourceLocator bean and overriding the default property source ordering.

Here’s an example:

@Bean
public static PropertySourceLocator propertySourceLocator() {
    return new VaultPropertySourceLocator();
}

public class VaultPropertySourceLocator implements PropertySourceLocator {
    @Override
    public List<PropertySource> locate(Environment environment) {
        List<PropertySource> propertySources = new ArrayList<>();
        propertySources.add(new VaultPropertySource("vault", "http://localhost:8200"));
        // Add other property sources with lower precedence
        propertySources.add(new PropertiesPropertySource("applicationProperties", new Properties()));
        return propertySources;
    }
}

By overriding the property source ordering, you can ensure that @VaultPropertySource gets the highest precedence, and your application retrieves properties from Vault as expected.

Remember to adjust the precedence of other property sources according to your application’s requirements.

Frequently Asked Question

Get answers to your burning questions about Spring Vault and its peculiar behavior with @VaultPropertySource

Why doesn’t @VaultPropertySource have the highest precedence in Spring Vault?

By design, @VaultPropertySource has a lower precedence than other property sources, such as @Value, @ConfigurationProperties, or application.properties. This is because Vault is meant to be a secure external configuration store, and you might not always want it to override your local application configuration.

How can I increase the precedence of @VaultPropertySource in Spring Vault?

You can increase the precedence of @VaultPropertySource by setting the order attribute on the @VaultPropertySource annotation. For example, @VaultPropertySource(order = Ordered.HIGHEST_PRECEDENCE) will give it the highest precedence.

What happens if I have multiple @VaultPropertySource annotations with different orders?

If you have multiple @VaultPropertySource annotations with different orders, Spring Vault will merge the properties from all sources, with the ones having higher orders taking precedence. For example, if you have two @VaultPropertySource annotations with orders 10 and 20, the one with order 20 will take precedence.

Can I use @VaultPropertySource with other property sources, such as application.properties?

Yes, you can use @VaultPropertySource with other property sources, such as application.properties. In fact, this is a common use case, where you use Vault for secure configuration and local properties for non-sensitive configuration.

What if I want to exclude certain properties from being overridden by @VaultPropertySource?

You can use the ignore attribute on the @VaultPropertySource annotation to specify which properties should not be overridden. For example, @VaultPropertySource(ignore = “password”) will exclude the password property from being overridden.