From 5e11c4421112b940f99305126a1eb3396a1c0b9b Mon Sep 17 00:00:00 2001 From: Tanner Smith Date: Wed, 1 Apr 2026 10:00:12 -0400 Subject: [PATCH 1/2] Validate .conf extension for --config-file option The --config-file option and KC_CONFIG_FILE environment variable silently ignored configuration files that did not use the .conf extension. This happened because the underlying SmallRye config source loader filters by file extension, returning an empty list for non-.conf files without any indication to the user. Added explicit validation in both the CLI option setter and the config source file resolution to reject files that do not end with .conf, giving the user a clear error message instead of silently ignoring their configuration. Closes #46978 Signed-off-by: Tanner Smith --- .../org/keycloak/quarkus/runtime/cli/command/Main.java | 4 ++++ .../configuration/KeycloakPropertiesConfigSource.java | 5 +++++ .../org/keycloak/it/cli/dist/StartCommandDistTest.java | 7 +++++++ .../integration/src/test/resources/keycloak.properties | 1 + 4 files changed, 17 insertions(+) create mode 100644 quarkus/tests/integration/src/test/resources/keycloak.properties diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java index 22efca662830..a8e336c0295a 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java @@ -111,6 +111,10 @@ public void setConfigFile(String path) { throw new CommandLine.ParameterException(spec.commandLine(), String.format("File specified via '%s' or '%s' option does not exist.", CONFIG_FILE_LONG_NAME, CONFIG_FILE_SHORT_NAME)); } + if (!path.endsWith(".conf")) { + throw new CommandLine.ParameterException(spec.commandLine(), + String.format("Configuration file specified via '%s' or '%s' must have the '.conf' extension.", CONFIG_FILE_LONG_NAME, CONFIG_FILE_SHORT_NAME)); + } System.setProperty(KeycloakPropertiesConfigSource.KEYCLOAK_CONFIG_FILE_PROP, path); } } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java index 931839b9722a..7e230a669923 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java @@ -99,6 +99,11 @@ public Path getConfigurationFile() { return null; } + if (!filePath.endsWith(".conf")) { + throw new RuntimeException( + String.format("Configuration file '%s' must have the '.conf' extension.", filePath)); + } + return Paths.get(filePath); } } diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java index 6050c7ffced0..565b47f32ace 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java @@ -250,6 +250,13 @@ void testInvalidConfigFileOption(CLIResult cliResult) { cliResult.assertError(String.format("Try '%s --help' for more information on the available options.", KeycloakDistribution.SCRIPT_CMD)); } + @DryRun + @Test + @Launch({CONFIG_FILE_LONG_NAME + "=src/test/resources/keycloak.properties", "start", "--db=dev-file"}) + void testConfigFileWithWrongExtension(CLIResult cliResult) { + cliResult.assertError("Configuration file specified via '--config-file' or '-cf' must have the '.conf' extension."); + } + @RawDistOnly(reason = "Containers are immutable") @Test void testRuntimeValuesAreNotCaptured(KeycloakDistribution dist) { diff --git a/quarkus/tests/integration/src/test/resources/keycloak.properties b/quarkus/tests/integration/src/test/resources/keycloak.properties new file mode 100644 index 000000000000..da05346608c8 --- /dev/null +++ b/quarkus/tests/integration/src/test/resources/keycloak.properties @@ -0,0 +1 @@ +# test config with wrong extension From 68252be02037e50e27651e59ca70c2fc62f0730c Mon Sep 17 00:00:00 2001 From: Tanner Smith Date: Thu, 2 Apr 2026 09:01:39 -0400 Subject: [PATCH 2/2] fix: validate config file extension before checking existence Move the .conf extension check before the file existence check in setConfigFile(). When a file with a wrong extension does not exist relative to the working directory, the existence check would fire first, masking the more specific extension validation error. Closes keycloak/keycloak#47696 Signed-off-by: Tanner Smith --- .../org/keycloak/quarkus/runtime/cli/command/Main.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java index a8e336c0295a..1d321c762e11 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Main.java @@ -107,14 +107,14 @@ public void setProfile(String profile) { description = "Set the path to a configuration file. By default, configuration properties are read from the \"keycloak.conf\" file in the \"conf\" directory.", paramLabel = "file") public void setConfigFile(String path) { - if (Files.notExists(Path.of(path))) { - throw new CommandLine.ParameterException(spec.commandLine(), - String.format("File specified via '%s' or '%s' option does not exist.", CONFIG_FILE_LONG_NAME, CONFIG_FILE_SHORT_NAME)); - } if (!path.endsWith(".conf")) { throw new CommandLine.ParameterException(spec.commandLine(), String.format("Configuration file specified via '%s' or '%s' must have the '.conf' extension.", CONFIG_FILE_LONG_NAME, CONFIG_FILE_SHORT_NAME)); } + if (Files.notExists(Path.of(path))) { + throw new CommandLine.ParameterException(spec.commandLine(), + String.format("File specified via '%s' or '%s' option does not exist.", CONFIG_FILE_LONG_NAME, CONFIG_FILE_SHORT_NAME)); + } System.setProperty(KeycloakPropertiesConfigSource.KEYCLOAK_CONFIG_FILE_PROP, path); } }