Uses Apache Cassandra to store and retrieve entities of all storage areas except authorization and events. Requires Keycloak >= 23.0.0.
⚠️ Keycloak 23 support is still early stages and mostly untested. Use version1.3.2-22.0.1
for Keycloak up until 22.x.x.
- Download the JAR from Maven Central: https://repo1.maven.org/maven2/de/arbeitsagentur/opdt/keycloak-cassandra-extension/1.1.0-22.0.1/keycloak-cassandra-extension-1.1.0-22.0.1.jar
- Put the JAR in Keycloak's providers folder
- Set
KC_COMMUNITY_DATASTORE_CASSANDRA_ENABLED=true
(kc.community.datastore.cassandra.enabled=true
as system property) orKC_COMMUNITY_DATASTORE_CASSANDRA_CACHE_ENABLED=true
(kc.community.datastore.cassandra.cache.enabled=true
as system property) to enable the extension - Set the necessary configuration options like cassandra endpoints (see the overview below)
⚠️ Important information: Since map storage has been removed from Keycloak, using different storage providers for different storage areas (like users, roles) requires you to implement your ownDatastoreProvider
. If "cache mode" is active (KC_COMMUNITY_DATASTORE_CASSANDRA_CACHE_ENABLED=true
), default providers (jpa) are used for non-cache areas.
The following parameters might be needed in addition to the configuration options of this extension (see below):
CLI-Parameter | Description |
---|---|
--features-disabled=authorization | Disable authorization (this is essential as otherwise Keycloak tries to use InfinispanStoreFactory at a lot of places) |
--spi-connections-jpa-legacy-enabled=false | Deactivate automatic JPA schema migration |
CLI-Parameter | Description |
---|---|
--spi-cassandra-connection-default-port | Cassandra CQL-Port |
--spi-cassandra-connection-default-contact-points | Comma-separated list of cassandra node-endpoints |
--spi-cassandra-connection-default-local-datacenter | Local datacenter name |
--spi-cassandra-connection-default-username | Username |
--spi-cassandra-connection-default-password | Password |
--spi-cassandra-connection-default-keyspace | Keyspace-name (will be generated by the extension if it does not exist at startup-time) |
--spi-cassandra-connection-default-replication-factor | Replication factor used if the extension creates the keyspace with simple strategy |
Due to Cassandras query first nature, users can only be looked up by specific fields.
UserProvider::searchForUserStream
supports the following subset of Keycloaks standard search attributes:
keycloak.session.realm.users.query.search
for a case insensitive username searchkeycloak.session.realm.users.query.include_service_account
to include service accountsemail
for an email search
UserProvider::searchForUserByUserAttributeStream
by default iterates all users in the entire database to filter for the requested attribute in-memory.
For efficient searches, attributes can be defined as indexed attributes by prefixing their name with indexed., e.g. indexed.businessKey
All write-queries are done conditionally via Cassandra Lightweight Transactions. Therefore we store a version column in each of the tables. To be able to use this to get notified if a conflicting change occured after data was read, the entityVersion is exposed via a readonly attribute readonly.entityVersion. In order to pass a version in update operations, one can use the corresponding attribute internal.entityVersion.
This extension supports additional checks to prevent setting username to a value that is already as email of another user and setting email to a value used as username.
To enable these checks for a realm, set its attribute enableCheckForDuplicatesAcrossUsernameAndEmail
to true
(default when not set: false
)
There is a long-standing bug inside Keycloak which prevents independent refresh token rotations on multiple tabs, using the same client: keycloak/keycloak#14122
This extension implements a workaround which is only active when refreshTokenMaxReuse
is equal to 0. Then the last refresh is tracked per refresh token instead of per client session.
Additionally, a grace period can be set via refreshTokenReuseInterval
realm attribute. Refresh token reuses during this grace period are allowed, which can be useful in case of retries / network problems.
Before contributing to Keycloak Cassandra, please read our contributing guidelines.
If you use a private image registry, you can use the .testcontainers file in your user directory to override all image-registries used by the tests. See https://www.testcontainers.org/features/image_name_substitution/
Example:
docker.client.strategy=org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy
hub.image.name.prefix=private-registry/3rd-party/
Debugging can be enabled via mvn -Dmaven.surefire.debug verify
(Port 5005).
If you want to use an external cassandra instance on localhost (Port 9042) you can
use mvn -Dkeycloak.testsuite.start-cassandra-container=false verify