diff --git a/servers/quarkus-common/build.gradle.kts b/servers/quarkus-common/build.gradle.kts index 320a5e7d4be..016a7597e84 100644 --- a/servers/quarkus-common/build.gradle.kts +++ b/servers/quarkus-common/build.gradle.kts @@ -31,6 +31,10 @@ dependencies { implementation(project(":nessie-catalog-files-impl")) implementation(project(":nessie-catalog-service-common")) implementation(project(":nessie-catalog-secrets-api")) + implementation(project(":nessie-catalog-secrets-cache")) + implementation(project(":nessie-catalog-secrets-aws")) + implementation(project(":nessie-catalog-secrets-gcs")) + implementation(project(":nessie-catalog-secrets-vault")) compileOnly(project(":nessie-doc-generator-annotations")) @@ -55,14 +59,20 @@ dependencies { implementation("io.quarkus:quarkus-opentelemetry") implementation("io.quarkus:quarkus-micrometer") implementation("io.smallrye.config:smallrye-config-source-keystore") + implementation(enforcedPlatform(libs.quarkus.amazon.services.bom)) + implementation("io.quarkiverse.amazonservices:quarkus-amazon-secretsmanager") implementation("io.quarkiverse.amazonservices:quarkus-amazon-dynamodb") implementation("software.amazon.awssdk:sts") implementation("software.amazon.awssdk:apache-client") { exclude("commons-logging", "commons-logging") } implementation(enforcedPlatform(libs.quarkus.google.cloud.services.bom)) + implementation("io.quarkiverse.googlecloudservices:quarkus-google-cloud-secret-manager") implementation("io.quarkiverse.googlecloudservices:quarkus-google-cloud-bigtable") + + implementation("io.quarkiverse.vault:quarkus-vault") + implementation(enforcedPlatform(libs.quarkus.cassandra.bom)) implementation("com.datastax.oss.quarkus:cassandra-quarkus-client") { // spotbugs-annotations has only a GPL license! diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/config/QuarkusSecretsCacheConfig.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/config/QuarkusSecretsCacheConfig.java new file mode 100644 index 00000000000..59beb2eb3af --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/config/QuarkusSecretsCacheConfig.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.config; + +import io.smallrye.config.WithDefault; +import java.time.Duration; +import java.util.OptionalLong; + +/** Configurations for secrets caching. */ +public interface QuarkusSecretsCacheConfig { + /** Flag whether the secrets cache is enabled. */ + @WithDefault("true") + boolean enabled(); + + /** Optionally restrict the number of cached secrets. */ + OptionalLong maxElements(); + + /** Approximated maximum size on the Java heap for cached secrets. */ + @WithDefault("16") + long capacityMb(); + + /** Time until cached secrets expire. */ + @WithDefault("PT15M") + Duration ttl(); +} diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/config/QuarkusSecretsConfig.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/config/QuarkusSecretsConfig.java new file mode 100644 index 00000000000..b9823fdb463 --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/config/QuarkusSecretsConfig.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.config; + +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; + +@ConfigMapping(prefix = "nessie.secrets") +public interface QuarkusSecretsConfig { + /** Choose the secrets manager to use. */ + @WithDefault("NONE") + SecretsSupplierType type(); + + QuarkusSecretsCacheConfig cache(); + + enum SecretsSupplierType { + NONE, + VAULT, + GOOGLE, + AMAZON + } +} diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/AmazonSecretsSupplierBuilder.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/AmazonSecretsSupplierBuilder.java new file mode 100644 index 00000000000..a516d5e4556 --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/AmazonSecretsSupplierBuilder.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.providers.secrets; + +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.projectnessie.catalog.secrets.aws.AwsSecretsSupplier; +import org.projectnessie.catalog.secrets.spi.SecretsSupplier; +import org.projectnessie.quarkus.config.QuarkusSecretsConfig.SecretsSupplierType; +import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; + +@Dependent +@SecretsType(SecretsSupplierType.AMAZON) +public class AmazonSecretsSupplierBuilder implements SecretsSupplierBuilder { + @Inject SecretsManagerClient client; + + @Override + public SecretsSupplier buildSupplier() { + return new AwsSecretsSupplier(client); + } +} diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/GoogleSecretsSupplierBuilder.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/GoogleSecretsSupplierBuilder.java new file mode 100644 index 00000000000..0d70977fff3 --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/GoogleSecretsSupplierBuilder.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.providers.secrets; + +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.projectnessie.catalog.secrets.gcs.GcsSecretsSupplier; +import org.projectnessie.catalog.secrets.spi.SecretsSupplier; +import org.projectnessie.quarkus.config.QuarkusSecretsConfig.SecretsSupplierType; + +@Dependent +@SecretsType(SecretsSupplierType.GOOGLE) +public class GoogleSecretsSupplierBuilder implements SecretsSupplierBuilder { + + @Inject SecretManagerServiceClient client; + + @Override + public SecretsSupplier buildSupplier() { + return new GcsSecretsSupplier(client); + } +} diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/NoneSecretsSupplierBuilder.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/NoneSecretsSupplierBuilder.java new file mode 100644 index 00000000000..9458b79052a --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/NoneSecretsSupplierBuilder.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.providers.secrets; + +import jakarta.enterprise.context.Dependent; +import java.util.Map; +import org.projectnessie.catalog.secrets.spi.SecretsSupplier; +import org.projectnessie.quarkus.config.QuarkusSecretsConfig.SecretsSupplierType; + +@Dependent +@SecretsType(SecretsSupplierType.NONE) +public class NoneSecretsSupplierBuilder implements SecretsSupplierBuilder { + @Override + public SecretsSupplier buildSupplier() { + return names -> Map.of(); + } +} diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/SecretsSupplierBuilder.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/SecretsSupplierBuilder.java new file mode 100644 index 00000000000..79ecc646c10 --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/SecretsSupplierBuilder.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.providers.secrets; + +import org.projectnessie.catalog.secrets.spi.SecretsSupplier; + +public interface SecretsSupplierBuilder { + SecretsSupplier buildSupplier(); +} diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/SecretsType.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/SecretsType.java new file mode 100644 index 00000000000..4bb79f5817c --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/SecretsType.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.providers.secrets; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import jakarta.enterprise.util.AnnotationLiteral; +import jakarta.inject.Qualifier; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import org.projectnessie.quarkus.config.QuarkusSecretsConfig.SecretsSupplierType; + +/** Store type qualifier for {@code VersionStoreFactory} classes. */ +@Target({TYPE, METHOD, PARAMETER, FIELD}) +@Retention(RUNTIME) +@Documented +@Qualifier +public @interface SecretsType { + /** Gets the store type. */ + SecretsSupplierType value(); + + /** Supports inline instantiation of the {@link SecretsType} qualifier. */ + final class Literal extends AnnotationLiteral implements SecretsType { + + private static final long serialVersionUID = 1L; + private final SecretsSupplierType value; + + public Literal(SecretsSupplierType value) { + this.value = value; + } + + @Override + public SecretsSupplierType value() { + return value; + } + } +} diff --git a/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/VaultSecretsSupplierBuilder.java b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/VaultSecretsSupplierBuilder.java new file mode 100644 index 00000000000..4cf4e746f3e --- /dev/null +++ b/servers/quarkus-common/src/main/java/org/projectnessie/quarkus/providers/secrets/VaultSecretsSupplierBuilder.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 Dremio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.projectnessie.quarkus.providers.secrets; + +import io.quarkus.vault.VaultKVSecretReactiveEngine; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.projectnessie.catalog.secrets.spi.SecretsSupplier; +import org.projectnessie.catalog.secrets.vault.VaultSecretsSupplier; +import org.projectnessie.quarkus.config.QuarkusSecretsConfig.SecretsSupplierType; + +@Dependent +@SecretsType(SecretsSupplierType.VAULT) +public class VaultSecretsSupplierBuilder implements SecretsSupplierBuilder { + @Inject VaultKVSecretReactiveEngine engine; + + @Override + public SecretsSupplier buildSupplier() { + return new VaultSecretsSupplier(engine); + } +} diff --git a/servers/quarkus-server/build.gradle.kts b/servers/quarkus-server/build.gradle.kts index 1ffef1ca560..958eeeeeebf 100644 --- a/servers/quarkus-server/build.gradle.kts +++ b/servers/quarkus-server/build.gradle.kts @@ -68,6 +68,7 @@ dependencies { implementation(project(":nessie-catalog-service-impl")) implementation(project(":nessie-catalog-service-rest")) implementation(project(":nessie-catalog-secrets-api")) + implementation(project(":nessie-catalog-secrets-cache")) implementation(libs.nessie.ui) implementation(enforcedPlatform(libs.quarkus.bom)) diff --git a/servers/quarkus-server/src/main/java/org/projectnessie/server/catalog/CatalogProducers.java b/servers/quarkus-server/src/main/java/org/projectnessie/server/catalog/CatalogProducers.java index 7036f16fe65..7b49d6a9f1e 100644 --- a/servers/quarkus-server/src/main/java/org/projectnessie/server/catalog/CatalogProducers.java +++ b/servers/quarkus-server/src/main/java/org/projectnessie/server/catalog/CatalogProducers.java @@ -15,7 +15,9 @@ */ package org.projectnessie.server.catalog; +import static java.lang.String.format; import static java.time.Clock.systemUTC; +import static org.projectnessie.quarkus.providers.RepositoryIdProvider.REPOSITORY_ID_BEAN_NAME; import com.azure.core.http.HttpClient; import com.google.auth.http.HttpTransportFactory; @@ -32,7 +34,6 @@ import jakarta.inject.Named; import jakarta.inject.Singleton; import java.time.Clock; -import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -60,6 +61,10 @@ import org.projectnessie.catalog.files.s3.S3SessionsManager; import org.projectnessie.catalog.files.s3.S3Signer; import org.projectnessie.catalog.secrets.SecretsProvider; +import org.projectnessie.catalog.secrets.cache.CachingSecrets; +import org.projectnessie.catalog.secrets.cache.CachingSecretsBackend; +import org.projectnessie.catalog.secrets.cache.SecretsCacheConfig; +import org.projectnessie.catalog.secrets.spi.SecretsSupplier; import org.projectnessie.catalog.service.config.CatalogConfig; import org.projectnessie.client.api.NessieApiV2; import org.projectnessie.nessie.combined.CombinedClientBuilder; @@ -72,7 +77,10 @@ import org.projectnessie.quarkus.config.CatalogGcsConfig; import org.projectnessie.quarkus.config.CatalogS3Config; import org.projectnessie.quarkus.config.CatalogServiceConfig; -import org.projectnessie.quarkus.config.QuarkusCatalogConfig; +import org.projectnessie.quarkus.config.QuarkusSecretsConfig; +import org.projectnessie.quarkus.config.QuarkusSecretsConfig.SecretsSupplierType; +import org.projectnessie.quarkus.providers.secrets.SecretsSupplierBuilder; +import org.projectnessie.quarkus.providers.secrets.SecretsType; import org.projectnessie.services.rest.RestV2ConfigResource; import org.projectnessie.services.rest.RestV2TreeResource; import org.projectnessie.versioned.storage.common.config.StoreConfig; @@ -155,8 +163,49 @@ public S3CredentialsResolver s3CredentialsResolver(S3Sessions sessions) { @Produces @Singleton - public SecretsProvider secretsProvider(QuarkusCatalogConfig config) { - return new SecretsProvider(names -> Map.of()); + public SecretsProvider secretsProvider( + @Named(REPOSITORY_ID_BEAN_NAME) String repositoryId, + QuarkusSecretsConfig config, + @Any Instance secretsSupplierBuilders, + @Any Instance meterRegistry) { + SecretsSupplierType type = config.type(); + + if (secretsSupplierBuilders.isUnsatisfied()) { + throw new IllegalStateException("No secrets implementation for " + type); + } + + SecretsSupplier supplier = + secretsSupplierBuilders.select(new SecretsType.Literal(type)).get().buildSupplier(); + + String cacheInfo = ""; + if (type != SecretsSupplierType.NONE && config.cache().enabled()) { + SecretsCacheConfig.Builder cacheConfig = + SecretsCacheConfig.builder() + .clockNanos(System::nanoTime) + .ttlMillis(config.cache().ttl().toMillis()) + .capacityMb(config.cache().capacityMb()); + if (meterRegistry.isResolvable()) { + cacheConfig.meterRegistry(meterRegistry.get()); + } + config.cache().maxElements().ifPresent(cacheConfig::maxElements); + + CachingSecretsBackend backend = new CachingSecretsBackend(cacheConfig.build()); + supplier = new CachingSecrets(backend).forRepository(repositoryId, supplier); + + cacheInfo = + format( + ", with capacity of %d MB and TTL of %s", + config.cache().capacityMb(), config.cache().ttl()); + } + + LOGGER.info("Using {} secrets provider{}", type, cacheInfo); + + return new SecretsProvider(supplier); + } + + public void eagerPersistInitialization( + @Observes StartupEvent event, SecretsProvider secretsProvider) { + // no-op } @Produces diff --git a/servers/quarkus-server/src/main/resources/application.properties b/servers/quarkus-server/src/main/resources/application.properties index 6dda83d9000..322cdf15bb1 100644 --- a/servers/quarkus-server/src/main/resources/application.properties +++ b/servers/quarkus-server/src/main/resources/application.properties @@ -45,6 +45,13 @@ nessie.server.send-stacktrace-to-client=false #quarkus.http.proxy.enable-forwarded-prefix=true #quarkus.http.proxy.trusted-proxies=127.0.0.1 +# Secret managers +nessie.secrets.type=NONE +# When using Google Cloud Secret Manager you may have to configure this to 'true' +quarkus.google.cloud.enable-metadata-server=false +# To enable a specific secrets manager consult the documentations for those, more +# information here: https://projectnessie.org/nessie-latest/configuration/#secrets-manager-settings + ##### Nessie Catalog # Iceberg default config (can be overridden per warehouse) diff --git a/site/in-dev/configuration.md b/site/in-dev/configuration.md index 9f4573f4d38..4e12189a359 100644 --- a/site/in-dev/configuration.md +++ b/site/in-dev/configuration.md @@ -141,6 +141,48 @@ Related Quarkus settings: {% include './generated-docs/smallrye-nessie_catalog_service.md' %} +#### Secrets manager settings + +{% include './generated-docs/smallrye-nessie_secrets.md' %} + +!!! info + See the Quarkus/Quarkiverse documentations for [Vault](https://docs.quarkiverse.io/quarkus-vault/dev/index.html), + [Google Cloud Secrets Manager](https://docs.quarkiverse.io/quarkus-google-cloud-services/main/secretmanager.html) and + [Amazon Secrets Manager Client](https://docs.quarkiverse.io/quarkus-amazon-services/dev/amazon-secretsmanager.html) + on how to configure these. + +##### Types of Secrets + +* **Basic credentials** are composites of a `name` attribute and a `secret` attribute. + AWS credentials are managed as basic credentials, where the `name` represents the access key ID and + the `secret` represents the secret access key. +* **Tokens** are composites of a `token` attribute and an optional `expiresAt` attribute, latter + represented as an instant. +* **Keys** consist of a single `key` attribute. + +Secrets are generally stored as JSON objects representing a map of strings to strings, where the map keys +are defined by the type of the secret as mentioned above. + +##### Secrets in Google Cloud Secrets Manager and Amazon Secrets Manager + +In Google Cloud Secrets Manager and Amazon Secrets Manager all secrets are stored as a simple string. + +For example, a basic credential has to be stored as JSON like this: + +```json +{"name": "mysecret", "secret": "mypassword"} +``` + +A token with an expiration date has to be stored as JSON like this: + +```json +{"token": "rkljmnfgoi4jfgoiujh23o4irj", "expiresAt": "2024-06-05T20:38:16Z"} +``` + +##### Secrets in Google Cloud Secrets Manager and Amazon Secrets Manager + +In Vault, secrets are stored as a map of strings to strings, see [above](#types-of-secrets). + ### Version Store Settings {% include './generated-docs/smallrye-nessie_version_store.md' %} diff --git a/tools/server-admin/src/main/resources/application.properties b/tools/server-admin/src/main/resources/application.properties index ac0f1d6211c..db4094a34cc 100644 --- a/tools/server-admin/src/main/resources/application.properties +++ b/tools/server-admin/src/main/resources/application.properties @@ -20,6 +20,23 @@ nessie.server.default-branch=main nessie.server.send-stacktrace-to-client=false +# To provide secrets via a keystore via Quarkus, the following configuration +# options need to be configured accordingly. +# For details see https://quarkus.io/guides/config-secrets#store-secrets-in-a-keystore +#smallrye.config.source.keystore."properties".path=properties +#smallrye.config.source.keystore."properties".password=arealpassword +#smallrye.config.source.keystore."properties".handler=aes-gcm-nopadding +#smallrye.config.source.keystore."key".path=key +#smallrye.config.source.keystore."key".password=anotherpassword + +# Secret managers +nessie.secrets.type=NONE +# When using Google Cloud Secret Manager you may have to configure this to 'true' +quarkus.google.cloud.enable-metadata-server=false +# To enable a specific secrets manager consult the documentations for those, more +# information here: https://projectnessie.org/nessie-latest/configuration/#secrets-manager-settings + + ### which type of version store to use: IN_MEMORY, ROCKSDB, DYNAMODB, MONGODB, CASSANDRA, JDBC, BIGTABLE. # Note: legacy configuration in `nessie.version.store.advanced` is _not_ applied to the version # store types above. Use the config options starting with `nessie.version.store.persist`.