Polish fips-mode switch for preview (#17228)

* Polish fips-mode switch for preview
Closes #17208 #17210 


Co-authored-by: mposolda <mposolda@gmail.com>
This commit is contained in:
rmartinc 2023-02-22 12:12:52 +01:00 committed by GitHub
parent 9df7ef4331
commit f91ac2970d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 150 additions and 106 deletions

View file

@ -32,6 +32,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -86,7 +87,9 @@ public class Profile {
UPDATE_EMAIL("Update Email Action", Type.PREVIEW), UPDATE_EMAIL("Update Email Action", Type.PREVIEW),
JS_ADAPTER("Host keycloak.js and keycloak-authz.js through the Keycloak sever", Type.DEFAULT); JS_ADAPTER("Host keycloak.js and keycloak-authz.js through the Keycloak sever", Type.DEFAULT),
FIPS("FIPS 140-2 mode", Type.PREVIEW_DISABLED_BY_DEFAULT);
private final Type type; private final Type type;
private String label; private String label;
@ -123,6 +126,7 @@ public class Profile {
DEFAULT("Default"), DEFAULT("Default"),
DISABLED_BY_DEFAULT("Disabled by default"), DISABLED_BY_DEFAULT("Disabled by default"),
PREVIEW("Preview"), PREVIEW("Preview"),
PREVIEW_DISABLED_BY_DEFAULT("Preview disabled by default"), // Preview features, which are not automatically enabled even with enabled preview profile (Needs to be enabled explicitly)
EXPERIMENTAL("Experimental"), EXPERIMENTAL("Experimental"),
DEPRECATED("Deprecated"); DEPRECATED("Deprecated");
@ -197,8 +201,12 @@ public class Profile {
return features.entrySet().stream().filter(e -> !e.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet()); return features.entrySet().stream().filter(e -> !e.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet());
} }
/**
* @return all features of type "preview" or "preview_disabled_by_default"
*/
public Set<Feature> getPreviewFeatures() { public Set<Feature> getPreviewFeatures() {
return getFeatures(Feature.Type.PREVIEW); return Stream.concat(getFeatures(Feature.Type.PREVIEW).stream(), getFeatures(Feature.Type.PREVIEW_DISABLED_BY_DEFAULT).stream())
.collect(Collectors.toSet());
} }
public Set<Feature> getExperimentalFeatures() { public Set<Feature> getExperimentalFeatures() {
@ -257,14 +265,18 @@ public class Profile {
} }
private void logUnsupportedFeatures() { private void logUnsupportedFeatures() {
logUnsuportedFeatures(Feature.Type.PREVIEW, Logger.Level.INFO); logUnsuportedFeatures(Feature.Type.PREVIEW, getPreviewFeatures(), Logger.Level.INFO);
logUnsuportedFeatures(Feature.Type.EXPERIMENTAL, Logger.Level.WARN); logUnsuportedFeatures(Feature.Type.EXPERIMENTAL, getExperimentalFeatures(), Logger.Level.WARN);
logUnsuportedFeatures(Feature.Type.DEPRECATED, Logger.Level.WARN); logUnsuportedFeatures(Feature.Type.DEPRECATED, getDeprecatedFeatures(), Logger.Level.WARN);
} }
private void logUnsuportedFeatures(Feature.Type type, Logger.Level level) { private void logUnsuportedFeatures(Feature.Type type, Set<Feature> checkedFeatures, Logger.Level level) {
Set<Feature.Type> checkedFeatureTypes = checkedFeatures.stream()
.map(Feature::getType)
.collect(Collectors.toSet());
String enabledFeaturesOfType = features.entrySet().stream() String enabledFeaturesOfType = features.entrySet().stream()
.filter(e -> e.getValue() && e.getKey().getType().equals(type)) .filter(e -> e.getValue() && checkedFeatureTypes.contains(e.getKey().getType()))
.map(e -> e.getKey().getKey()).sorted().collect(Collectors.joining(", ")); .map(e -> e.getKey().getKey()).sorted().collect(Collectors.joining(", "));
if (!enabledFeaturesOfType.isEmpty()) { if (!enabledFeaturesOfType.isEmpty()) {

View file

@ -1,21 +1,32 @@
package org.keycloak.common.crypto; package org.keycloak.common.crypto;
public enum FipsMode { public enum FipsMode {
enabled("org.keycloak.crypto.fips.FIPS1402Provider"), NON_STRICT("org.keycloak.crypto.fips.FIPS1402Provider"),
strict("org.keycloak.crypto.fips.Fips1402StrictCryptoProvider"), STRICT("org.keycloak.crypto.fips.Fips1402StrictCryptoProvider"),
disabled("org.keycloak.crypto.def.DefaultCryptoProvider"); DISABLED("org.keycloak.crypto.def.DefaultCryptoProvider");
private String providerClassName; private final String providerClassName;
private final String optionName;
FipsMode(String providerClassName) { FipsMode(String providerClassName) {
this.providerClassName = providerClassName; this.providerClassName = providerClassName;
this.optionName = name().toLowerCase().replace('_', '-');
} }
public boolean isFipsEnabled() { public boolean isFipsEnabled() {
return this.equals(enabled) || this.equals(strict); return this.equals(NON_STRICT) || this.equals(STRICT);
} }
public String getProviderClassName() { public String getProviderClassName() {
return providerClassName; return providerClassName;
} }
public static FipsMode valueOfOption(String name) {
return valueOf(name.toUpperCase().replace('-', '_'));
}
@Override
public String toString() {
return optionName;
}
} }

View file

@ -70,13 +70,13 @@ public class ProfileTest {
} }
Assert.assertEquals(Profile.ProfileName.DEFAULT, profile.getName()); Assert.assertEquals(Profile.ProfileName.DEFAULT, profile.getName());
Set<Profile.Feature> disabledFeatutes = new HashSet<>(Arrays.asList(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DYNAMIC_SCOPES, Profile.Feature.DOCKER, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.MAP_STORAGE, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL)); Set<Profile.Feature> disabledFeatutes = new HashSet<>(Arrays.asList(Profile.Feature.FIPS, Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DYNAMIC_SCOPES, Profile.Feature.DOCKER, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.MAP_STORAGE, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL));
// KERBEROS can be disabled (i.e. FIPS mode disables SunJGSS provider) // KERBEROS can be disabled (i.e. FIPS mode disables SunJGSS provider)
if (Profile.Feature.KERBEROS.getType() == Profile.Feature.Type.DISABLED_BY_DEFAULT) { if (Profile.Feature.KERBEROS.getType() == Profile.Feature.Type.DISABLED_BY_DEFAULT) {
disabledFeatutes.add(Profile.Feature.KERBEROS); disabledFeatutes.add(Profile.Feature.KERBEROS);
} }
assertEquals(profile.getDisabledFeatures(), disabledFeatutes); assertEquals(profile.getDisabledFeatures(), disabledFeatutes);
assertEquals(profile.getPreviewFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL); assertEquals(profile.getPreviewFeatures(), Profile.Feature.FIPS, Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL);
} }
@Test @Test

View file

@ -84,7 +84,7 @@ public class HttpOptions {
.category(OptionCategory.HTTP) .category(OptionCategory.HTTP)
.description("The type of the key store file. " + .description("The type of the key store file. " +
"If not given, the type is automatically detected based on the file name. " + "If not given, the type is automatically detected based on the file name. " +
"If '" + SecurityOptions.FIPS_MODE.getKey() + "' is set to '" + FipsMode.strict.name() + "' and no value is set, it defaults to 'BCFKS'.") "If '" + SecurityOptions.FIPS_MODE.getKey() + "' is set to '" + FipsMode.STRICT + "' and no value is set, it defaults to 'BCFKS'.")
.build(); .build();
public static final Option HTTPS_TRUST_STORE_FILE = new OptionBuilder<>("https-trust-store-file", File.class) public static final Option HTTPS_TRUST_STORE_FILE = new OptionBuilder<>("https-trust-store-file", File.class)
@ -101,7 +101,7 @@ public class HttpOptions {
.category(OptionCategory.HTTP) .category(OptionCategory.HTTP)
.description("The type of the trust store file. " + .description("The type of the trust store file. " +
"If not given, the type is automatically detected based on the file name. " + "If not given, the type is automatically detected based on the file name. " +
"If '" + SecurityOptions.FIPS_MODE.getKey() + "' is set to '" + FipsMode.strict.name() + "' and no value is set, it defaults to 'BCFKS'.") "If '" + SecurityOptions.FIPS_MODE.getKey() + "' is set to '" + FipsMode.STRICT + "' and no value is set, it defaults to 'BCFKS'.")
.build(); .build();
public static final Option<Boolean> HTTP_SERVER_ENABLED = new OptionBuilder<>("http-server-enabled", Boolean.class) public static final Option<Boolean> HTTP_SERVER_ENABLED = new OptionBuilder<>("http-server-enabled", Boolean.class)

View file

@ -14,7 +14,7 @@ public enum OptionCategory {
PROXY("Proxy", 90, ConfigSupportLevel.SUPPORTED), PROXY("Proxy", 90, ConfigSupportLevel.SUPPORTED),
VAULT("Vault", 100, ConfigSupportLevel.SUPPORTED), VAULT("Vault", 100, ConfigSupportLevel.SUPPORTED),
LOGGING("Logging", 110, ConfigSupportLevel.SUPPORTED), LOGGING("Logging", 110, ConfigSupportLevel.SUPPORTED),
SECURITY("Security", 120, ConfigSupportLevel.EXPERIMENTAL), SECURITY("Security", 120, ConfigSupportLevel.PREVIEW),
GENERAL("General", 999, ConfigSupportLevel.SUPPORTED); GENERAL("General", 999, ConfigSupportLevel.SUPPORTED);
private String heading; private String heading;

View file

@ -1,13 +1,21 @@
package org.keycloak.config; package org.keycloak.config;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.keycloak.common.crypto.FipsMode; import org.keycloak.common.crypto.FipsMode;
public class SecurityOptions { public class SecurityOptions {
public static final Option<FipsMode> FIPS_MODE = new OptionBuilder<>("fips-mode", FipsMode.class) public static final Option<FipsMode> FIPS_MODE = new OptionBuilder<>("fips-mode", FipsMode.class)
.category(OptionCategory.SECURITY) .category(OptionCategory.SECURITY)
.expectedValues(SecurityOptions::getFipsModeValues)
.buildTime(true) .buildTime(true)
.description("Sets the FIPS mode. If 'enabled' is set, FIPS is enabled but on non-approved mode. For full FIPS compliance, set 'strict' to run on approved mode.") .description("Sets the FIPS mode. If '" + FipsMode.NON_STRICT + "' is set, FIPS is enabled but on non-approved mode. For full FIPS compliance, set '" + FipsMode.STRICT + "' to run on approved mode.")
.defaultValue(FipsMode.disabled) .defaultValue(FipsMode.DISABLED)
.build(); .build();
private static List<String> getFipsModeValues() {
return Arrays.asList(FipsMode.NON_STRICT.toString(), FipsMode.STRICT.toString());
}
} }

View file

@ -84,7 +84,6 @@ import io.smallrye.config.ConfigValue;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.hibernate.jpa.boot.internal.PersistenceXmlParser; import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.ClassInfo; import org.jboss.jandex.ClassInfo;
@ -217,9 +216,7 @@ class KeycloakProcessor {
return new ConfigBuildItem(); return new ConfigBuildItem();
} }
@Record(ExecutionTime.STATIC_INIT) // called from setCryptoProvider now
@BuildStep
@Consume(ConfigBuildItem.class)
ProfileBuildItem configureProfile(KeycloakRecorder recorder) { ProfileBuildItem configureProfile(KeycloakRecorder recorder) {
Profile profile = Profile.configure( Profile profile = Profile.configure(
new QuarkusProfileConfigResolver(), new QuarkusProfileConfigResolver(),
@ -625,9 +622,16 @@ class KeycloakProcessor {
@BuildStep @BuildStep
@Record(ExecutionTime.STATIC_INIT) @Record(ExecutionTime.STATIC_INIT)
void setCryptoProvider(KeycloakRecorder recorder) { void setCryptoProvider(KeycloakRecorder recorder) {
FipsMode fipsMode = Configuration.getOptionalValue( configureProfile(recorder);
NS_KEYCLOAK_PREFIX + SecurityOptions.FIPS_MODE.getKey()).map( FipsMode fipsMode = Configuration.getOptionalValue(NS_KEYCLOAK_PREFIX + SecurityOptions.FIPS_MODE.getKey())
FipsMode::valueOf).orElse(FipsMode.disabled); .map(FipsMode::valueOfOption)
.orElse(FipsMode.DISABLED);
if (Profile.isFeatureEnabled(Profile.Feature.FIPS) && !fipsMode.isFipsEnabled()) {
// default to non strict when fips feature enabled
fipsMode = FipsMode.NON_STRICT;
} else if (fipsMode.isFipsEnabled() && !Profile.isFeatureEnabled(Profile.Feature.FIPS)) {
throw new RuntimeException("FIPS mode cannot be enabled without enabling the FIPS feature --features=fips");
}
recorder.setCryptoProvider(fipsMode); recorder.setCryptoProvider(fipsMode);
} }

View file

@ -2,17 +2,13 @@ package org.keycloak.quarkus.runtime.configuration.mappers;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.Optional;
import org.keycloak.common.crypto.FipsMode;
import org.keycloak.config.ClassLoaderOptions;
import org.keycloak.config.SecurityOptions;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
import io.smallrye.config.ConfigSourceInterceptorContext; import io.smallrye.config.ConfigSourceInterceptorContext;
import io.smallrye.config.ConfigValue; import java.util.Optional;
import org.keycloak.common.Profile;
import org.keycloak.common.profile.PropertiesFileProfileConfigResolver;
import org.keycloak.config.ClassLoaderOptions;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.QuarkusProfileConfigResolver;
final class ClassLoaderPropertyMappers { final class ClassLoaderPropertyMappers {
@ -29,10 +25,9 @@ final class ClassLoaderPropertyMappers {
private static Optional<String> resolveIgnoredArtifacts(Optional<String> value, ConfigSourceInterceptorContext context) { private static Optional<String> resolveIgnoredArtifacts(Optional<String> value, ConfigSourceInterceptorContext context) {
if (Environment.isRebuildCheck() || Environment.isRebuild()) { if (Environment.isRebuildCheck() || Environment.isRebuild()) {
ConfigValue fipsEnabled = Configuration.getConfigValue( Profile profile = Profile.configure(new QuarkusProfileConfigResolver(), new PropertiesFileProfileConfigResolver());
MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + SecurityOptions.FIPS_MODE.getKey());
if (fipsEnabled != null && FipsMode.valueOf(fipsEnabled.getValue()).isFipsEnabled()) { if (profile.getFeatures().get(Profile.Feature.FIPS)) {
return Optional.of( return Optional.of(
"org.bouncycastle:bcprov-jdk15on,org.bouncycastle:bcpkix-jdk15on,org.bouncycastle:bcutil-jdk15on,org.keycloak:keycloak-crypto-default"); "org.bouncycastle:bcprov-jdk15on,org.bouncycastle:bcpkix-jdk15on,org.bouncycastle:bcutil-jdk15on,org.keycloak:keycloak-crypto-default");
} }

View file

@ -147,7 +147,7 @@ final class HttpPropertyMappers {
ConfigSourceInterceptorContext configSourceInterceptorContext) { ConfigSourceInterceptorContext configSourceInterceptorContext) {
if (value.isPresent()) { if (value.isPresent()) {
try { try {
if (FipsMode.valueOf(value.get()).equals(FipsMode.strict)) { if (FipsMode.valueOfOption(value.get()).equals(FipsMode.STRICT)) {
return of("BCFKS"); return of("BCFKS");
} }
return empty(); return empty();

View file

@ -25,16 +25,16 @@ final class SecurityPropertyMappers {
private static Optional<String> resolveFipsMode(Optional<String> value, ConfigSourceInterceptorContext context) { private static Optional<String> resolveFipsMode(Optional<String> value, ConfigSourceInterceptorContext context) {
if (value.isEmpty()) { if (value.isEmpty()) {
return of(FipsMode.disabled.toString()); return of(FipsMode.DISABLED.toString());
} }
return of(FipsMode.valueOf(value.get()).toString()); return of(FipsMode.valueOfOption(value.get()).toString());
} }
private static Optional<String> resolveSecurityProvider(Optional<String> value, private static Optional<String> resolveSecurityProvider(Optional<String> value,
ConfigSourceInterceptorContext configSourceInterceptorContext) { ConfigSourceInterceptorContext configSourceInterceptorContext) {
FipsMode fipsMode = value.map(FipsMode::valueOf) FipsMode fipsMode = value.map(FipsMode::valueOfOption)
.orElse(FipsMode.disabled); .orElse(FipsMode.DISABLED);
if (fipsMode.isFipsEnabled()) { if (fipsMode.isFipsEnabled()) {
return of("BCFIPS"); return of("BCFIPS");

View file

@ -118,7 +118,7 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<configuration> <configuration>
<argLine>-Djdk.net.hosts.file=${project.build.testOutputDirectory}/hosts_file -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError</argLine> <argLine>-Djdk.net.hosts.file=${project.build.testOutputDirectory}/hosts_file -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError --add-opens=java.base/java.security=ALL-UNNAMED</argLine>
<systemPropertyVariables> <systemPropertyVariables>
<kc.quarkus.tests.dist>${kc.quarkus.tests.dist}</kc.quarkus.tests.dist> <kc.quarkus.tests.dist>${kc.quarkus.tests.dist}</kc.quarkus.tests.dist>
</systemPropertyVariables> </systemPropertyVariables>
@ -187,4 +187,4 @@
</profile> </profile>
</profiles> </profiles>
</project> </project>

View file

@ -123,7 +123,7 @@ public class Keycloak {
addOptionIfNotSet(args, StorageOptions.STORAGE, StorageOptions.StorageType.chm); addOptionIfNotSet(args, StorageOptions.STORAGE, StorageOptions.StorageType.chm);
} }
boolean isFipsEnabled = ofNullable(getOptionValue(args, SecurityOptions.FIPS_MODE)).orElse(FipsMode.disabled).isFipsEnabled(); boolean isFipsEnabled = ofNullable(getOptionValue(args, SecurityOptions.FIPS_MODE)).orElse(FipsMode.DISABLED).isFipsEnabled();
if (isFipsEnabled) { if (isFipsEnabled) {
String logLevel = getOptionValue(args, LoggingOptions.LOG_LEVEL); String logLevel = getOptionValue(args, LoggingOptions.LOG_LEVEL);

View file

@ -60,7 +60,6 @@ final class ServerOptions extends ArrayList<String> {
private Map<String, Predicate<String>> getDefaultOptions(LegacyStore legacyStoreConfig, WithDatabase withDatabase) { private Map<String, Predicate<String>> getDefaultOptions(LegacyStore legacyStoreConfig, WithDatabase withDatabase) {
Map<String, Predicate<String>> defaultOptions = new HashMap<>(); Map<String, Predicate<String>> defaultOptions = new HashMap<>();
defaultOptions.put("--storage=chm", ignoreStorageChm(legacyStoreConfig, withDatabase));
defaultOptions.put("--cache=local", ignoreCacheLocal(legacyStoreConfig)); defaultOptions.put("--cache=local", ignoreCacheLocal(legacyStoreConfig));
return defaultOptions; return defaultOptions;

View file

@ -28,6 +28,8 @@ import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTI
@LegacyStore @LegacyStore
public class FeaturesDistTest { public class FeaturesDistTest {
private static final String PREVIEW_FEATURES_EXPECTED_LOG = "Preview features enabled: admin-fine-grained-authz, client-secret-rotation, declarative-user-profile, openshift-integration, recovery-codes, scripts, token-exchange, update-email";
@Test @Test
public void testEnableOnBuild(KeycloakDistribution dist) { public void testEnableOnBuild(KeycloakDistribution dist) {
CLIResult cliResult = dist.run(Build.NAME, "--features=preview"); CLIResult cliResult = dist.run(Build.NAME, "--features=preview");
@ -47,6 +49,18 @@ public class FeaturesDistTest {
assertPreviewFeaturesEnabled((CLIResult) result); assertPreviewFeaturesEnabled((CLIResult) result);
} }
// Should enable "fips" together with all other "preview" features
@Test
@Launch({StartDev.NAME, "--features=preview,fips"})
public void testEnablePreviewFeaturesAndFips(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
String previewFeaturesWithFipsIncluded = PREVIEW_FEATURES_EXPECTED_LOG.replace("declarative-user-profile", "declarative-user-profile, fips");
assertThat(result.getOutput(), CoreMatchers.allOf(
containsString(previewFeaturesWithFipsIncluded)));
cliResult.assertError("Failed to configure FIPS.");
}
@Test @Test
@Launch({StartDev.NAME, "--features=preview", "--features-disabled=token-exchange"}) @Launch({StartDev.NAME, "--features=preview", "--features-disabled=token-exchange"})
public void testPreviewFeatureDisabledInPreviewMode(LaunchResult result) { public void testPreviewFeatureDisabledInPreviewMode(LaunchResult result) {
@ -87,6 +101,6 @@ public class FeaturesDistTest {
private void assertPreviewFeaturesEnabled(CLIResult result) { private void assertPreviewFeaturesEnabled(CLIResult result) {
assertThat(result.getOutput(), CoreMatchers.allOf( assertThat(result.getOutput(), CoreMatchers.allOf(
containsString("Preview features enabled: admin-fine-grained-authz, client-secret-rotation, declarative-user-profile, openshift-integration, recovery-codes, scripts, token-exchange, update-email"))); containsString(PREVIEW_FEATURES_EXPECTED_LOG)));
} }
} }

View file

@ -29,14 +29,14 @@ import org.keycloak.it.utils.RawKeycloakDistribution;
import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult; import io.quarkus.test.junit.main.LaunchResult;
@DistributionTest(keepAlive = true, defaultOptions = { "--http-enabled=true", "--hostname-strict=false", "--log-level=org.keycloak.common.crypto.CryptoIntegration:trace" }) @DistributionTest(keepAlive = true, defaultOptions = { "--features=fips", "--http-enabled=true", "--hostname-strict=false", "--log-level=org.keycloak.common.crypto.CryptoIntegration:trace" })
@RawDistOnly(reason = "Containers are immutable") @RawDistOnly(reason = "Containers are immutable")
public class FipsDistTest { public class FipsDistTest {
@Test @Test
void testFipsNonApprovedMode(KeycloakDistribution dist) { void testFipsNonApprovedMode(KeycloakDistribution dist) {
runOnFipsEnabledDistribution(dist, () -> { runOnFipsEnabledDistribution(dist, () -> {
CLIResult cliResult = dist.run("start", "--fips-mode=enabled"); CLIResult cliResult = dist.run("start");
cliResult.assertStarted(); cliResult.assertStarted();
cliResult.assertMessage("Java security providers: [ \n" cliResult.assertMessage("Java security providers: [ \n"
+ " KC(BCFIPS version 1.000203, FIPS-JVM: " + KeycloakFipsSecurityProvider.isSystemFipsEnabled() + ") version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider"); + " KC(BCFIPS version 1.000203, FIPS-JVM: " + KeycloakFipsSecurityProvider.isSystemFipsEnabled() + ") version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider");
@ -64,7 +64,7 @@ public class FipsDistTest {
} }
@Test @Test
@Launch({ "start", "--fips-mode=enabled" }) @Launch({ "start", "--fips-mode=non-strict" })
void failStartDueToMissingFipsDependencies(LaunchResult result) { void failStartDueToMissingFipsDependencies(LaunchResult result) {
CLIResult cliResult = (CLIResult) result; CLIResult cliResult = (CLIResult) result;
cliResult.assertError("Failed to configure FIPS. Make sure you have added the Bouncy Castle FIPS dependencies to the 'providers' directory."); cliResult.assertError("Failed to configure FIPS. Make sure you have added the Bouncy Castle FIPS dependencies to the 'providers' directory.");
@ -116,7 +116,7 @@ public class FipsDistTest {
void testHttpsPkcs12KeyStoreInNonApprovedMode(KeycloakDistribution dist) { void testHttpsPkcs12KeyStoreInNonApprovedMode(KeycloakDistribution dist) {
runOnFipsEnabledDistribution(dist, () -> { runOnFipsEnabledDistribution(dist, () -> {
dist.copyOrReplaceFileFromClasspath("/server.keystore.pkcs12", Path.of("conf", "server.keystore")); dist.copyOrReplaceFileFromClasspath("/server.keystore.pkcs12", Path.of("conf", "server.keystore"));
CLIResult cliResult = dist.run("start", "--fips-mode=enabled", "--https-key-store-password=passwordpassword"); CLIResult cliResult = dist.run("start", "--fips-mode=non-strict", "--https-key-store-password=passwordpassword");
cliResult.assertStarted(); cliResult.assertStarted();
}); });
} }
@ -129,8 +129,8 @@ public class FipsDistTest {
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class); RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
Path truststorePath = rawDist.getDistPath().resolve("conf").resolve("server.keystore").toAbsolutePath(); Path truststorePath = rawDist.getDistPath().resolve("conf").resolve("server.keystore").toAbsolutePath();
// https-trust-store-type should be automatically set to pkcs12 in fips-mode=enabled // https-trust-store-type should be automatically set to pkcs12 in fips-mode=non-strict
CLIResult cliResult = dist.run("--verbose", "start", "--fips-mode=enabled", "--https-key-store-password=passwordpassword", CLIResult cliResult = dist.run("--verbose", "start", "--fips-mode=non-strict", "--https-key-store-password=passwordpassword",
"--https-trust-store-file=" + truststorePath, "--https-trust-store-password=passwordpassword"); "--https-trust-store-file=" + truststorePath, "--https-trust-store-password=passwordpassword");
cliResult.assertStarted(); cliResult.assertStarted();
}); });

View file

@ -75,13 +75,13 @@ public class ImportAtStartupDistTest {
@Test @Test
@BeforeStartDistribution(CreateRealmConfigurationFile.class) @BeforeStartDistribution(CreateRealmConfigurationFile.class)
void testImportFromFileCreatedByExportAllRealms(KeycloakDistribution dist) throws IOException { void testImportFromFileCreatedByExportAllRealms(KeycloakDistribution dist) throws IOException {
dist.run("start-dev", "--import-realm"); dist.run("start-dev", "--import-realm", "--storage=chm");
dist.run("export", "--file=../data/import/realm.json"); dist.run("export", "--file=../data/import/realm.json");
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class); RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("chm").toAbsolutePath()); FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("chm").toAbsolutePath());
CLIResult result = dist.run("start-dev", "--import-realm"); CLIResult result = dist.run("start-dev", "--import-realm", "--storage=chm");
result.assertMessage("Realm 'quickstart-realm' imported"); result.assertMessage("Realm 'quickstart-realm' imported");
result.assertMessage("Realm 'master' already exists. Import skipped"); result.assertMessage("Realm 'master' already exists. Import skipped");
} }
@ -89,13 +89,13 @@ public class ImportAtStartupDistTest {
@Test @Test
@BeforeStartDistribution(CreateRealmConfigurationFile.class) @BeforeStartDistribution(CreateRealmConfigurationFile.class)
void testImportFromFileCreatedByExportSingleRealm(KeycloakDistribution dist) throws IOException { void testImportFromFileCreatedByExportSingleRealm(KeycloakDistribution dist) throws IOException {
dist.run("start-dev", "--import-realm"); dist.run("start-dev", "--import-realm", "--storage=chm");
dist.run("export", "--realm=quickstart-realm", "--file=../data/import/realm.json"); dist.run("export", "--realm=quickstart-realm", "--file=../data/import/realm.json");
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class); RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("chm").toAbsolutePath()); FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("chm").toAbsolutePath());
CLIResult result = dist.run("start-dev", "--import-realm"); CLIResult result = dist.run("start-dev", "--import-realm", "--storage=chm");
result.assertMessage("Realm 'quickstart-realm' imported"); result.assertMessage("Realm 'quickstart-realm' imported");
result.assertNoMessage("Not importing realm master from file"); result.assertNoMessage("Not importing realm master from file");
} }
@ -103,14 +103,14 @@ public class ImportAtStartupDistTest {
@Test @Test
@BeforeStartDistribution(CreateRealmConfigurationFile.class) @BeforeStartDistribution(CreateRealmConfigurationFile.class)
void testImportFromDirCreatedByExport(KeycloakDistribution dist) throws IOException { void testImportFromDirCreatedByExport(KeycloakDistribution dist) throws IOException {
dist.run("start-dev", "--import-realm"); dist.run("start-dev", "--import-realm", "--storage=chm");
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class); RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("import").toAbsolutePath()); FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("import").toAbsolutePath());
dist.run("export", "--dir=../data/import"); dist.run("export", "--dir=../data/import");
FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("chm").toAbsolutePath()); FileUtil.deleteDirectory(rawDist.getDistPath().resolve("data").resolve("chm").toAbsolutePath());
CLIResult result = dist.run("start-dev", "--import-realm"); CLIResult result = dist.run("start-dev", "--import-realm", "--storage=chm");
result.assertMessage("Realm 'quickstart-realm' imported"); result.assertMessage("Realm 'quickstart-realm' imported");
result.assertNoMessage("Not importing realm master from file"); result.assertNoMessage("Not importing realm master from file");
} }

View file

@ -46,14 +46,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.

View file

@ -46,14 +46,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.

View file

@ -69,14 +69,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.

View file

@ -69,14 +69,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.

View file

@ -129,14 +129,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
@ -280,11 +280,11 @@ Logging:
categories and their levels. For the root category, you don't need to categories and their levels. For the root category, you don't need to
specify a category. Default: info. specify a category. Default: info.
Security (Experimental): Security (Preview):
--fips-mode <mode> Experimental: Sets the FIPS mode. If 'enabled' is set, FIPS is enabled but on --fips-mode <mode> Preview: Sets the FIPS mode. If 'non-strict' is set, FIPS is enabled but on
non-approved mode. For full FIPS compliance, set 'strict' to run on approved non-approved mode. For full FIPS compliance, set 'strict' to run on approved
mode. Possible values are: enabled, strict, disabled. Default: disabled. mode. Possible values are: non-strict, strict. Default: disabled.
Do NOT start the server using this command when deploying to production. Do NOT start the server using this command when deploying to production.

View file

@ -129,14 +129,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
@ -280,13 +280,13 @@ Logging:
categories and their levels. For the root category, you don't need to categories and their levels. For the root category, you don't need to
specify a category. Default: info. specify a category. Default: info.
Security (Experimental): Security (Preview):
--fips-mode <mode> Experimental: Sets the FIPS mode. If 'enabled' is set, FIPS is enabled but on --fips-mode <mode> Preview: Sets the FIPS mode. If 'non-strict' is set, FIPS is enabled but on
non-approved mode. For full FIPS compliance, set 'strict' to run on approved non-approved mode. For full FIPS compliance, set 'strict' to run on approved
mode. Possible values are: enabled, strict, disabled. Default: disabled. mode. Possible values are: non-strict, strict. Default: disabled.
Do NOT start the server using this command when deploying to production. Do NOT start the server using this command when deploying to production.
Use 'kc.bat start-dev --help-all' to list all available options, including Use 'kc.bat start-dev --help-all' to list all available options, including
build options. build options.

View file

@ -75,14 +75,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.

View file

@ -75,14 +75,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
@ -233,4 +233,4 @@ By default, this command tries to update the server configuration by running a
$ kc.bat start '--optimized' $ kc.bat start '--optimized'
By doing that, the server should start faster based on any previous By doing that, the server should start faster based on any previous
configuration you have set when manually running the 'build' command. configuration you have set when manually running the 'build' command.

View file

@ -135,14 +135,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
@ -286,11 +286,11 @@ Logging:
categories and their levels. For the root category, you don't need to categories and their levels. For the root category, you don't need to
specify a category. Default: info. specify a category. Default: info.
Security (Experimental): Security (Preview):
--fips-mode <mode> Experimental: Sets the FIPS mode. If 'enabled' is set, FIPS is enabled but on --fips-mode <mode> Preview: Sets the FIPS mode. If 'non-strict' is set, FIPS is enabled but on
non-approved mode. For full FIPS compliance, set 'strict' to run on approved non-approved mode. For full FIPS compliance, set 'strict' to run on approved
mode. Possible values are: enabled, strict, disabled. Default: disabled. mode. Possible values are: non-strict, strict. Default: disabled.
By default, this command tries to update the server configuration by running a By default, this command tries to update the server configuration by running a
'build' before starting the server. You can disable this behavior by using the 'build' before starting the server. You can disable this behavior by using the

View file

@ -135,14 +135,14 @@ Feature:
--features <feature> Enables a set of one or more features. Possible values are: account-api, --features <feature> Enables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
--features-disabled <feature> --features-disabled <feature>
Disables a set of one or more features. Possible values are: account-api, Disables a set of one or more features. Possible values are: account-api,
account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, account2, admin-api, admin-fine-grained-authz, admin2, authorization, ciba,
client-policies, client-secret-rotation, declarative-user-profile, docker, client-policies, client-secret-rotation, declarative-user-profile, docker,
dynamic-scopes, impersonation, js-adapter, kerberos, map-storage, dynamic-scopes, fips, impersonation, js-adapter, kerberos, map-storage,
openshift-integration, par, preview, recovery-codes, scripts, openshift-integration, par, preview, recovery-codes, scripts,
step-up-authentication, token-exchange, update-email, web-authn. step-up-authentication, token-exchange, update-email, web-authn.
@ -286,11 +286,11 @@ Logging:
categories and their levels. For the root category, you don't need to categories and their levels. For the root category, you don't need to
specify a category. Default: info. specify a category. Default: info.
Security (Experimental): Security (Preview):
--fips-mode <mode> Experimental: Sets the FIPS mode. If 'enabled' is set, FIPS is enabled but on --fips-mode <mode> Preview: Sets the FIPS mode. If 'non-strict' is set, FIPS is enabled but on
non-approved mode. For full FIPS compliance, set 'strict' to run on approved non-approved mode. For full FIPS compliance, set 'strict' to run on approved
mode. Possible values are: enabled, strict, disabled. Default: disabled. mode. Possible values are: non-strict, strict. Default: disabled.
By default, this command tries to update the server configuration by running a By default, this command tries to update the server configuration by running a
'build' before starting the server. You can disable this behavior by using the 'build' before starting the server. You can disable this behavior by using the
@ -299,4 +299,4 @@ By default, this command tries to update the server configuration by running a
$ kc.bat start '--optimized' $ kc.bat start '--optimized'
By doing that, the server should start faster based on any previous By doing that, the server should start faster based on any previous
configuration you have set when manually running the 'build' command. configuration you have set when manually running the 'build' command.

View file

@ -304,7 +304,7 @@
<profile> <profile>
<id>auth-server-fips140-2</id> <id>auth-server-fips140-2</id>
<properties> <properties>
<auth.server.fips.mode>enabled</auth.server.fips.mode> <auth.server.fips.mode>non-strict</auth.server.fips.mode>
</properties> </properties>
<dependencies> <dependencies>
@ -376,4 +376,4 @@
</profile> </profile>
</profiles> </profiles>
</project> </project>

View file

@ -131,7 +131,7 @@ public class AuthServerTestEnricher {
public static final String AUTH_SERVER_FIPS_MODE_PROPERTY = "auth.server.fips.mode"; public static final String AUTH_SERVER_FIPS_MODE_PROPERTY = "auth.server.fips.mode";
public static final FipsMode AUTH_SERVER_FIPS_MODE = FipsMode.valueOf(System.getProperty(AUTH_SERVER_FIPS_MODE_PROPERTY, FipsMode.disabled.toString())); public static final FipsMode AUTH_SERVER_FIPS_MODE = FipsMode.valueOfOption(System.getProperty(AUTH_SERVER_FIPS_MODE_PROPERTY, FipsMode.DISABLED.toString()));
public static final String CACHE_SERVER_LIFECYCLE_SKIP_PROPERTY = "cache.server.lifecycle.skip"; public static final String CACHE_SERVER_LIFECYCLE_SKIP_PROPERTY = "cache.server.lifecycle.skip";
public static final boolean CACHE_SERVER_LIFECYCLE_SKIP = Boolean.parseBoolean(System.getProperty(CACHE_SERVER_LIFECYCLE_SKIP_PROPERTY, "false")); public static final boolean CACHE_SERVER_LIFECYCLE_SKIP = Boolean.parseBoolean(System.getProperty(CACHE_SERVER_LIFECYCLE_SKIP_PROPERTY, "false"));

View file

@ -173,7 +173,7 @@ public abstract class AbstractQuarkusDeployableContainer implements DeployableCo
log.debugf("FIPS Mode: %s", configuration.getFipsMode()); log.debugf("FIPS Mode: %s", configuration.getFipsMode());
// only run build during first execution of the server (if the DB is specified), restarts or when running cluster tests // only run build during first execution of the server (if the DB is specified), restarts or when running cluster tests
if (restart.get() || shouldSetUpDb.get() || "ha".equals(getClusterConfig.get()) || configuration.getFipsMode() != FipsMode.disabled) { if (restart.get() || shouldSetUpDb.get() || "ha".equals(getClusterConfig.get()) || configuration.getFipsMode() != FipsMode.DISABLED) {
commands.removeIf("--optimized"::equals); commands.removeIf("--optimized"::equals);
commands.add("--http-relative-path=/auth"); commands.add("--http-relative-path=/auth");
@ -187,7 +187,7 @@ public abstract class AbstractQuarkusDeployableContainer implements DeployableCo
} }
} }
if (configuration.getFipsMode() != FipsMode.disabled) { if (configuration.getFipsMode() != FipsMode.DISABLED) {
addFipsOptions(commands); addFipsOptions(commands);
} }
} }
@ -325,6 +325,7 @@ public abstract class AbstractQuarkusDeployableContainer implements DeployableCo
} }
private void addFipsOptions(List<String> commands) { private void addFipsOptions(List<String> commands) {
commands.add("--features=fips");
commands.add("--fips-mode=" + configuration.getFipsMode().toString()); commands.add("--fips-mode=" + configuration.getFipsMode().toString());
log.debugf("Keystore file: %s, truststore file: %s", log.debugf("Keystore file: %s, truststore file: %s",
@ -339,7 +340,7 @@ public abstract class AbstractQuarkusDeployableContainer implements DeployableCo
// BCFIPS approved mode requires passwords of at least 112 bits (14 characters) to be used. To bypass this, we use this by default // BCFIPS approved mode requires passwords of at least 112 bits (14 characters) to be used. To bypass this, we use this by default
// as testsuite uses shorter passwords everywhere // as testsuite uses shorter passwords everywhere
if (FipsMode.strict == configuration.getFipsMode()) { if (FipsMode.STRICT == configuration.getFipsMode()) {
commands.add("--spi-password-hashing-pbkdf2-max-padding-length=14"); commands.add("--spi-password-hashing-pbkdf2-max-padding-length=14");
commands.add("--spi-password-hashing-pbkdf2-sha256-max-padding-length=14"); commands.add("--spi-password-hashing-pbkdf2-sha256-max-padding-length=14");
commands.add("--spi-password-hashing-pbkdf2-sha512-max-padding-length=14"); commands.add("--spi-password-hashing-pbkdf2-sha512-max-padding-length=14");

View file

@ -45,7 +45,7 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
private boolean reaugmentBeforeStart; private boolean reaugmentBeforeStart;
private String importFile = System.getProperty("migration.import.file.name"); private String importFile = System.getProperty("migration.import.file.name");
private FipsMode fipsMode = FipsMode.valueOf(System.getProperty("auth.server.fips.mode")); private FipsMode fipsMode = FipsMode.valueOfOption(System.getProperty("auth.server.fips.mode"));
@Override @Override
public void validate() throws ConfigurationException { public void validate() throws ConfigurationException {

View file

@ -75,7 +75,7 @@ public abstract class AbstractCliTest extends AbstractKeycloakTest {
} }
private boolean isFipsDisabled() { private boolean isFipsDisabled() {
return AuthServerTestEnricher.AUTH_SERVER_FIPS_MODE == FipsMode.disabled; return AuthServerTestEnricher.AUTH_SERVER_FIPS_MODE == FipsMode.DISABLED;
} }
} }

View file

@ -213,7 +213,7 @@ public class KcRegCreateTest extends AbstractRegCliTest {
} }
// TODO: SAML is not tested with FIPS enabled as it does not work. This needs to be revisited when SAML works with FIPS // TODO: SAML is not tested with FIPS enabled as it does not work. This needs to be revisited when SAML works with FIPS
if (AuthServerTestEnricher.AUTH_SERVER_FIPS_MODE == FipsMode.disabled) { if (AuthServerTestEnricher.AUTH_SERVER_FIPS_MODE == FipsMode.DISABLED) {
// test create saml formated xml - format autodetection // test create saml formated xml - format autodetection
File samlSpMetaFile = new File(System.getProperty("user.dir") + "/src/test/resources/cli/kcreg/saml-sp-metadata.xml"); File samlSpMetaFile = new File(System.getProperty("user.dir") + "/src/test/resources/cli/kcreg/saml-sp-metadata.xml");

View file

@ -1569,7 +1569,7 @@
<profile> <profile>
<id>auth-server-fips140-2</id> <id>auth-server-fips140-2</id>
<properties> <properties>
<auth.server.fips.mode>enabled</auth.server.fips.mode> <auth.server.fips.mode>non-strict</auth.server.fips.mode>
<auth.server.supported.keystore.types>PKCS12,BCFKS</auth.server.supported.keystore.types> <auth.server.supported.keystore.types>PKCS12,BCFKS</auth.server.supported.keystore.types>
<auth.server.kerberos.supported>false</auth.server.kerberos.supported> <auth.server.kerberos.supported>false</auth.server.kerberos.supported>