Skip to content

Conversation

@LeMakhno
Copy link

No description provided.

* Specify additional property transformer classes
* {@link org.springframework.vault.core.util.PropertyTransformer}.
*/
Class<? extends PropertyTransformer>[] propertyTransformers() default {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introducing another flavor of property transformation creates ambiguity and takes away the simplicity of use. We have property-prefixing in place and we don't want to give up on simplicity.

The huge benefit of the current design approach is that all property transformations are visible from just looking at the annotation. Any other transformers require navigation and indirection.

Instead, I suggest exploring a design towards annotation-based property mapping. Admittedly, @VaultProperties(mapping = {@PropertyMapping(from="password", to="spring.datasource.password")} reads rather clunky, but that is still a direction worth exploring. Maybe you want to explore textblocks or other syntactical variants so that we come to a design that is simple and allows for addressing your use-case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mp911de i liked the approach with @PropertyMapping as annotation parameter, also i came up with idea of specitying an array of strings, where each 2 items is pair of from-to property names. But i like the variant with @PropertyMapping more

@VaultProperties(mapping = { "url", "spring.datasource.url", "user", "spring.datasource.username", "pwd", "spring.datasource.password" })

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mp911de implemented approach with @PropertyMapping

@mp911de
Copy link
Member

mp911de commented Dec 8, 2025

Because there are no tests showing the usage really, this pull request is really difficult to judge in terms of usability. Based on your contribution, here are usage examples of which the first one is based on the current changes while the subsequent ones are variants of various ideas:

@PropertyMapping Variant:

@VaultPropertySource(value = "secret/myapp/config", propertyMappings = {
		@PropertyMapping(from = "db.username", to = "spring.datasource.username"),
		@PropertyMapping(from = "db.password", to = "spring.datasource.password")
})

String-based property mappings:

@VaultPropertySource(value = "secret/myapp/config", propertyMappings = {
		"db.username=spring.datasource.username",
		"db.password=spring.datasource.password"})

@VaultPropertySource(value = "secret/myapp/config"
		    propertyMappings = "username=spring.datasource.username,password=spring.datasource.password"
)

External property file property mappings:

@VaultPropertySource(
    value = "secret/myapp/config",
    mappings = "classpath:vault-mappings.properties"
)

JSON-like property mappings:

@VaultPropertySource(
    value = "secret/myapp/config",
		mappings = """
				{ 
					'spring.datasource.username': '${db.username}',
					'spring.datasource.password': '${db.password}'
				}
				"""
)

@mp911de
Copy link
Member

mp911de commented Dec 8, 2025

Circling back to Spring Cloud Vault (as there is quite elaborate support for property mapping):

RequestedSecret rotating = RequestedSecret.rotating("secret/rotating");
PropertyNameTransformer transformer = new PropertyNameTransformer();
transformer.addKeyTransformation("db.username", "spring.datasource.username");
// …

configurer.add(RequestedSecret.rotating("database/mysql/creds/readonly"), transformer);

What's the reason for you using @VaultPropertySource over VaultConfigurer via Spring Cloud Vault?

@LeMakhno
Copy link
Author

LeMakhno commented Dec 8, 2025

I'd like to keep it declarative, as it supposed to be in Spring, instead of describing secrets in code. My pull request enhances annotation based approach with feature of custom prop name mapping.

@LeMakhno
Copy link
Author

LeMakhno commented Dec 8, 2025

Approach with @PropertyMapping is the most elegant in my opinion.

@LeMakhno
Copy link
Author

LeMakhno commented Dec 8, 2025

VaultConfigurer configuration does not seem to work, spring 3.5.8, springCloudVersion 2025.0.0. Tried declaring @Component, @Configuration of this type, spring does not call the method addSecretBackends i override to configure vault.

@mp911de
Copy link
Member

mp911de commented Dec 8, 2025

Configuration is initialized before the context is started as configuration is required to control bean registrations. Here's the documentation showing how to configure Spring Vault through the config data API: https://docs.spring.io/spring-cloud-vault/reference/secret-backends.html#vault.config.backends.configurer

@LeMakhno
Copy link
Author

LeMakhno commented Dec 8, 2025

I did as specified in documentation, there are issues:

  1. there is no method addBootstrapper on SpringApplication anymore (spring boot 3.5.8)
  2. the closest where i can put VaultConfigurer is through app.addBootstrapRegistryInitializer(VaultBootstrapper.fromConfigurer(new MyVaultConfigurer()));, in this case the overridden method addSecretBackends is not being called.

Could you suggest something?

@mp911de
Copy link
Member

mp911de commented Dec 9, 2025

Good catch about addBootstrapRegistryInitializer vs. addBootstrapper, we need to fix that in our documentation. Right now, the customizer is being called when importing Vault through the config data API by setting e.g. spring.config.import=vault: as it serves primarily as configuration hook for mounting secret backends available on the class path (e.g. databases, key/value). These can be disabled via SecretBackendConfigurer.registerDefaultKeyValueSecretBackends(false) for selective imports.

@LeMakhno
Copy link
Author

LeMakhno commented Dec 9, 2025

Sorry, can't make it work. Did as you suggested in last comment, my VaultConfigurer is not called anyways.
All attempts to configure vault using annotation @VaultPropertySource and properties file end with

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.vault.config.VaultAutoConfiguration]: No default constructor found

My use case is renewable secret

@mp911de
Copy link
Member

mp911de commented Dec 10, 2025

The constructor exception is part of why @VaultProperties does not play nicely with Spring Boot, see spring-cloud/spring-cloud-vault#642 for further explanation.

I see the appetite for annotation-based configuration of Vault property sources with Spring Boot applications, maybe that's an angle we should spend a bit more time on and consider how such an arrangement could be enabled with the config data API. However, configuration class parsing happens after Config Data is loaded so this cycle currently doesn't allow for a simple solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants