Uses Apache Cassandra to store and retrieve entities of all storage areas except authorization and events. Requires Keycloak >= 25.0.0 (older versions may be supported by older versions of this extension).
KC_COMMUNITY_DATASTORE_CASSANDRA_ENABLED=true
(kc.community.datastore.cassandra.enabled=true
as system property) or KC_COMMUNITY_DATASTORE_CASSANDRA_CACHE_ENABLED=true
(kc.community.datastore.cassandra.cache.enabled=true
as system property) to enable the extension:warning: 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 own
DatastoreProvider
. 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 searchUserProvider::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
)
This extension adds support for a grace period when checking for reuses. It 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