quarkiverse / quarkus-vault

Quarkus HashiCorp Vault extension
Apache License 2.0
19 stars 24 forks source link

ConfigValidationException on Quarkus 3.7.1 #231

Open computerlove opened 7 months ago

computerlove commented 7 months ago

When upgrading to Quarkus 3.7.1 (and quarkus-vault 3.4.1) the application crash at startup with

Configuration validation failed:
    SRCFG00050: quarkus.vault.authentication.app.role.role.id in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    SRCFG00050: quarkus.vault.authentication.app.role.secret.id in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root

java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:111)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:62)
    at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:33)
Caused by: io.quarkus.runtime.configuration.ConfigurationException: Failed to read configuration properties
    at io.quarkus.deployment.steps.RuntimeConfigSetup.deploy(Unknown Source)
    ... 11 more
Caused by: io.smallrye.config.ConfigValidationException: Configuration validation failed:
    SRCFG00050: quarkus.vault.authentication.app.role.role.id in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    SRCFG00050: quarkus.vault.authentication.app.role.secret.id in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    at io.smallrye.config.ConfigMappingProvider.mapConfiguration(ConfigMappingProvider.java:73)
    at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:86)
    at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:724)
    at io.smallrye.config.ConfigSourceFactory$ConfigurableConfigSourceFactory.getConfigSources(ConfigSourceFactory.java:54)
    at io.smallrye.config.ConfigurableConfigSource.getConfigSources(ConfigurableConfigSource.java:50)
    at io.smallrye.config.SmallRyeConfig$ConfigSources.mapLateSources(SmallRyeConfig.java:832)
    at io.smallrye.config.SmallRyeConfig$ConfigSources.<init>(SmallRyeConfig.java:722)
    at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:83)
    at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:724)
    at io.quarkus.runtime.generated.Config.readConfig(Unknown Source)
    at io.quarkus.runtime.generated.Config.createRunTimeConfig(Unknown Source)
    ... 12 more
vsevel commented 7 months ago

how do you set the properties?

computerlove commented 7 months ago

Those two are set as environment variables.

vsevel commented 7 months ago

nothing was changed in vault. must have been in smallrye config. I saw something similar with export QUARKUS_VAULT_AUTHENTICATION_CLIENT_TOKEN=... not working anymore any idea @radcortez ?

radcortez commented 7 months ago

Probably related with https://github.com/quarkusio/quarkus/issues/38479.

If this is a blocker for you, please use any of the alternatives described in https://github.com/quarkusio/quarkus/issues/38479#issuecomment-1917593210

Quarkus 3.7.2 just came out with a relaxed validation. Alternatively, you can update SmallRye Config manually for Quarkus 3.7.1:

<dependency>
  <groupId>io.smallrye.config</groupId>
  <artifactId>smallrye-config-common</artifactId>
  <version>3.5.4</version>
</dependency>
<dependency>
  <groupId>io.smallrye.config</groupId>
  <artifactId>smallrye-config-core</artifactId>
  <version>3.5.4</version>
</dependency>
vsevel commented 7 months ago

the issue seems to be related to QUARKUS_VAULT_AUTHENTICATION_APP_ROLE_ROLE_ID being interpreted as quarkus.vault.authentication.app.role.role.id, whereas the property is quarkus.vault.authentication.app-role.role-id.

we actually just checked that using QUARKUS_VAULT_AUTHENTICATION_CLIENT-TOKEN instead of QUARKUS_VAULT_AUTHENTICATION_CLIENT_TOKEN worked (at least on windows, which accepts - )

radcortez commented 6 months ago

Is this still an issue? @computerlove did you try with Quarkus 3.7.2? Thanks!

computerlove commented 6 months ago

Yeah, tried today. Same problem. But did not have time to test the config for disable the validation and investigate. Will try to take another look tomorrow.

bmontuelle commented 6 months ago

Hi, we ran into a similar issue using Quarkus 3.7.3 and quarkus-vault 3.4.1

Caused by: io.smallrye.config.ConfigValidationException: Configuration validation failed:
    SRCFG00050: quarkus.vault.kv.secret.engine.mount.path in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    SRCFG00050: quarkus.vault.authentication.kubernetes.auth.mount.path in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    SRCFG00050: quarkus.vault.tls.use.kubernetes.ca.cert in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    SRCFG00050: quarkus.vault.tls.ca.cert in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    SRCFG00050: quarkus.vault.secret.config.kv.path in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root
    SRCFG00050: quarkus.vault.tls.skip.verify in io.smallrye.config.ConfigSourceContext$ConfigSourceContextConfigSource does not map to any root

Configuration properties also injected via env variables. Went back to Quarkus 3.6.9 for the moment.

computerlove commented 6 months ago

Yeah, still there in 3.7.3. Running with quarkus.config.mapping.validate-unknown=false for now.

vsevel commented 6 months ago

have you tried using QUARKUS_VAULT_AUTHENTICATION_CLIENT-TOKEN ?

radcortez commented 6 months ago

Ok, thanks for checking. I'll have a look.

computerlove commented 6 months ago

Removing quarkus.config.mapping.validate-unknown=false and changing to ...ROLE-ID and ...SECRET-ID resulted in

unknown authType null

java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:111)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:62)
    at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:33)
Caused by: io.quarkus.runtime.configuration.ConfigurationException: Failed to read configuration properties
    at io.quarkus.deployment.steps.RuntimeConfigSetup.deploy(Unknown Source)
    ... 11 more
