diff --git a/src/main/java/sh/libre/scim/core/GroupScimClient.java b/src/main/java/sh/libre/scim/core/GroupScimClient.java
index 1483d3bda3224292a63889f3971ef2f666623ef6..b4c911d8647f6304387a29930fe2e7c7799c525a 100644
--- a/src/main/java/sh/libre/scim/core/GroupScimClient.java
+++ b/src/main/java/sh/libre/scim/core/GroupScimClient.java
@@ -30,6 +30,11 @@ public class GroupScimClient implements ScimClientInterface<GroupModel> {
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public ScrimProviderConfiguration getConfiguration() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public void close() throws Exception {
         throw new UnsupportedOperationException();
diff --git a/src/main/java/sh/libre/scim/core/ScimClientInterface.java b/src/main/java/sh/libre/scim/core/ScimClientInterface.java
index d28f289faece814412bf2a8e6a6b0f894081010a..5316bf58a5cdc59759b0a7b335b58ad95c381965 100644
--- a/src/main/java/sh/libre/scim/core/ScimClientInterface.java
+++ b/src/main/java/sh/libre/scim/core/ScimClientInterface.java
@@ -39,4 +39,9 @@ public interface ScimClientInterface<M extends RoleMapperModel> extends AutoClos
      * @param result the synchronization result to update for indicating triggered operations (e.g. user deletions)
      */
     void sync(SynchronizationResult result);
+
+    /**
+     * @return the {@link ScrimProviderConfiguration} corresponding to this client.
+     */
+    ScrimProviderConfiguration getConfiguration();
 }
diff --git a/src/main/java/sh/libre/scim/core/ScimDispatcher.java b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
index 3434911014eeb4867818ca52dd9b76544fa45e65..9501586d3ecb88b69df8707e3a69d40b7dd8da35 100644
--- a/src/main/java/sh/libre/scim/core/ScimDispatcher.java
+++ b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
@@ -5,66 +5,97 @@ import org.keycloak.component.ComponentModel;
 import org.keycloak.models.KeycloakSession;
 import sh.libre.scim.storage.ScimStorageProviderFactory;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
 import java.util.function.Consumer;
-import java.util.stream.Stream;
 
 /**
  * In charge of sending SCIM Request to all registered Scim endpoints.
  */
 public class ScimDispatcher {
 
-    private static final Logger LOGGER = Logger.getLogger(ScimDispatcher.class);
+    private static final Logger logger = Logger.getLogger(ScimDispatcher.class);
 
     private final KeycloakSession session;
+    private final List<UserScimClient> userScimClients = new ArrayList<>();
+    private final List<GroupScimClient> groupScimClients = new ArrayList<>();
 
     public ScimDispatcher(KeycloakSession session) {
         this.session = session;
+        refreshActiveScimEndpoints();
     }
 
-    public void dispatchUserModificationToAll(Consumer<UserScimClient> operationToDispatch) {
-        getAllSCIMServer(Scope.USER).forEach(scimServerConfiguration -> dispatchUserModificationToOne(scimServerConfiguration, operationToDispatch));
-    }
+    /**
+     * Lists all active ScimStorageProviderFactory and create new ScimClients for each of them
+     */
+    public void refreshActiveScimEndpoints() {
+        try {
+            // Step 1: close existing clients
+            for (GroupScimClient c : groupScimClients) {
+                c.close();
+            }
+            for (UserScimClient c : userScimClients) {
+                c.close();
+            }
 
-    public void dispatchUserModificationToOne(ComponentModel scimServerConfiguration, Consumer<UserScimClient> operationToDispatch) {
-        LOGGER.infof("%s %s %s %s", scimServerConfiguration.getId(), scimServerConfiguration.getName(), scimServerConfiguration.getProviderId(), scimServerConfiguration.getProviderType());
-        try (UserScimClient client = UserScimClient.newUserScimClient(scimServerConfiguration, session)) {
-            operationToDispatch.accept(client);
+            // Step 2: Get All SCIM endpoints defined in Admin Console (enabled ScimStorageProviderFactory)
+            session.getContext().getRealm().getComponentsStream()
+                    .filter(m -> ScimStorageProviderFactory.ID.equals(m.getProviderId())
+                                 && m.get("enabled", true))
+                    .forEach(scimEndpoint -> {
+                        // Step 3 : create scim clients for each endpoint
+                        if (scimEndpoint.get(ScrimProviderConfiguration.CONF_KEY_PROPAGATION_GROUP, false)) {
+                            GroupScimClient groupScimClient = GroupScimClient.newGroupScimClient(scimEndpoint, session);
+                            groupScimClients.add(groupScimClient);
+                        }
+                        if (scimEndpoint.get(ScrimProviderConfiguration.CONF_KEY_PROPAGATION_USER, false)) {
+                            UserScimClient userScimClient = UserScimClient.newUserScimClient(scimEndpoint, session);
+                            userScimClients.add(userScimClient);
+                        }
+                    });
         } catch (Exception e) {
-            LOGGER.error(e);
+            logger.error("[SCIM] Error while refreshing scim clients ", e);
+            // TODO : how to handle exception here ?
         }
     }
 
+    public void dispatchUserModificationToAll(Consumer<UserScimClient> operationToDispatch) {
+        // TODO should not be required to launch a refresh here : we should refresh clients only if an endpoint configuration changes
+        refreshActiveScimEndpoints();
+        userScimClients.forEach(operationToDispatch);
+    }
+
     public void dispatchGroupModificationToAll(Consumer<GroupScimClient> operationToDispatch) {
-        getAllSCIMServer(Scope.GROUP).forEach(scimServerConfiguration -> dispatchGroupModificationToOne(scimServerConfiguration, operationToDispatch));
+        // TODO should not be required to launch a refresh here : we should refresh clients only if an endpoint configuration changes
+        refreshActiveScimEndpoints();
+        groupScimClients.forEach(operationToDispatch);
     }
 
-    public void dispatchGroupModificationToOne(ComponentModel scimServerConfiguration, Consumer<GroupScimClient> operationToDispatch) {
-        LOGGER.infof("%s %s %s %s", scimServerConfiguration.getId(), scimServerConfiguration.getName(), scimServerConfiguration.getProviderId(), scimServerConfiguration.getProviderType());
-        try (GroupScimClient client = GroupScimClient.newGroupScimClient(scimServerConfiguration, session)) {
-            operationToDispatch.accept(client);
-        } catch (Exception e) {
-            LOGGER.error(e);
+    public void dispatchUserModificationToOne(ComponentModel scimServerConfiguration, Consumer<UserScimClient> operationToDispatch) {
+        // TODO should not be required to launch a refresh here : we should refresh clients only if an endpoint configuration changes
+        refreshActiveScimEndpoints();
+
+        // Scim client should already have been created
+        Optional<UserScimClient> matchingClient = userScimClients.stream().filter(u -> u.getConfiguration().getId().equals(scimServerConfiguration.getId())).findFirst();
+        if (matchingClient.isPresent()) {
+            operationToDispatch.accept(matchingClient.get());
+        } else {
+            logger.error("[SCIM] Could not find a Scim Client matching endpoint configuration" + scimServerConfiguration.getId());
         }
     }
 
-    /**
-     * @param scope The {@link Scope} to consider (User or Group)
-     * @return all enabled registered Scim endpoints with propagation enabled for the given scope
-     */
-    private Stream<ComponentModel> getAllSCIMServer(Scope scope) {
-        // TODO : we could initiative this list once and invalidate it when configuration changes
 
-        String propagationConfKey = switch (scope) {
-            case GROUP -> ScrimProviderConfiguration.CONF_KEY_PROPAGATION_GROUP;
-            case USER -> ScrimProviderConfiguration.CONF_KEY_PROPAGATION_USER;
-        };
-        return session.getContext().getRealm().getComponentsStream()
-                .filter(m -> ScimStorageProviderFactory.ID.equals(m.getProviderId())
-                             && m.get("enabled", true)
-                             && m.get(propagationConfKey, false));
-    }
+    public void dispatchGroupModificationToOne(ComponentModel scimServerConfiguration, Consumer<GroupScimClient> operationToDispatch) {
+        // TODO should not be required to launch a refresh here : we should refresh clients only if an endpoint configuration changes
+        refreshActiveScimEndpoints();
 
-    public enum Scope {
-        USER, GROUP
+        // Scim client should already have been created
+        Optional<GroupScimClient> matchingClient = groupScimClients.stream().filter(u -> u.getConfiguration().getId().equals(scimServerConfiguration.getId())).findFirst();
+        if (matchingClient.isPresent()) {
+            operationToDispatch.accept(matchingClient.get());
+        } else {
+            logger.error("[SCIM] Could not find a Scim Client matching endpoint configuration" + scimServerConfiguration.getId());
+        }
     }
 }
diff --git a/src/main/java/sh/libre/scim/core/UserScimClient.java b/src/main/java/sh/libre/scim/core/UserScimClient.java
index 4f257a0fca661b6f027f4d6c24fb5f99f9a97cf5..8d2f25279b291f7143e5fadff98dd2c3f68112a0 100644
--- a/src/main/java/sh/libre/scim/core/UserScimClient.java
+++ b/src/main/java/sh/libre/scim/core/UserScimClient.java
@@ -275,6 +275,11 @@ public class UserScimClient implements ScimClientInterface<UserModel> {
         }
     }
 
+    @Override
+    public ScrimProviderConfiguration getConfiguration() {
+        return this.scimProviderConfiguration;
+    }
+
 
     @Override
     public void close() {