Skip to content

Commit

Permalink
Introduce CLI parameter to set the deployment state version seed (#13412
Browse files Browse the repository at this point in the history
)

Closes #12710

Co-authored-by: Alexander Schwartz <aschwart@redhat.com>
  • Loading branch information
hmlnarik and ahus1 committed Jul 29, 2022
1 parent f3a734e commit 2a6d8ff
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ public void init(Config.Scope config) {
String seed = config.get(RESOURCES_VERSION_SEED);
if (seed == null) {
Logger.getLogger(DeploymentStateProviderFactory.class)
.warnf("It is recommended to set '%s' property in the %s provider config of %s SPI", RESOURCES_VERSION_SEED, PROVIDER_ID, DeploymentStateSpi.NAME);
.warnf("Version seed for deployment state set with a random number. Caution: This can lead to unstable operations when serving resources from the cluster without a sticky loadbalancer or when restarting nodes. Set the '%s' property in the %s provider config of %s SPI for stable operations", RESOURCES_VERSION_SEED, PROVIDER_ID, DeploymentStateSpi.NAME);
//generate random string for this installation
seed = SecretGenerator.getInstance().randomString(10);
}
try {
Version.RESOURCES_VERSION = Base64Url.encode(MessageDigest.getInstance("SHA-256")
.digest((seed + new ModelVersion(Version.VERSION_KEYCLOAK).toString()).getBytes()))
.digest((seed + Version.RESOURCES_VERSION).getBytes()))
.substring(0, 5);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ public String getProvider() {
.buildTime(true)
.build();

public static final Option<String> STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED = new OptionBuilder<>("storage-deployment-state-version-seed", String.class)
.category(OptionCategory.STORAGE)
.description("Secret that serves as a seed to mask the version number of Keycloak in URLs. Need to be identical across all servers in the cluster. Will default to a random number generated when starting the server which is secure but will lead to problems when a loadbalancer without sticky sessions is used or nodes are restarted.")
.hidden()
.buildTime(false)
.build();

public static final Option<String> STORAGE_AUTH_SESSION_PROVIDER = new OptionBuilder<>("storage-auth-session-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;

import java.util.Optional;

import org.jboss.logging.Logger;
import org.keycloak.common.util.SecretGenerator;
import org.keycloak.config.StorageOptions;
import org.keycloak.config.StorageOptions.StorageType;

Expand Down Expand Up @@ -136,6 +139,11 @@ public static PropertyMapper[] getMappers() {
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED)
.to("kc.spi-deployment-state-map-resources-version-seed")
.transformer(StoragePropertyMappers::getResourcesVersionSeed)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_AUTH_SESSION_PROVIDER)
.to("kc.spi-authentication-sessions-provider")
.mapFrom("storage")
Expand Down Expand Up @@ -307,18 +315,19 @@ public static PropertyMapper[] getMappers() {
};
}

private static Optional<String> isForceComponentFactoryCache(Optional<String> storage, ConfigSourceInterceptorContext context) {
if (storage.isPresent()) {
return Optional.of(Boolean.TRUE.toString());
}

return storage;
}

private static Optional<String> getAreaStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
return of(storage.isEmpty() ? "jpa" : "map");
}

private static Optional<String> getResourcesVersionSeed(Optional<String> parameterValue, ConfigSourceInterceptorContext context) {
if (!parameterValue.isEmpty()) {
return parameterValue;
}
Logger.getLogger(StoragePropertyMappers.class)
.warnf("Version seed for deployment state set with a random number. Caution: This can lead to unstable operations when serving resources from the cluster without a sticky loadbalancer or when restarting nodes. Set the '--%s' option with a secret seed to ensure stable operations.", StorageOptions.STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED.getKey());
return Optional.of(SecretGenerator.getInstance().randomString(10));
}

private static Optional<String> getCacheStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
return of(storage.isEmpty() ? "infinispan" : "map");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Options:

Storage (Experimental):

--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Options:

Storage (Experimental):

--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.
Expand Down

0 comments on commit 2a6d8ff

Please sign in to comment.