-
Bug
-
Resolution: Done
-
Undefined
-
None
-
False
-
-
False
-
-
Before reporting an issue
[X] I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
infinispan
Describe the bug
We ran into an issue while configuring a Keycloak cluster that uses a remote Infinispan cluster (we are using Infinispan version 14.0.21.Final); we are using Terraform to do so, using this provider.
Please find the relevant configurations below.
Terraform:
```
terraform {
required_version = ">= 0.14.11, < 2.0.0"
required_providers
keycloak =
{ source = "mrparkers/keycloak" version = "4.4.0" } {code} }
}
provider "keycloak" {
client_id = "admin-cli"
username = "foo"
password = "bar"
url = "https://localhost:8081"
base_path = "/foo"
client_timeout = 60
}
resource "keycloak_realm" "foo_realm" {
realm = "foo"
display_name = "foo realm"
enabled = true
login_with_email_allowed = true
}
resource "keycloak_authentication_flow" "foo_browser_flow" {
realm_id = keycloak_realm.foo_realm.id
alias = "foo-browser"
description = "Browser based authentication for clients"
provider_id = "basic-flow"
}
resource "keycloak_authentication_execution" "foo_browser_cookie_execution" {
realm_id = keycloak_realm.foo_realm.id
parent_flow_alias = keycloak_authentication_flow.foo_browser_flow.alias
authenticator = "auth-cookie"
requirement = "ALTERNATIVE"
}
resource "keycloak_authentication_subflow" "foo_browser_subflow_authentication"
{ depends_on = [keycloak_authentication_execution.foo_browser_cookie_execution] realm_id = keycloak_realm.foo_realm.id alias = "foo-browser-subflow-authentication" description = "foo: lorem ipsum" parent_flow_alias = keycloak_authentication_flow.foo_browser_flow.alias provider_id = "basic-flow" requirement = "ALTERNATIVE" } ``` Our setup is the following: - 3-node Keycloak cluster - 3-node Infinispan cluster - Postgres as a backend for Keycloak - Infinispan is configured with a persisting store (Postgres) Please find the configs for Keycloak and Infinispan below. Keycloak: ```<?xml version="1.0" encoding="UTF-8"?> <infinispan {code} xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:14.0 http://www.infinispan.org/schemas/infinispan-config-14.0.xsd"
xmlns="urn:infinispan:config:14.0">
<cache-container name="keycloak">
<transport lock-timeout="60000"/>
<local-cache-configuration name="local-cache-cfg">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
</local-cache-configuration>
<local-cache name="realms" configuration="local-cache-cfg">
<memory max-count="10000"/>
</local-cache>
<local-cache name="users" configuration="local-cache-cfg">
<memory max-count="10000"/>
</local-cache>
<local-cache name="keys" configuration="local-cache-cfg">
<expiration max-idle="3600000"/>
<memory max-count="1000"/>
</local-cache>
<local-cache name="authorization" configuration="local-cache-cfg">
<memory max-count="10000"/>
</local-cache>
<distributed-cache name="authenticationSessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<distributed-cache name="sessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="sessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="clientSessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="clientSessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="offlineSessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="offlineSessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="offlineClientSessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="offlineClientSessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="loginFailures" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="loginFailures"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="actionTokens" owners="2">
<expiration max-idle="-1" lifespan="-1" interval="300000"/>
<memory max-count="-1"/>
<remote-store cache="actionTokens" xmlns="urn:infinispan:config:store:remote:14.0"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<replicated-cache name="work">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="work"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</replicated-cache>
</cache-container>
</infinispan> ``` Infinispan: ```<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:infinispan:config:14.0"
xsi:schemaLocation="urn:infinispan:config:14.0 https://infinispan.org/schemas/infinispan-config-14.0.xsd urn:infinispan:server:14.0 https://infinispan.org/schemas/infinispan-server-14.0.xsd">
<!-- see https://docs.jboss.org/infinispan/14.0/configdocs/infinispan-config-14.0.html -->
<jgroups>
<!-- TCP local cluster with JDBCPING discovery -->
<stack name="dns-ping">
<dns.DNS_PING dns_query="${jgroups.dns.query}" />
<FD_SOCK stack.combine="REMOVE"/>
<pbcast.GMS join_timeout="30000" />
<RSVP timeout="60000" resend_interval="500" ack_on_delivery="true" />
</stack>
</jgroups>
<cache-container name="default" statistics="true">
<metrics gauges="true" histograms="false" />
<!-- TODO configure custom jgroups stack: +auth +encryption -->
<serialization marshaller="org.infinispan.jboss.marshalling.commons.GenericJBossMarshaller">
<allow-list>
<class>org.keycloak.cluster.infinispan.WrapperClusterEvent</class>
<regex>.*</regex>
</allow-list>
</serialization>
<transport
cluster="${infinispan.cluster.name:kcispn}"
stack="${infinispan.cluster.stack:kubernetes}"
node-name="${env.POD_NAME}"/>
<replicated-cache-configuration name="replicated-cache-cfg"
xmlns:jdbc="urn:infinispan:config:store:jdbc:14.0"
mode="SYNC"
statistics="true"
segments="256"
unreliable-return-values="false">
<encoding media-type="application/x-jboss-marshalling"/>
<transaction mode="NON_XA"
locking="OPTIMISTIC"/>
<persistence passivation="false">
<jdbc:string-keyed-jdbc-store shared="true" preload="false">
<jdbc:data-source jndi-url="jdbc/datasource"/>
<jdbc:string-keyed-table drop-on-exit="false" create-on-start="true" prefix="ispn">
<jdbc:id-column name="id" type="VARCHAR(255)"/>
<jdbc:data-column name="data" type="bytea"/>
<jdbc:timestamp-column name="ts" type="BIGINT"/>
<jdbc:segment-column name="seg" type="INT"/>
</jdbc:string-keyed-table>
</jdbc:string-keyed-jdbc-store>
</persistence>
</replicated-cache-configuration>
<distributed-cache-configuration name="distributed-cache-cfg"
xmlns:jdbc="urn:infinispan:config:store:jdbc:14.0"
mode="SYNC"
owners="2"
remote-timeout="60000"
statistics="true"
segments="256"
unreliable-return-values="false">
<encoding media-type="application/x-jboss-marshalling"/>
<locking isolation="REPEATABLE_READ"
striping="false"
acquire-timeout="10000"
concurrency-level="32"/>
<transaction mode="NON_XA"
locking="OPTIMISTIC"/>
<expiration lifespan="-1"
max-idle="-1"
interval="60000" />
<memory max-count="-1" when-full="NONE" storage="HEAP"/>
<partition-handling when-split="ALLOW_READ_WRITES" />
<persistence passivation="false">
<jdbc:string-keyed-jdbc-store shared="true" preload="false">
<jdbc:data-source jndi-url="jdbc/datasource"/>
<jdbc:string-keyed-table drop-on-exit="false" create-on-start="true" prefix="ispn">
<jdbc:id-column name="id" type="VARCHAR(255)"/>
<jdbc:data-column name="data" type="bytea"/>
<jdbc:timestamp-column name="ts" type="BIGINT"/>
<jdbc:segment-column name="seg" type="INT"/>
</jdbc:string-keyed-table>
</jdbc:string-keyed-jdbc-store>
</persistence>
<state-transfer enabled="true"
timeout="240000"
chunk-size="240000"
await-initial-transfer="true"/>
</distributed-cache-configuration>
<replicated-cache name="work" configuration="replicated-cache-cfg">
</replicated-cache>
<distributed-cache name="sessions" configuration="distributed-cache-cfg">
</distributed-cache>
<distributed-cache name="authenticationSessions" configuration="distributed-cache-cfg">
</distributed-cache>
<distributed-cache name="offlineSessions" configuration="distributed-cache-cfg">
</distributed-cache>
<distributed-cache name="clientSessions" configuration="distributed-cache-cfg">
</distributed-cache>
<distributed-cache name="offlineClientSessions" configuration="distributed-cache-cfg">
</distributed-cache>
<distributed-cache name="loginFailures" configuration="distributed-cache-cfg">
</distributed-cache>
<distributed-cache name="actionTokens" configuration="distributed-cache-cfg">
<memory max-count="-1">
</memory>
<expiration interval="300000" max-idle="-1"/>
</distributed-cache>
</cache-container>
<server xmlns="urn:infinispan:server:14.0">
<interfaces>
<interface name="public">
<any-address/>
</interface>
</interfaces>
<socket-bindings default-interface="public" port-offset="${infinispan.socket.binding.port-offset:0}">
<socket-binding name="default" port="${infinispan.bind.port:11222}"/>
</socket-bindings>
<security>
<security-realms>
<security-realm name="default">
<!-- Uncomment to enable TLS on the realm -->
<properties-realm groups-attribute="Roles">
<user-properties path="users.properties" relative-to="infinispan.server.config.path"
plain-text="true"/>
<group-properties path="groups.properties" relative-to="infinispan.server.config.path"/>
</properties-realm>
</security-realm>
</security-realms>
</security>
<data-sources>
<data-source name="KeycloakDS" jndi-name="jdbc/datasource" statistics="true">
<connection-factory driver="org.postgresql.Driver"
username="${env.DB_USERNAME}"
password="${env.DB_PASSWORD}"
url="jdbc:postgresql://${env.DB_HOSTNAME}/${env.DB_DATABASE}?ApplicationName=${env.DB_APP_NAME}"
new-connection-sql="SELECT 1" transaction-isolation="READ_COMMITTED">
</connection-factory>
<connection-pool initial-size="${env.CONN_POOL_INITIAL_SIZE}" max-size="${env.CONN_POOL_MAX_SIZE}" min-size="${env.CONN_POOL_MIN_SIZE}" background-validation="1000" idle-removal="1" blocking-timeout="1000" leak-detection="10000"/>
</data-source>
</data-sources>
<!-- see https://docs.jboss.org/infinispan/14.0/configdocs/infinispan-server-14.0.html#endpoints -->
<endpoints>
<endpoint socket-binding="default" security-realm="default">
<hotrod-connector name="hotrod" security-realm="default"/>
<rest-connector>
<authentication mechanisms="BASIC"/>
</rest-connector>
</endpoint>
</endpoints>
</server>
</infinispan> ``` All referenced environment variables are correctly evaluated at run time. This is the chain of events that we get: ``` POST /admin/realms/foo-realm/authentication/flows/foo-browser-with-product-events-cookie/executions/execution -> 201 created ``` ``` PUT /admin/realms/foo-realm/authentication/flows/foo-browser-with-product-events-cookie/executions -> 404 not found ``` This is the stack trace corresponding to the 404: ``` jakarta.ws.rs.NotFoundException: Illegal execution at org.keycloak.services.resources.admin.AuthenticationManagementResource.updateExecutions(AuthenticationManagementResource.java:721) at org.keycloak.services.resources.admin.AuthenticationManagementResource$quarkusrestinvoker$updateExecutions_1fb26a2fba65839d9e0fe9f9233d954e611af6dd.invoke(Unknown Source) at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29) at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141) at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:840) ``` When this happens, we can see a sudden increase in warning messages from Keycloak, as it is visible from the following logs: ![image|https://github.com/keycloak/keycloak/assets/17787120/0dc4f0c4-67f3-431c-84c4-2b5d28fd06c5] ``` Event object wasn't available in remote cache after event was received. Event key: 4af1c45f-a0ac-4fee-be2e-f8467e73af92 ``` h3. Version 23.0.7 h3. Regression [ ] The issue is a regression h3. Expected behavior The flows and subflows are created according to what is specified in the Terraform file. h3. Actual behavior On subsequent PUT calls, Keycloak returns a 404 error even though the resource was successfully created as the logs provided in the bug description show. h3. How to Reproduce? Apply the provided Terraform file on a Keycloak clustered deployment with an external Infinispan (see provided config files to configure Infinispan and Keycloak). h3. Anything else? If the {{work}} cache is hosted in the embedded cache or we have a single Keycloak node, the Terraform apply runs without any error. See the following config file as a reference for this case: ``` <?xml version="1.0" encoding="UTF-8"?> <infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:14.0 http://www.infinispan.org/schemas/infinispan-config-14.0.xsd"
xmlns="urn:infinispan:config:14.0">
<cache-container name="keycloak">
<transport lock-timeout="60000"/>
<local-cache-configuration name="local-cache-cfg">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
</local-cache-configuration>
<local-cache name="realms" configuration="local-cache-cfg">
<memory max-count="10000"/>
</local-cache>
<local-cache name="users" configuration="local-cache-cfg">
<memory max-count="10000"/>
</local-cache>
<local-cache name="keys" configuration="local-cache-cfg">
<expiration max-idle="3600000"/>
<memory max-count="1000"/>
</local-cache>
<local-cache name="authorization" configuration="local-cache-cfg">
<memory max-count="10000"/>
</local-cache>
<distributed-cache name="authenticationSessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<distributed-cache name="sessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="sessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="clientSessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="clientSessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="offlineSessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="offlineSessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="offlineClientSessions" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="offlineClientSessions"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="loginFailures" owners="2">
<expiration lifespan="-1"/>
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
cache="loginFailures"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<distributed-cache name="actionTokens" owners="2">
<expiration max-idle="-1" lifespan="-1" interval="300000"/>
<memory max-count="-1"/>
<remote-store cache="actionTokens" xmlns="urn:infinispan:config:store:remote:14.0"
purge="false"
preload="false"
shared="true"
segmented="false"
connect-timeout="${env.KEYCLOAK_REMOTE_ISPN_CONN_TIMEOUT:2000}"
raw-values="true"
marshaller="org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory">
<remote-server host="${env.KEYCLOAK_REMOTE_ISPN_HOST}" port="${infinispan.bind.port:11222}"/>
<security>
<authentication>
<digest username="${env.KEYCLOAK_REMOTE_ISPN_USERNAME}"
password="${env.KEYCLOAK_REMOTE_ISPN_PASSWORD}"
realm="default"/>
</authentication>
</security>
</remote-store>
</distributed-cache>
<!-- !!! PLEASE NOTE !!! -->
<!-- WORK CACHE IS NOT REMOTE ANYMORE -->
<replicated-cache name="work">
<expiration lifespan="-1"/>
</replicated-cache>
</cache-container>
</infinispan>
```
- links to