Caused by: java.lang.UnsupportedOperationException: unknown authType null
    at io.quarkus.vault.runtime.VaultAuthManager.login(VaultAuthManager.java:179)
    at io.quarkus.vault.runtime.VaultAuthManager.vaultLogin(VaultAuthManager.java:154)
    at io.quarkus.vault.runtime.VaultAuthManager.lambda$login$5(VaultAuthManager.java:120)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:68)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:60)
    at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.forward(UniCreateFromKnownItem.java:38)
    at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem.subscribe(UniCreateFromKnownItem.java:23)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:81)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:60)
    at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.forward(UniCreateFromKnownItem.java:38)
    at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem.subscribe(UniCreateFromKnownItem.java:23)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:81)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)
    at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.forward(UniCreateFromKnownItem.java:38)
    at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem.subscribe(UniCreateFromKnownItem.java:23)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    at io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:60)
    at io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65)
    at io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:133)
    at io.quarkus.vault.runtime.config.VaultConfigSource.lambda$fetchSecrets$2(VaultConfigSource.java:128)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:128)
    at io.quarkus.vault.runtime.config.VaultConfigSource.lambda$fetchSecrets$0(VaultConfigSource.java:121)
    at java.base/java.util.Optional.ifPresent(Optional.java:178)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecrets(VaultConfigSource.java:121)
    at io.quarkus.vault.runtime.config.VaultConfigSource.fetchSecretsFirstTime(VaultConfigSource.java:104)
    at io.quarkus.vault.runtime.config.VaultConfigSource.getSecretConfig(VaultConfigSource.java:82)
    at io.quarkus.vault.runtime.config.VaultConfigSource.getValue(VaultConfigSource.java:63)
    at io.smallrye.config.ConfigValueConfigSourceWrapper.getConfigValue(ConfigValueConfigSourceWrapper.java:20)
    at io.smallrye.config.SmallRyeConfigSources.getValue(SmallRyeConfigSources.java:29)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.SecretKeysConfigSourceInterceptor.getValue(SecretKeysConfigSourceInterceptor.java:26)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.ProfileConfigSourceInterceptor.getProfileValue(ProfileConfigSourceInterceptor.java:51)
    at io.smallrye.config.ProfileConfigSourceInterceptor.getValue(ProfileConfigSourceInterceptor.java:36)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.LoggingConfigSourceInterceptor.getValue(LoggingConfigSourceInterceptor.java:22)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.RelocateConfigSourceInterceptor.getValue(RelocateConfigSourceInterceptor.java:25)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.ExpressionConfigSourceInterceptor.getValue(ExpressionConfigSourceInterceptor.java:43)
    at io.smallrye.config.ExpressionConfigSourceInterceptor.getValue(ExpressionConfigSourceInterceptor.java:35)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.FallbackConfigSourceInterceptor.getValue(FallbackConfigSourceInterceptor.java:24)
    at io.quarkus.opentelemetry.runtime.config.OTelFallbackConfigSourceInterceptor.getValue(OTelFallbackConfigSourceInterceptor.java:44)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.SecretKeysHandlerConfigSourceInterceptor.getValue(SecretKeysHandlerConfigSourceInterceptor.java:26)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.FallbackConfigSourceInterceptor.getValue(FallbackConfigSourceInterceptor.java:24)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.FallbackConfigSourceInterceptor.getValue(FallbackConfigSourceInterceptor.java:24)
    at io.smallrye.config.SmallRyeConfigSourceInterceptorContext.proceed(SmallRyeConfigSourceInterceptorContext.java:20)
    at io.smallrye.config.SmallRyeConfig.getConfigValue(SmallRyeConfig.java:395)
    at io.smallrye.config.SmallRyeConfig.getValue(SmallRyeConfig.java:302)
    at io.smallrye.config.SmallRyeConfig.getOptionalValue(SmallRyeConfig.java:412)
    at io.smallrye.config.ConfigMappingProvider.mapConfiguration(ConfigMappingProvider.java:69)
    at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:84)
    at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:724)
    at io.quarkus.runtime.generated.Config.readConfig(Unknown Source)
    at io.quarkus.runtime.generated.Config.createRunTimeConfig(Unknown Source)
    ... 12 more
radcortez commented 6 months ago

Can you please provide me with the full configuration you are using for Vault and how is being set up exactly? Please remove any sensitive information, but keep the configuration keys. Thanks!

computerlove commented 6 months ago

UnsupportedOperationException: unknown authType null with QUARKUS_VAULT_AUTHENTICATION_APP-ROLE_ROLE-ID and QUARKUS_VAULT_AUTHENTICATION_APP-ROLE_SECRET-ID also.

In application.properties we have

quarkus.vault.kv-secret-engine-mount-path=kv
quarkus.vault.secret-config-kv-path=ext/databaseandotherthings,app/applicationname

When deploying a container this is set as enviroment:

QUARKUS_VAULT_URL: "$VAULT_URL"
QUARKUS_VAULT_AUTHENTICATION_APP-ROLE_ROLE-ID: "$VAULT_ROLE_ID"
QUARKUS_VAULT_AUTHENTICATION_APP-ROLE_SECRET-ID: "$VAULT_SECRET_ID"
radcortez commented 6 months ago

Thanks!

radcortez commented 6 months ago

If you run with quarkus.config.mapping.validate-unknown=false everything works as expected, correct?

computerlove commented 6 months ago

Correct :)

radcortez commented 6 months ago

Great. Please use that for now until I figure out something.

radcortez commented 6 months ago

I've added a fix, but I'll probably prefer to only ship it in the next major Quarkus version. Is it acceptable to have quarkus.config.mapping.validate-unknown=false as a workaround?