From a53eab24e5a8938a34563a74ef350c9713d4638e Mon Sep 17 00:00:00 2001
From: Martin Weise <martin.weise@tuwien.ac.at>
Date: Wed, 12 Feb 2025 09:10:33 +0100
Subject: [PATCH] Updated the listener

Signed-off-by: Martin Weise <martin.weise@tuwien.ac.at>
---
 dbrepo-auth-service/dbrepo-realm.json         |    2 +-
 dbrepo-auth-service/listeners/.gitignore      |   30 +
 dbrepo-auth-service/listeners/pom.xml         |  111 +
 .../src/main/java/at/tuwien/Client.java       |   65 +
 .../tuwien/CreateEventListenerProvider.java   |  133 +
 .../CreateEventListenerProviderFactory.java   |   36 +
 .../META-INF/jboss-deployment-structure.xml   |    8 +
 ...ycloak.events.EventListenerProviderFactory |    1 +
 .../tuwien/EventListenerIntegrationTest.java  |   18 +
 .../src/test/resources/dbrepo-realm.json      | 2798 +++++++++++++++++
 .../target/create-event-listener.jar          |  Bin 0 -> 10130 bytes
 .../at/tuwien/api/auth/CreateUserDto.java     |   46 +
 .../DbrepoMetadataServiceApplication.java     |    2 -
 .../at/tuwien/endpoints/UserEndpoint.java     |   57 +
 .../java/at/tuwien/utils/KeycloakUtils.java   |    9 -
 .../java/at/tuwien/config/KeycloakConfig.java |   14 +-
 .../at/tuwien/listener/KeycloakListener.java  |    5 -
 .../listener/impl/KeycloakListenerImpl.java   |   66 -
 .../java/at/tuwien/service/UserService.java   |   10 +
 .../tuwien/service/impl/UserServiceImpl.java  |   28 +-
 dbrepo-ui/layouts/default.vue                 |    3 -
 dbrepo-ui/pages/user/info.vue                 |   10 +-
 docker-compose.yml                            |    4 +
 helm/dbrepo/files/create-event-listener.jar   |  Bin 0 -> 10130 bytes
 helm/dbrepo/templates/auth-configmap.yaml     |    5 +-
 make/build.mk                                 |    4 +
 make/dev.mk                                   |    2 +-
 27 files changed, 3358 insertions(+), 109 deletions(-)
 create mode 100644 dbrepo-auth-service/listeners/.gitignore
 create mode 100644 dbrepo-auth-service/listeners/pom.xml
 create mode 100644 dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java
 create mode 100644 dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java
 create mode 100644 dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProviderFactory.java
 create mode 100644 dbrepo-auth-service/listeners/src/main/resources/META-INF/jboss-deployment-structure.xml 
 create mode 100644 dbrepo-auth-service/listeners/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory
 create mode 100644 dbrepo-auth-service/listeners/src/test/java/at/tuwien/EventListenerIntegrationTest.java
 create mode 100644 dbrepo-auth-service/listeners/src/test/resources/dbrepo-realm.json
 create mode 100644 dbrepo-auth-service/listeners/target/create-event-listener.jar
 create mode 100644 dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java
 delete mode 100644 dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/KeycloakListener.java
 delete mode 100644 dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/KeycloakListenerImpl.java
 create mode 100644 helm/dbrepo/files/create-event-listener.jar

diff --git a/dbrepo-auth-service/dbrepo-realm.json b/dbrepo-auth-service/dbrepo-realm.json
index 2dd2aa7cea..1c703b8375 100644
--- a/dbrepo-auth-service/dbrepo-realm.json
+++ b/dbrepo-auth-service/dbrepo-realm.json
@@ -2328,7 +2328,7 @@
   "adminTheme" : "",
   "emailTheme" : "",
   "eventsEnabled" : false,
-  "eventsListeners" : [ "jboss-logging" ],
+  "eventsListeners" : [ "create-event-listener", "jboss-logging" ],
   "enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_CONSENT_ERROR", "GRANT_CONSENT", "VERIFY_PROFILE_ERROR", "REMOVE_TOTP", "REVOKE_GRANT", "UPDATE_TOTP", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", "RESTART_AUTHENTICATION", "IMPERSONATE", "UPDATE_PROFILE_ERROR", "LOGIN", "OAUTH2_DEVICE_VERIFY_USER_CODE", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "TOKEN_EXCHANGE", "AUTHREQID_TO_TOKEN", "LOGOUT", "REGISTER", "DELETE_ACCOUNT_ERROR", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "DELETE_ACCOUNT", "UPDATE_PASSWORD", "CLIENT_DELETE", "FEDERATED_IDENTITY_LINK_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN", "CLIENT_DELETE_ERROR", "VERIFY_EMAIL", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "EXECUTE_ACTIONS", "REMOVE_FEDERATED_IDENTITY_ERROR", "TOKEN_EXCHANGE_ERROR", "PERMISSION_TOKEN", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "SEND_VERIFY_EMAIL", "OAUTH2_DEVICE_AUTH", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "OAUTH2_DEVICE_CODE_TO_TOKEN", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "EXECUTE_ACTION_TOKEN", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "CLIENT_UPDATE_ERROR", "AUTHREQID_TO_TOKEN_ERROR", "UPDATE_PROFILE", "CLIENT_REGISTER_ERROR", "FEDERATED_IDENTITY_LINK", "SEND_IDENTITY_PROVIDER_LINK", "SEND_VERIFY_EMAIL_ERROR", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "OAUTH2_DEVICE_AUTH_ERROR", "UPDATE_CONSENT", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "CUSTOM_REQUIRED_ACTION_ERROR", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "VERIFY_PROFILE", "GRANT_CONSENT_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ],
   "adminEventsEnabled" : false,
   "adminEventsDetailsEnabled" : false,
diff --git a/dbrepo-auth-service/listeners/.gitignore b/dbrepo-auth-service/listeners/.gitignore
new file mode 100644
index 0000000000..5d6e1ae3b1
--- /dev/null
+++ b/dbrepo-auth-service/listeners/.gitignore
@@ -0,0 +1,30 @@
+### IntelliJ IDEA ###
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+target/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/dbrepo-auth-service/listeners/pom.xml b/dbrepo-auth-service/listeners/pom.xml
new file mode 100644
index 0000000000..e70201b96a
--- /dev/null
+++ b/dbrepo-auth-service/listeners/pom.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.keycloak</groupId>
+        <artifactId>keycloak-parent</artifactId>
+        <version>24.0.5</version>
+    </parent>
+
+    <groupId>at.tuwien</groupId>
+    <artifactId>create-event-listener</artifactId>
+    <name>dbrepo-auth-service</name>
+    <version>24.0.5</version>
+
+    <description>Create event listener</description>
+
+    <url>https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/</url>
+    <developers>
+        <developer>
+            <name>Martin Weise</name>
+            <email>martin.weise@tuwien.ac.at</email>
+            <organization>TU Wien</organization>
+        </developer>
+    </developers>
+
+    <properties>
+        <java.version>17</java.version>
+        <maven.version>3.9.8</maven.version>
+        <maven.compiler.source>${java.version}</maven.compiler.source>
+        <maven.compiler.target>${java.version}</maven.compiler.target>
+        <maven.compiler.release>${java.version}</maven.compiler.release>
+        <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
+        <testcontainers.version>1.19.1</testcontainers.version>
+        <keycloak-testcontainer.version>3.2.0</keycloak-testcontainer.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-spi</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-spi-private</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-services</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-saml-core-public</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.spec.javax.ws.rs</groupId>
+            <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
+        </dependency>
+        <!-- Tests -->
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>${testcontainers.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.dasniko</groupId>
+            <artifactId>testcontainers-keycloak</artifactId>
+            <version>${keycloak-testcontainer.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>create-event-listener</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.wildfly.plugins</groupId>
+                <artifactId>wildfly-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java
new file mode 100644
index 0000000000..769ec49097
--- /dev/null
+++ b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java
@@ -0,0 +1,65 @@
+package at.tuwien;
+
+import org.jboss.logging.Logger;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Base64;
+
+public class Client {
+    private static final Logger log = Logger.getLogger(Client.class);
+
+    public static void postService(String data) throws IOException {
+        try {
+            final String urlString = System.getenv("METADATA_SERVICE_ENDPOINT");
+            log.debugf("METADATA_SERVICE_ENDPOINT: %s", urlString);
+            if (urlString == null || urlString.isEmpty()) {
+                throw new IllegalArgumentException("Environment variable METADATA_SERVICE_ENDPOINT is not set or is empty.");
+            }
+            final String systemUsername = System.getenv("SYSTEM_USERNAME");
+            if (systemUsername == null || systemUsername.isEmpty()) {
+                throw new IllegalArgumentException("Environment variable SYSTEM_USERNAME is not set or is empty.");
+            }
+            log.debugf("SYSTEM_USERNAME: %s", systemUsername);
+            final String systemPassword = System.getenv("SYSTEM_PASSWORD");
+            if (systemPassword == null || systemPassword.isEmpty()) {
+                throw new IllegalArgumentException("Environment variable SYSTEM_PASSWORD is not set or is empty.");
+            }
+
+            URL url = URI.create(urlString).toURL();
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setDoOutput(true);
+            conn.setRequestMethod("POST");
+            final String token = systemUsername + ":" + systemPassword;
+            conn.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString(token.getBytes(
+                    Charset.defaultCharset())));
+            conn.setRequestProperty("Content-Type", "application/json; utf-8");
+
+            OutputStream os = conn.getOutputStream();
+            os.write(data.getBytes());
+            os.flush();
+
+            final int responseCode = conn.getResponseCode();
+            if (responseCode != HttpURLConnection.HTTP_CREATED && responseCode != HttpURLConnection.HTTP_OK) {
+                throw new RuntimeException("Failed : HTTP error code : " + responseCode);
+            }
+
+            final BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String output;
+            log.debugf("Output from Server .... \n");
+            while ((output = br.readLine()) != null) {
+                System.out.println(output);
+                log.debugf("Input from Server: %s", output);
+            }
+            conn.disconnect();
+        } catch (IOException e) {
+            throw new IOException("Failed to post service: " + e.getMessage(), e);
+        }
+    }
+}
diff --git a/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java
new file mode 100644
index 0000000000..93f2b2919b
--- /dev/null
+++ b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java
@@ -0,0 +1,133 @@
+package at.tuwien;
+
+import org.jboss.logging.Logger;
+import org.keycloak.events.Event;
+import org.keycloak.events.EventListenerProvider;
+import org.keycloak.events.EventType;
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.OperationType;
+import org.keycloak.events.admin.ResourceType;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RealmProvider;
+import org.keycloak.models.UserModel;
+
+import java.util.StringJoiner;
+
+public class CreateEventListenerProvider implements EventListenerProvider {
+
+    private static final Logger log = Logger.getLogger(CreateEventListenerProvider.class);
+
+    private final KeycloakSession session;
+    private final RealmProvider model;
+
+    public CreateEventListenerProvider(KeycloakSession session) {
+        this.session = session;
+        this.model = session.realms();
+    }
+
+    @Override
+    public void onEvent(Event event) {
+        if (EventType.REGISTER.equals(event.getType()) || EventType.IDENTITY_PROVIDER_FIRST_LOGIN.equals(event.getType())) {
+            event.getDetails().forEach((key, value) -> log.debugf("%s : %s", key, value));
+            RealmModel realm = this.model.getRealm(event.getRealmId());
+            UserModel user = this.session.users().getUserById(realm, event.getUserId());
+            sendUserData(user);
+        }
+
+    }
+
+    @Override
+    public void onEvent(AdminEvent adminEvent, boolean b) {
+        log.debug("onEvent(AdminEvent)");
+        log.debugf("Resource path: %s", adminEvent.getResourcePath());
+        log.debugf("Resource type: %s", adminEvent.getResourceType());
+        log.debugf("Operation type: %s", adminEvent.getOperationType());
+        log.debugf("AdminEvent.toString(): %s", toString(adminEvent));
+        if (ResourceType.USER.equals(adminEvent.getResourceType())
+                && OperationType.CREATE.equals(adminEvent.getOperationType())) {
+            RealmModel realm = this.model.getRealm(adminEvent.getRealmId());
+            UserModel user = this.session.users().getUserById(realm, adminEvent.getResourcePath().substring(6));
+
+            sendUserData(user);
+        }
+    }
+
+    private void sendUserData(UserModel user) {
+        final String userData = "{" +
+                quoteAttr("id", user.getId()) + ", " +
+                quoteAttr("username", user.getUsername()) + ", " +
+                quoteAttr("email", user.getEmail()) + ", " +
+                quoteAttr("ldap_id", user.getFirstAttribute("LDAP_ID")) + ", " +
+                quoteAttr("given_name", user.getFirstName()) + ", " +
+                quoteAttr("family_name", user.getLastName()) +
+                "}";
+        try {
+            log.debugf("create new user in API: %s", userData);
+            Client.postService(userData);
+        } catch (Exception e) {
+            log.errorf("Failed to call API: %s", e);
+        }
+    }
+
+    private static String quoteAttr(String key, String value) {
+        if (value == null || value.isBlank() || value.isEmpty() || value.contentEquals(" ")) {
+            return "\"" + key + "\": null";
+        }
+        return "\"" + key + "\": \"" + value + "\"";
+    }
+
+    @Override
+    public void close() {
+    }
+
+    private String toString(Event event) {
+        final StringJoiner joiner = new StringJoiner(", ");
+        joiner.add("type=" + event.getType())
+                .add("realmId=" + event.getRealmId())
+                .add("clientId=" + event.getClientId())
+                .add("userId=" + event.getUserId())
+                .add("ipAddress=" + event.getIpAddress());
+        if (event.getError() != null) {
+            joiner.add("error=" + event.getError());
+        }
+        if (event.getDetails() != null) {
+            event.getDetails().forEach((key, value) -> {
+                if (value == null || !value.contains(" ")) {
+                    joiner.add(key + "=" + value);
+                } else {
+                    joiner.add(key + "='" + value + "'");
+                }
+            });
+        }
+        return joiner.toString();
+    }
+
+    private String toString(AdminEvent event) {
+        RealmModel realm = this.model.getRealm(event.getRealmId());
+        UserModel newRegisteredUser = this.session.users().getUserById(realm, event.getAuthDetails().getUserId());
+
+        StringJoiner joiner = new StringJoiner(", ");
+
+        joiner.add("operationType=" + event.getOperationType())
+                .add("realmId=" + event.getAuthDetails().getRealmId())
+                .add("clientId=" + event.getAuthDetails().getClientId())
+                .add("userId=" + event.getAuthDetails().getUserId());
+
+        if (newRegisteredUser != null) {
+            joiner.add("email=" + newRegisteredUser.getEmail())
+                    .add("username=" + newRegisteredUser.getUsername())
+                    .add("firstName=" + newRegisteredUser.getFirstName())
+                    .add("lastName=" + newRegisteredUser.getLastName());
+        }
+
+        joiner.add("ipAddress=" + event.getAuthDetails().getIpAddress())
+                .add("resourcePath=" + event.getResourcePath());
+
+        if (event.getError() != null) {
+            joiner.add("error=" + event.getError());
+        }
+
+        return joiner.toString();
+    }
+}
diff --git a/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProviderFactory.java b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProviderFactory.java
new file mode 100644
index 0000000000..61477ffa33
--- /dev/null
+++ b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProviderFactory.java
@@ -0,0 +1,36 @@
+package at.tuwien;
+
+import org.keycloak.Config;
+import org.keycloak.events.EventListenerProvider;
+import org.keycloak.events.EventListenerProviderFactory;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+
+public class CreateEventListenerProviderFactory implements EventListenerProviderFactory {
+
+    @Override
+    public EventListenerProvider create(KeycloakSession keycloakSession) {
+        return new CreateEventListenerProvider(keycloakSession);
+    }
+
+    @Override
+    public void init(Config.Scope scope) {
+
+    }
+
+    @Override
+    public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
+
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public String getId() {
+        return "create-event-listener";
+    }
+
+}
diff --git a/dbrepo-auth-service/listeners/src/main/resources/META-INF/jboss-deployment-structure.xml  b/dbrepo-auth-service/listeners/src/main/resources/META-INF/jboss-deployment-structure.xml 
new file mode 100644
index 0000000000..c0330ba082
--- /dev/null
+++ b/dbrepo-auth-service/listeners/src/main/resources/META-INF/jboss-deployment-structure.xml 	
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jboss-deployment-structure>
+    <deployment>
+        <dependencies>
+            <module name="org.keycloak.keycloak-services" />
+        </dependencies>
+    </deployment>
+</jboss-deployment-structure>
\ No newline at end of file
diff --git a/dbrepo-auth-service/listeners/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory b/dbrepo-auth-service/listeners/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory
new file mode 100644
index 0000000000..df3c5521f0
--- /dev/null
+++ b/dbrepo-auth-service/listeners/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory
@@ -0,0 +1 @@
+at.tuwien.CreateEventListenerProviderFactory
\ No newline at end of file
diff --git a/dbrepo-auth-service/listeners/src/test/java/at/tuwien/EventListenerIntegrationTest.java b/dbrepo-auth-service/listeners/src/test/java/at/tuwien/EventListenerIntegrationTest.java
new file mode 100644
index 0000000000..c3d6ee94cc
--- /dev/null
+++ b/dbrepo-auth-service/listeners/src/test/java/at/tuwien/EventListenerIntegrationTest.java
@@ -0,0 +1,18 @@
+package at.tuwien;
+
+import dasniko.testcontainers.keycloak.KeycloakContainer;
+import org.testcontainers.images.PullPolicy;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+@Testcontainers
+public class EventListenerIntegrationTest {
+
+    @Container
+    private static KeycloakContainer keycloakContainer = new KeycloakContainer("quay.io/keycloak/keycloak:24.0")
+            .withImagePullPolicy(PullPolicy.alwaysPull())
+            .withAdminUsername("admin")
+            .withAdminPassword("admin")
+            .withRealmImportFile("dbrepo-realm.json")
+            .withEnv("KC_HOSTNAME_STRICT_HTTPS", "false");
+}
diff --git a/dbrepo-auth-service/listeners/src/test/resources/dbrepo-realm.json b/dbrepo-auth-service/listeners/src/test/resources/dbrepo-realm.json
new file mode 100644
index 0000000000..56f2003e96
--- /dev/null
+++ b/dbrepo-auth-service/listeners/src/test/resources/dbrepo-realm.json
@@ -0,0 +1,2798 @@
+{
+  "id" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+  "realm" : "dbrepo",
+  "notBefore" : 0,
+  "defaultSignatureAlgorithm" : "RS256",
+  "revokeRefreshToken" : false,
+  "refreshTokenMaxReuse" : 1,
+  "accessTokenLifespan" : 900,
+  "accessTokenLifespanForImplicitFlow" : 900,
+  "ssoSessionIdleTimeout" : 864000,
+  "ssoSessionMaxLifespan" : 2592000,
+  "ssoSessionIdleTimeoutRememberMe" : 0,
+  "ssoSessionMaxLifespanRememberMe" : 0,
+  "offlineSessionIdleTimeout" : 2592000,
+  "offlineSessionMaxLifespanEnabled" : false,
+  "offlineSessionMaxLifespan" : 5184000,
+  "clientSessionIdleTimeout" : 0,
+  "clientSessionMaxLifespan" : 0,
+  "clientOfflineSessionIdleTimeout" : 0,
+  "clientOfflineSessionMaxLifespan" : 0,
+  "accessCodeLifespan" : 60,
+  "accessCodeLifespanUserAction" : 300,
+  "accessCodeLifespanLogin" : 1800,
+  "actionTokenGeneratedByAdminLifespan" : 43200,
+  "actionTokenGeneratedByUserLifespan" : 1800,
+  "oauth2DeviceCodeLifespan" : 600,
+  "oauth2DevicePollingInterval" : 5,
+  "enabled" : true,
+  "sslRequired" : "none",
+  "registrationAllowed" : false,
+  "registrationEmailAsUsername" : false,
+  "rememberMe" : false,
+  "verifyEmail" : true,
+  "loginWithEmailAllowed" : false,
+  "duplicateEmailsAllowed" : false,
+  "resetPasswordAllowed" : false,
+  "editUsernameAllowed" : false,
+  "bruteForceProtected" : false,
+  "permanentLockout" : false,
+  "maxTemporaryLockouts" : 0,
+  "maxFailureWaitSeconds" : 900,
+  "minimumQuickLoginWaitSeconds" : 60,
+  "waitIncrementSeconds" : 60,
+  "quickLoginCheckMilliSeconds" : 1000,
+  "maxDeltaTimeSeconds" : 43200,
+  "failureFactor" : 30,
+  "roles" : {
+    "realm" : [ {
+      "id" : "48f38342-1e3f-427a-995d-c436eaee65cb",
+      "name" : "default-user-handling",
+      "description" : "${default-user-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "modify-user-theme", "modify-user-information" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "9bb4a8dc-28e0-4645-b62f-cc94425f0cb0",
+      "name" : "default-maintenance-handling",
+      "description" : "${default-maintenance-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "create-maintenance-message", "find-maintenance-message", "update-maintenance-message", "delete-maintenance-message", "list-maintenance-messages" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "7ee1c424-11b0-46a9-b0ed-725e9b7fc40c",
+      "name" : "default-system-roles",
+      "description" : "${default-system-roles}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "delete-database-view", "update-semantic-unit", "export-query-data", "default-data-steward-roles", "execute-query", "default-user-handling", "delete-table-data", "find-query", "list-database-views", "persist-query", "update-search-index", "delete-database-access", "view-table-history", "create-ontology", "update-ontology", "modify-user-theme", "default-system-roles", "create-semantic-concept", "default-container-handling", "create-container", "create-table", "default-broker-handling", "default-maintenance-handling", "execute-semantic-query", "uma_authorization", "table-semantic-analyse", "list-containers", "check-database-access", "escalated-query-handling", "delete-identifier", "modify-database-owner", "list-tables", "export-table-data", "create-database-access", "delete-container", "re-execute-query", "create-semantic-unit", "escalated-identifier-handling", "system", "update-table-statistic", "escalated-semantics-handling", "default-database-handling", "delete-ontology", "find-database", "find-database-view", "update-semantic-concept", "find-user", "import-database-data", "publish-identifier", "default-roles-dbrepo", "find-foreign-user", "create-database", "create-maintenance-message", "find-maintenance-message", "escalated-container-handling", "default-researcher-roles", "default-identifier-handling", "escalated-user-handling", "modify-user-information", "create-database-view", "update-maintenance-message", "delete-foreign-table", "offline_access", "modify-foreign-table-column-semantics", "delete-maintenance-message", "find-container", "insert-table-data", "modify-identifier-metadata", "modify-database-image", "escalated-broker-handling", "modify-table-column-semantics", "escalated-database-handling", "default-semantics-handling", "update-database-access", "default-query-handling", "find-table", "list-queries", "default-developer-roles", "create-identifier", "escalated-table-handling", "find-identifier", "view-table-data", "list-licenses", "default-table-handling", "list-identifiers", "create-foreign-identifier", "list-databases", "list-ontologies", "modify-database-visibility", "list-maintenance-messages", "delete-table" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "143ba359-5fa2-451e-8296-43ecf20bb251",
+      "name" : "update-semantic-concept",
+      "description" : "${update-semantic-concept}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "5136d7a3-e3f0-4585-bacd-15cb8a56095c",
+      "name" : "escalated-container-handling",
+      "description" : "${escalated-container-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "create-container", "delete-container" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "b0bc8649-7d84-4dd3-84f0-7f174425babe",
+      "name" : "list-tables",
+      "description" : "${list-tables}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "bfd85d9c-2772-4660-a8f0-cdc0cd8252b3",
+      "name" : "default-database-handling",
+      "description" : "${default-database-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "modify-database-image", "modify-database-owner", "update-database-access", "create-database", "list-databases", "create-database-access", "find-database", "modify-database-visibility", "import-database-data", "delete-database-access", "check-database-access" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "74648f9a-777e-4ef9-b97b-4c5d749d862f",
+      "name" : "update-search-index",
+      "description" : "${update-search-index}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "22492b64-c633-48a0-9678-b28669f2885b",
+      "name" : "execute-semantic-query",
+      "description" : "${execute-semantic-query}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "4ed919fa-edc5-44e5-9411-607786e4a86d",
+      "name" : "view-table-history",
+      "description" : "${view-table-history}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "d89a2881-b642-4abb-b990-196e71372f6b",
+      "name" : "default-table-handling",
+      "description" : "${default-table-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "modify-table-column-semantics", "list-tables", "update-table-statistic", "find-table", "create-table", "delete-table" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "b0d66d3d-59b4-4aae-aa66-e3d5a49f28e3",
+      "name" : "view-database-view-data",
+      "description" : "${view-database-view-data}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "f5ea431a-9b2c-4195-bcb4-9511f38e4b44",
+      "name" : "create-database-view",
+      "description" : "${create-database-view}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "a5ffc20e-8b11-498c-9f3b-b5740aec24c7",
+      "name" : "default-semantics-handling",
+      "description" : "${default-semantics-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "create-semantic-unit", "create-semantic-concept", "execute-semantic-query", "table-semantic-analyse" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "fe4a01f3-6590-4df6-9ade-5a9c1fae4736",
+      "name" : "create-semantic-unit",
+      "description" : "${create-semantic-unit}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "0e12eedf-545d-4d32-ac4d-2821dcb118b8",
+      "name" : "update-table-statistic",
+      "description" : "${update-table-statistic}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e63e61a2-d852-4ad3-bfb5-92d9ceafef6a",
+      "name" : "escalated-user-handling",
+      "description" : "${escalated-user-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "find-user" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "be4e1aba-e276-4241-b6ea-01dce6c52f8b",
+      "name" : "find-container",
+      "description" : "${find-container}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "3a801b48-f3c2-4bc6-aa25-c7a91d5b32a7",
+      "name" : "default-researcher-roles",
+      "description" : "${default-researcher-roles}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "default-table-handling", "default-semantics-handling", "default-container-handling", "default-query-handling", "default-user-handling", "default-database-handling", "default-broker-handling", "default-identifier-handling" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "3d8104fb-8307-40f0-b4b2-c3e518957110",
+      "name" : "view-table-data",
+      "description" : "${view-table-data}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "fe71b907-7020-44ab-9964-da2b87264582",
+      "name" : "create-database",
+      "description" : "${create-database}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e51b63c2-48dd-4bd6-95fb-d257d21b26ba",
+      "name" : "import-database-data",
+      "description" : "${import-database-data}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "1f0a9b13-c2b8-474c-bc08-59dbd71835a6",
+      "name" : "modify-database-image",
+      "description" : "${modify-database-image}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "a7ad038c-5c06-42fc-951c-15ac09d4df66",
+      "name" : "modify-database-owner",
+      "description" : "${modify-database-owner}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "c12c1f4e-186f-4153-a795-26e79fb623d6",
+      "name" : "create-ontology",
+      "description" : "${create-ontology}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "b60a5694-4099-4f7d-a7e9-4c433e0eb9c9",
+      "name" : "update-semantic-unit",
+      "description" : "${update-semantic-unit}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e9854bbb-4580-4757-b1ae-305934173249",
+      "name" : "create-database-access",
+      "description" : "${create-database-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "50c604c1-7c6e-43f3-9c43-2398f5eff66e",
+      "name" : "list-databases",
+      "description" : "${list-databases}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "535f1484-4514-4d24-8d97-e3f6c11a426b",
+      "name" : "create-container",
+      "description" : "${create-container}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "f4116230-8642-4bb7-bbc8-db9c5c07b558",
+      "name" : "create-maintenance-message",
+      "description" : "${create-maintenance-message}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "973f0999-cc70-4b28-9f43-979c470bea8e",
+      "name" : "default-data-steward-roles",
+      "description" : "${default-data-steward-roles}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "escalated-identifier-handling", "default-semantics-handling", "escalated-semantics-handling", "default-user-handling" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e1383fb7-d54c-4732-9146-93030eb2ca50",
+      "name" : "escalated-query-handling",
+      "description" : "${escalated-query-handling}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "993b5c69-9eb2-42af-ac28-b4a46c6b61f2",
+      "name" : "find-user",
+      "description" : "${find-user}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e4cfdc4d-2373-477b-a8df-161db99aba00",
+      "name" : "create-foreign-identifier",
+      "description" : "${create-foreign-identifier}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "6a5872a5-2b51-415d-ae2d-25a6db4a35df",
+      "name" : "escalated-semantics-handling",
+      "description" : "${escalated-semantics-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "update-semantic-unit", "create-ontology", "update-ontology", "list-ontologies", "delete-ontology", "modify-foreign-table-column-semantics", "update-semantic-concept" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "09147c48-273b-450b-8b11-7ef9b9245244",
+      "name" : "export-table-data",
+      "description" : "${export-table-data}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "d14af590-60a8-4d75-b864-40ee0165bd7f",
+      "name" : "delete-database-access",
+      "description" : "${delete-database-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "be051d45-cd74-4b13-8a45-f2d3351bd995",
+      "name" : "table-semantic-analyse",
+      "description" : "${table-semantic-analyse}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "272a79a7-e282-4261-8f7d-5d5d1364243a",
+      "name" : "update-maintenance-message",
+      "description" : "${update-maintenance-message}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "64c16bfb-2015-48ad-a23f-637ff24419cb",
+      "name" : "default-query-handling",
+      "description" : "${default-query-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "delete-database-view", "export-query-data", "execute-query", "delete-table-data", "export-table-data", "list-queries", "find-query", "list-database-views", "persist-query", "view-table-data", "re-execute-query", "view-table-history", "create-database-view", "find-database-view", "insert-table-data" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "c047d521-cec3-4444-86c4-aef098489b7b",
+      "name" : "delete-maintenance-message",
+      "description" : "${delete-maintenance-message}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "88f82262-be80-4d18-9fb4-5529da031f33",
+      "name" : "system",
+      "description" : "${system}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e14ab76b-1c24-484d-ae2d-478b8457edea",
+      "name" : "list-licenses",
+      "description" : "${list-licenses}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "d4f29937-3ca0-41e9-9786-2b7b921b6cdd",
+      "name" : "modify-foreign-table-column-semantics",
+      "description" : "${modify-foreign-table-column-semantics}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "8eda9f5c-938c-4915-bed5-6a81a1de15a8",
+      "name" : "list-database-views",
+      "description" : "${list-database-views}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "b372f8f7-d203-4293-b991-ad93fb505917",
+      "name" : "escalated-database-handling",
+      "description" : "${escalated-database-handling}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "abd2d9ee-ebc4-4d0a-839e-6b588a6d442a",
+      "name" : "default-roles-dbrepo",
+      "description" : "${role_default-roles}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "3293799a-82b9-4f47-8f25-1aad2e0222fd",
+      "name" : "find-identifier",
+      "description" : "${find-identifier}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "aaa3f804-38a0-4474-b8e9-f1020c4b3f62",
+      "name" : "list-queries",
+      "description" : "${list-queries}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "76e38f7b-99bf-4d12-8d74-1c7d8812f443",
+      "name" : "update-ontology",
+      "description" : "${update-ontology}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "11f7973e-d1eb-42cb-a35d-c59dfc122775",
+      "name" : "modify-user-theme",
+      "description" : "${modify-user-theme}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "f392bfcb-0be5-4fad-9ce4-8ac6396f176d",
+      "name" : "export-query-data",
+      "description" : "${export-query-data}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "da493b7e-fb9b-43ca-82a5-e274ad2e6b39",
+      "name" : "find-query",
+      "description" : "${find-query}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "a4d4a788-ebcf-4d32-baed-4a85616ca037",
+      "name" : "escalated-identifier-handling",
+      "description" : "${escalated-identifier-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "create-foreign-identifier", "modify-identifier-metadata" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "ea38d69d-17b8-4c65-95e8-1c3501b83618",
+      "name" : "default-container-handling",
+      "description" : "${default-container-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "find-container", "list-containers" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "8b8813e0-af07-4d04-a8c1-e3f37192bace",
+      "name" : "publish-identifier",
+      "description" : "${publish-identifier}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "47f5eee7-9821-4bf8-b434-0da1f81c3e5a",
+      "name" : "default-broker-handling",
+      "description" : "${default-broker-handling}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "71874bde-64a5-4a69-8685-d8998303a80c",
+      "name" : "delete-table-data",
+      "description" : "${delete-table-data}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "7c0306fc-3b03-4c64-87d1-9a34f2073977",
+      "name" : "modify-table-column-semantics",
+      "description" : "${modify-table-column-semantics}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "cd0ee04c-4a5e-4035-a11b-f6a1165f7829",
+      "name" : "delete-container",
+      "description" : "${delete-container}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "67ee39c0-d601-4a67-a0fe-c4f0021d557e",
+      "name" : "list-containers",
+      "description" : "${list-containers}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "795c7bb8-3502-414a-a97b-2ba1cfd6a79c",
+      "name" : "persist-query",
+      "description" : "${persist-query}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "d05e7698-ddf5-4f20-9027-771afb2cc3c7",
+      "name" : "list-identifiers",
+      "description" : "${list-identifiers}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e4bfaf36-9a5d-43e0-9fa3-0f4ea7bad8d0",
+      "name" : "default-developer-roles",
+      "description" : "${default-developer-roles}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "escalated-query-handling", "escalated-broker-handling", "default-table-handling", "escalated-database-handling", "default-container-handling", "default-query-handling", "default-user-handling", "default-database-handling", "default-maintenance-handling", "escalated-container-handling", "escalated-table-handling", "default-identifier-handling" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "e2cb054e-ea41-4ab0-881b-e6f576f7424e",
+      "name" : "create-semantic-concept",
+      "description" : "${create-semantic-concept}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "feb612cc-96a6-4ed2-aaa5-01f39b25beb5",
+      "name" : "insert-table-data",
+      "description" : "${insert-table-data}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "a0942e33-441b-4343-9f02-4353d03f7bbb",
+      "name" : "find-database",
+      "description" : "${find-database}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "6a0bb740-4448-49be-aee8-6dd183325be5",
+      "name" : "delete-foreign-table",
+      "description" : "${delete-foreign-table}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "7f3652c7-3073-4566-ab63-25385495ebc3",
+      "name" : "modify-database-visibility",
+      "description" : "${modify-database-visibility}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "4a5df51d-f14d-41a2-ad70-6521df5a5b4f",
+      "name" : "offline_access",
+      "description" : "${role_offline-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "fd41c4c3-d2f8-4f49-84c7-dba84e9a5575",
+      "name" : "execute-query",
+      "description" : "${execute-query}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "2963c2bb-b129-4224-b98f-c8eeab8e72d1",
+      "name" : "create-table",
+      "description" : "${create-table}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "0c487c93-448f-4a82-8b9f-ebd8a0904bf8",
+      "name" : "find-foreign-user",
+      "description" : "${find-foreign-user}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "cf9735a9-fb70-4cc5-b5f4-75afc4e5654b",
+      "name" : "modify-identifier-metadata",
+      "description" : "${modify-identifier-metadata}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "64c2b8f2-1527-4928-81ea-b2651512d028",
+      "name" : "delete-ontology",
+      "description" : "${delete-ontology}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "d6e38368-b40f-423b-82e4-e8aa595237c9",
+      "name" : "find-maintenance-message",
+      "description" : "${find-maintenance-message}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "fd1cc463-3e67-49d9-81b8-2cd90c1daa9c",
+      "name" : "check-database-access",
+      "description" : "${check-database-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "74013867-e426-46cc-ab98-2f4a9225ad1e",
+      "name" : "find-table",
+      "description" : "${find-table}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "a2cc60df-d280-46c5-a539-92e2aa249b4a",
+      "name" : "modify-user-information",
+      "description" : "${modify-user-information}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "c367241f-b5b5-491f-84d5-07fe1bef3877",
+      "name" : "default-identifier-handling",
+      "description" : "${default-identifier-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "delete-identifier", "list-identifiers", "create-identifier", "find-identifier", "publish-identifier" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "ba1ad8f2-39aa-487d-987f-645e8a459559",
+      "name" : "delete-table",
+      "description" : "${delete-table}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "09f7bdb0-296f-46c8-a3a3-8f9254fb17e4",
+      "name" : "list-maintenance-messages",
+      "description" : "${list-maintenance-messages}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "fe3bc45c-61c2-4ece-bcaf-d410dc7de501",
+      "name" : "update-database-access",
+      "description" : "${update-database-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "f43e86ed-76de-4ca8-9b5e-c292c9359bfe",
+      "name" : "escalated-broker-handling",
+      "description" : "${escalated-broker-handling}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "916b1e65-f60c-42cd-96e4-5c98ffc1ba3c",
+      "name" : "uma_authorization",
+      "description" : "${role_uma_authorization}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "d1afa3ed-bf4f-469a-a061-ad7325fb8d9e",
+      "name" : "delete-database-view",
+      "description" : "${delete-database-view}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "6f044bad-6651-4408-bffa-20c2d8f92eee",
+      "name" : "create-identifier",
+      "description" : "${create-identifier}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "be91195a-e30a-4d15-a8da-0aca0a68782f",
+      "name" : "escalated-table-handling",
+      "description" : "${escalated-table-handling}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "delete-foreign-table" ]
+      },
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "98bee7d6-d78c-4e7f-b6a3-3705968b248c",
+      "name" : "list-ontologies",
+      "description" : "${list-ontologies}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "15720c6b-027d-4d53-a0ff-0124bfab7c4c",
+      "name" : "re-execute-query",
+      "description" : "${re-execute-query}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "a9b5181a-8135-41d3-9862-ef80af42211d",
+      "name" : "delete-identifier",
+      "description" : "${delete-identifier}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    }, {
+      "id" : "469c2e63-cda6-48d4-ab8f-eb59a2c69798",
+      "name" : "find-database-view",
+      "description" : "${find-database-view}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0",
+      "attributes" : { }
+    } ],
+    "client" : {
+      "realm-management" : [ {
+        "id" : "4628f654-f8f3-483b-8f92-2a7fc5930b14",
+        "name" : "query-realms",
+        "description" : "${role_query-realms}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "95c2cc47-12f5-4d73-8b74-67e270c45ade",
+        "name" : "manage-authorization",
+        "description" : "${role_manage-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "824791f3-c345-42f8-b103-b7e6d7e40114",
+        "name" : "manage-identity-providers",
+        "description" : "${role_manage-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "1f840202-b7e2-4195-bac9-64e64dad2037",
+        "name" : "view-identity-providers",
+        "description" : "${role_view-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "3c32c096-bb13-44c9-a080-d756a48a9ea3",
+        "name" : "query-clients",
+        "description" : "${role_query-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "e4b85a68-7f31-4fcf-89a2-f10d7df358e9",
+        "name" : "view-authorization",
+        "description" : "${role_view-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "7d317752-ae56-46f2-a2ce-67c64d1b35f6",
+        "name" : "view-users",
+        "description" : "${role_view-users}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-users", "query-groups" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "28824208-976e-4622-b4d7-3d18efbb46fa",
+        "name" : "realm-admin",
+        "description" : "${role_realm-admin}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-realms", "view-identity-providers", "manage-identity-providers", "manage-authorization", "query-clients", "view-authorization", "view-users", "manage-users", "view-realm", "query-users", "view-clients", "query-groups", "create-client", "manage-clients", "manage-events", "impersonation", "view-events", "manage-realm" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "57e846a2-930d-4621-819d-c35086507146",
+        "name" : "manage-users",
+        "description" : "${role_manage-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "7fad9cde-bf96-475a-9174-14a87da51f95",
+        "name" : "view-realm",
+        "description" : "${role_view-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "bbcac294-d78a-4ea1-a4bf-0384266d2fe1",
+        "name" : "query-users",
+        "description" : "${role_query-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "480e1437-ab9e-47de-b47a-edc6b6e285de",
+        "name" : "view-clients",
+        "description" : "${role_view-clients}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-clients" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "b9a9a8f5-f91e-4e73-9e88-1cdf42bd49f9",
+        "name" : "create-client",
+        "description" : "${role_create-client}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "4d1397fb-247c-436f-b26f-124cd89afb08",
+        "name" : "query-groups",
+        "description" : "${role_query-groups}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "e31f522b-b283-4ae1-b875-52afcd98b1d2",
+        "name" : "impersonation",
+        "description" : "${role_impersonation}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "51822d02-fa28-4a49-89da-bc534719d8a8",
+        "name" : "manage-clients",
+        "description" : "${role_manage-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "b2743ce5-0ce8-4157-ae00-f693560f0b39",
+        "name" : "manage-events",
+        "description" : "${role_manage-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "7ea3d7e0-9bf4-438a-b773-243daf622aaa",
+        "name" : "view-events",
+        "description" : "${role_view-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      }, {
+        "id" : "fb73f6f5-0ed5-41d0-852c-0eb3b195b15a",
+        "name" : "manage-realm",
+        "description" : "${role_manage-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+        "attributes" : { }
+      } ],
+      "security-admin-console" : [ ],
+      "dbrepo-client" : [ ],
+      "admin-cli" : [ ],
+      "rabbitmq-client" : [ ],
+      "account-console" : [ ],
+      "broker" : [ {
+        "id" : "de0cfd5e-c2fe-4082-ac39-e3b092139a0f",
+        "name" : "read-token",
+        "description" : "${role_read-token}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "88694c91-753d-4c44-9740-ec9ac06bba45",
+        "attributes" : { }
+      } ],
+      "account" : [ {
+        "id" : "acd78c04-eefc-4344-a5b4-3fc83d848936",
+        "name" : "delete-account",
+        "description" : "${role_delete-account}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      }, {
+        "id" : "939be844-8c49-45b3-9ca1-4b10a454b346",
+        "name" : "view-profile",
+        "description" : "${role_view-profile}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      }, {
+        "id" : "e52fdf00-3e73-4c17-bc1c-643493710a6b",
+        "name" : "view-applications",
+        "description" : "${role_view-applications}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      }, {
+        "id" : "b02a822e-a708-420a-bddc-1a315033fd7c",
+        "name" : "view-consent",
+        "description" : "${role_view-consent}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      }, {
+        "id" : "c590e5f5-2cbf-4151-b1dc-96c454f1f654",
+        "name" : "view-groups",
+        "description" : "${role_view-groups}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      }, {
+        "id" : "15974151-6c13-426b-8cc3-7683dd1311e1",
+        "name" : "manage-account-links",
+        "description" : "${role_manage-account-links}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      }, {
+        "id" : "c12d8d94-c2df-498e-bbe4-2f934a83ae92",
+        "name" : "manage-consent",
+        "description" : "${role_manage-consent}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "view-consent" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      }, {
+        "id" : "55f85811-bded-4d6b-8f7b-45844b963875",
+        "name" : "manage-account",
+        "description" : "${role_manage-account}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "manage-account-links" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+        "attributes" : { }
+      } ]
+    }
+  },
+  "groups" : [ {
+    "id" : "f2ce17fe-7b15-47a4-bbf8-86f415298fa9",
+    "name" : "data-stewards",
+    "path" : "/data-stewards",
+    "subGroups" : [ ],
+    "attributes" : { },
+    "realmRoles" : [ "default-data-steward-roles" ],
+    "clientRoles" : { }
+  }, {
+    "id" : "124d9888-0b6e-46aa-8225-077dcedaf16e",
+    "name" : "developers",
+    "path" : "/developers",
+    "subGroups" : [ ],
+    "attributes" : { },
+    "realmRoles" : [ "default-developer-roles" ],
+    "clientRoles" : { }
+  }, {
+    "id" : "f467c38e-9041-4faa-ae0b-39cec65ff4db",
+    "name" : "researchers",
+    "path" : "/researchers",
+    "subGroups" : [ ],
+    "attributes" : { },
+    "realmRoles" : [ "default-researcher-roles" ],
+    "clientRoles" : { }
+  }, {
+    "id" : "2b9f94b4-d434-4a98-8eab-25678cfee983",
+    "name" : "system",
+    "path" : "/system",
+    "subGroups" : [ ],
+    "attributes" : { },
+    "realmRoles" : [ "default-system-roles" ],
+    "clientRoles" : { }
+  } ],
+  "defaultRole" : {
+    "id" : "abd2d9ee-ebc4-4d0a-839e-6b588a6d442a",
+    "name" : "default-roles-dbrepo",
+    "description" : "${role_default-roles}",
+    "composite" : false,
+    "clientRole" : false,
+    "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0"
+  },
+  "defaultGroups" : [ "/researchers" ],
+  "requiredCredentials" : [ "password" ],
+  "otpPolicyType" : "totp",
+  "otpPolicyAlgorithm" : "HmacSHA1",
+  "otpPolicyInitialCounter" : 0,
+  "otpPolicyDigits" : 6,
+  "otpPolicyLookAheadWindow" : 1,
+  "otpPolicyPeriod" : 30,
+  "otpPolicyCodeReusable" : false,
+  "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ],
+  "localizationTexts" : { },
+  "webAuthnPolicyRpEntityName" : "keycloak",
+  "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
+  "webAuthnPolicyRpId" : "",
+  "webAuthnPolicyAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyRequireResidentKey" : "not specified",
+  "webAuthnPolicyUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyCreateTimeout" : 0,
+  "webAuthnPolicyAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyAcceptableAaguids" : [ ],
+  "webAuthnPolicyExtraOrigins" : [ ],
+  "webAuthnPolicyPasswordlessRpEntityName" : "keycloak",
+  "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ],
+  "webAuthnPolicyPasswordlessRpId" : "",
+  "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified",
+  "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyPasswordlessCreateTimeout" : 0,
+  "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ],
+  "webAuthnPolicyPasswordlessExtraOrigins" : [ ],
+  "scopeMappings" : [ {
+    "clientScope" : "rabbitmq.tag:administrator",
+    "roles" : [ "escalated-broker-handling" ]
+  }, {
+    "clientScope" : "rabbitmq.tag:management",
+    "roles" : [ "default-broker-handling" ]
+  } ],
+  "clientScopeMappings" : {
+    "account" : [ {
+      "client" : "account-console",
+      "roles" : [ "manage-account", "view-groups" ]
+    } ]
+  },
+  "clients" : [ {
+    "id" : "e767a4a6-79e9-4e08-82b7-1076e1a09142",
+    "clientId" : "account",
+    "name" : "${client_account}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/dbrepo/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/dbrepo/account/*" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "d3c4a04e-39ce-4549-a34a-11e25774cd96",
+    "clientId" : "account-console",
+    "name" : "${client_account-console}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/dbrepo/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/dbrepo/account/*" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+",
+      "pkce.code.challenge.method" : "S256"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "protocolMappers" : [ {
+      "id" : "22d90d9c-9881-474c-8dfd-a62c808a9f1c",
+      "name" : "audience resolve",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-audience-resolve-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    } ],
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "81ef0f59-a5ca-4be4-a1d1-0c32edf1cfd6",
+    "clientId" : "admin-cli",
+    "name" : "${client_admin-cli}",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : false,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : true,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "88694c91-753d-4c44-9740-ec9ac06bba45",
+    "clientId" : "broker",
+    "name" : "${client_broker}",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : true,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : false,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "6b7ef364-4132-4831-b4e2-b6e9e9dc63ee",
+    "clientId" : "dbrepo-client",
+    "name" : "${dbrepo-client}",
+    "description" : "",
+    "rootUrl" : "",
+    "adminUrl" : "",
+    "baseUrl" : "",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : true,
+    "clientAuthenticatorType" : "client-secret",
+    "secret" : "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG",
+    "redirectUris" : [ "*" ],
+    "webOrigins" : [ "*" ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : true,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : false,
+    "frontchannelLogout" : true,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "oidc.ciba.grant.enabled" : "false",
+      "client.secret.creation.time" : "1680085365",
+      "backchannel.logout.session.required" : "true",
+      "post.logout.redirect.uris" : "*",
+      "oauth2.device.authorization.grant.enabled" : "false",
+      "backchannel.logout.revoke.offline.tokens" : "false"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : true,
+    "nodeReRegistrationTimeout" : -1,
+    "protocolMappers" : [ {
+      "id" : "da0b27c1-ae2e-4baa-bf78-db233e15c78d",
+      "name" : "preferred_username",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "user.attribute" : "username",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "preferred_username",
+        "userinfo.token.claim" : "true"
+      }
+    }, {
+      "id" : "7c94de93-f60f-487b-b4b7-1891c67f74cc",
+      "name" : "aud",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-hardcoded-claim-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "claim.value" : "dbrepo",
+        "userinfo.token.claim" : "true",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "aud",
+        "access.tokenResponse.claim" : "false"
+      }
+    }, {
+      "id" : "0b4c644f-0cf0-4794-8395-d5d83009dabe",
+      "name" : "uid",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "CUSTOM_ID",
+        "id.token.claim" : "true",
+        "lightweight.claim" : "false",
+        "access.token.claim" : "true",
+        "claim.name" : "uid",
+        "jsonType.label" : "String"
+      }
+    } ],
+    "defaultClientScopes" : [ "roles", "attributes" ],
+    "optionalClientScopes" : [ "rabbitmq.read:*/*", "web-origins", "acr", "rabbitmq.write:*/*", "address", "phone", "offline_access", "profile", "microprofile-jwt", "email", "rabbitmq.configure:*/*" ]
+  }, {
+    "id" : "25741f6b-4867-4138-8238-6345c6ba8702",
+    "clientId" : "rabbitmq-client",
+    "name" : "${rabbitmq-client}",
+    "description" : "",
+    "rootUrl" : "",
+    "adminUrl" : "",
+    "baseUrl" : "",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "secret" : "JEC2FexxrX4N65fLeDGukAl6R3Lc9y0u",
+    "redirectUris" : [ "*" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : true,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : false,
+    "frontchannelLogout" : true,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "oidc.ciba.grant.enabled" : "false",
+      "client.secret.creation.time" : "1680000860",
+      "backchannel.logout.session.required" : "true",
+      "post.logout.redirect.uris" : "*",
+      "oauth2.device.authorization.grant.enabled" : "false",
+      "backchannel.logout.revoke.offline.tokens" : "false"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : -1,
+    "protocolMappers" : [ {
+      "id" : "01a937ed-f0e8-4137-80f3-3be3c447f7fb",
+      "name" : "username",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "false",
+        "user.attribute" : "username",
+        "id.token.claim" : "false",
+        "access.token.claim" : "true",
+        "claim.name" : "client_id",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "f1afc22d-f595-403b-ba2e-6ab19d98205e",
+      "name" : "Audience",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-hardcoded-claim-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "claim.value" : "rabbitmq",
+        "userinfo.token.claim" : "false",
+        "id.token.claim" : "false",
+        "access.token.claim" : "true",
+        "claim.name" : "aud",
+        "access.tokenResponse.claim" : "false"
+      }
+    } ],
+    "defaultClientScopes" : [ "web-origins", "acr", "rabbitmq.tag:management" ],
+    "optionalClientScopes" : [ "rabbitmq.read:*/*", "rabbitmq.write:*/*", "address", "phone", "offline_access", "profile", "roles", "microprofile-jwt", "email", "rabbitmq.configure:*/*" ]
+  }, {
+    "id" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930",
+    "clientId" : "realm-management",
+    "name" : "${client_realm-management}",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : true,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : false,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "f205c451-9524-4380-acc3-947f7ecb6b7c",
+    "clientId" : "security-admin-console",
+    "name" : "${client_security-admin-console}",
+    "rootUrl" : "${authAdminUrl}",
+    "baseUrl" : "/admin/dbrepo/console/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/admin/dbrepo/console/*" ],
+    "webOrigins" : [ "+" ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+",
+      "pkce.code.challenge.method" : "S256"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "protocolMappers" : [ {
+      "id" : "c4d54410-3f22-4259-9571-94da2c43b752",
+      "name" : "locale",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "locale",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "locale",
+        "jsonType.label" : "String"
+      }
+    } ],
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  } ],
+  "clientScopes" : [ {
+    "id" : "69f4ecf0-4165-49ab-bf0d-38409b15b706",
+    "name" : "rabbitmq.tag:administrator",
+    "description" : "administrator",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    }
+  }, {
+    "id" : "7f6e9b44-e2eb-417d-b0fe-db820c9a6564",
+    "name" : "email",
+    "description" : "OpenID Connect built-in scope: email",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "consent.screen.text" : "${emailScopeConsentText}"
+    },
+    "protocolMappers" : [ {
+      "id" : "782819fe-ba5d-4ddb-9f95-cabb69d79c8d",
+      "name" : "email verified",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "emailVerified",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "email_verified",
+        "jsonType.label" : "boolean"
+      }
+    }, {
+      "id" : "ca613fc8-bbf2-4240-8b33-a1874f1559f3",
+      "name" : "email",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "email",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "email",
+        "jsonType.label" : "String"
+      }
+    } ]
+  }, {
+    "id" : "b9da268f-6745-49dc-a764-3c54e385accc",
+    "name" : "profile",
+    "description" : "OpenID Connect built-in scope: profile",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "consent.screen.text" : "${profileScopeConsentText}"
+    },
+    "protocolMappers" : [ {
+      "id" : "84f0487a-1d7d-470c-9b8e-5835294ae235",
+      "name" : "username",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "username",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "preferred_username",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "bbdcdb36-3ec0-443d-b1af-9993d40f0567",
+      "name" : "gender",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "gender",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "gender",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "9faa870b-5491-4ce9-b27d-c9ce07d6a95e",
+      "name" : "birthdate",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "birthdate",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "birthdate",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "f0e3c012-9523-4076-83ae-e466e2d08220",
+      "name" : "full name",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-full-name-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "userinfo.token.claim" : "true"
+      }
+    }, {
+      "id" : "f757d8ec-e181-429c-9287-9ad0600b061f",
+      "name" : "profile",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "profile",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "profile",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "18cfbf4b-0a8e-45c7-a832-c0f72c92f3f3",
+      "name" : "updated at",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "updatedAt",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "updated_at",
+        "jsonType.label" : "long"
+      }
+    }, {
+      "id" : "841ea785-26ab-429a-a420-09ce3948924d",
+      "name" : "family name",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "lastName",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "family_name",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "bfba13ff-f952-4e89-bbb1-a693fdebfae8",
+      "name" : "website",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "website",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "website",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "475f071d-5149-4379-b928-76482f5f519c",
+      "name" : "zoneinfo",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "zoneinfo",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "zoneinfo",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "b8bebfed-b5e9-4604-a0ee-9817f7d439ac",
+      "name" : "middle name",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "middleName",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "middle_name",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "445232c8-6830-476c-a6f1-8bbef167595a",
+      "name" : "picture",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "picture",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "picture",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "65f2e474-6ede-4872-86e4-e49504dd0f2a",
+      "name" : "locale",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "locale",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "locale",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "16cd5a27-ccf3-453c-ae1e-8621813ab73c",
+      "name" : "given name",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "firstName",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "given_name",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "f9efedfc-3388-457c-b10a-1dff4525ff9b",
+      "name" : "nickname",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "nickname",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "nickname",
+        "jsonType.label" : "String"
+      }
+    } ]
+  }, {
+    "id" : "627fa054-08eb-4206-af71-9e838e984b8b",
+    "name" : "microprofile-jwt",
+    "description" : "Microprofile - JWT built-in scope",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "false"
+    },
+    "protocolMappers" : [ {
+      "id" : "e6cc53e5-5d7e-468e-88c8-0737dd3dc759",
+      "name" : "groups",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "multivalued" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "foo",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "groups",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "83b4444c-10fc-44e8-a0c0-0c1da1f9bba3",
+      "name" : "upn",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-property-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "username",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "upn",
+        "jsonType.label" : "String"
+      }
+    } ]
+  }, {
+    "id" : "4122ff9e-ad3c-4142-afc6-9aefdecfc86d",
+    "name" : "role_list",
+    "description" : "SAML role list",
+    "protocol" : "saml",
+    "attributes" : {
+      "consent.screen.text" : "${samlRoleListScopeConsentText}",
+      "display.on.consent.screen" : "true"
+    },
+    "protocolMappers" : [ {
+      "id" : "bb0747fa-c008-4af3-93be-e7739650ebd5",
+      "name" : "role list",
+      "protocol" : "saml",
+      "protocolMapper" : "saml-role-list-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "single" : "false",
+        "attribute.nameformat" : "Basic",
+        "attribute.name" : "Role"
+      }
+    } ]
+  }, {
+    "id" : "2e76447d-fbe7-4fa7-a16c-54a381b960ae",
+    "name" : "rabbitmq.configure:*/*",
+    "description" : "",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "false",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    }
+  }, {
+    "id" : "52aad832-c6c4-49df-8a04-6ad4a406fdfa",
+    "name" : "phone",
+    "description" : "OpenID Connect built-in scope: phone",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "consent.screen.text" : "${phoneScopeConsentText}"
+    },
+    "protocolMappers" : [ {
+      "id" : "dae802fb-9138-408a-b80e-a40eb0f56814",
+      "name" : "phone number",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "phoneNumber",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "phone_number",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "feb06a8d-b0eb-4911-8464-368d93f566fa",
+      "name" : "phone number verified",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "phoneNumberVerified",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "phone_number_verified",
+        "jsonType.label" : "boolean"
+      }
+    } ]
+  }, {
+    "id" : "f64d64e8-57ce-4eb2-b99e-9f02fdbd99f9",
+    "name" : "web-origins",
+    "description" : "OpenID Connect scope for add allowed web origins to the access token",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "false",
+      "display.on.consent.screen" : "false",
+      "consent.screen.text" : ""
+    },
+    "protocolMappers" : [ {
+      "id" : "c6411e3b-6478-453d-b530-5fe175a4d786",
+      "name" : "allowed web origins",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-allowed-origins-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    } ]
+  }, {
+    "id" : "55341d34-0086-4173-ae61-d9b175b179d8",
+    "name" : "acr",
+    "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "false",
+      "display.on.consent.screen" : "false"
+    },
+    "protocolMappers" : [ {
+      "id" : "58ea3217-0fff-4207-9d08-919f5493b629",
+      "name" : "acr loa level",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-acr-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "userinfo.token.claim" : "true"
+      }
+    } ]
+  }, {
+    "id" : "a02c2c38-923c-46ec-9899-321412b388e5",
+    "name" : "attributes",
+    "description" : "User Attributes",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "false",
+      "display.on.consent.screen" : "false",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    },
+    "protocolMappers" : [ {
+      "id" : "78c461c1-f3f9-4d10-8835-097f13bdcd60",
+      "name" : "Theme",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "aggregate.attrs" : "false",
+        "multivalued" : "false",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "theme_dark",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "attributes.theme_dark"
+      }
+    } ]
+  }, {
+    "id" : "06062e22-89c0-4e1d-a25b-2483903b02d5",
+    "name" : "rabbitmq.write:*/*",
+    "description" : "",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "false",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    }
+  }, {
+    "id" : "db63e03b-7918-492f-997b-f2dda98f3b39",
+    "name" : "rabbitmq.tag:management",
+    "description" : "management",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    }
+  }, {
+    "id" : "210cc792-6c07-45a6-a77e-827cdf3b41ba",
+    "name" : "offline_access",
+    "description" : "OpenID Connect built-in scope: offline_access",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "consent.screen.text" : "${offlineAccessScopeConsentText}",
+      "display.on.consent.screen" : "true"
+    }
+  }, {
+    "id" : "425abf4a-2ee2-431d-aa92-e373a36fe556",
+    "name" : "address",
+    "description" : "OpenID Connect built-in scope: address",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "consent.screen.text" : "${addressScopeConsentText}"
+    },
+    "protocolMappers" : [ {
+      "id" : "8d4ffe4d-1d01-4ca1-8ff4-44eacca61b30",
+      "name" : "address",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-address-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "user.attribute.formatted" : "formatted",
+        "user.attribute.country" : "country",
+        "user.attribute.postal_code" : "postal_code",
+        "userinfo.token.claim" : "true",
+        "user.attribute.street" : "street",
+        "id.token.claim" : "true",
+        "user.attribute.region" : "region",
+        "access.token.claim" : "true",
+        "user.attribute.locality" : "locality"
+      }
+    } ]
+  }, {
+    "id" : "c96f0b73-ea79-4b46-93ef-d1092297f855",
+    "name" : "rabbitmq.read:*/*",
+    "description" : "",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "false",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    }
+  }, {
+    "id" : "37f61543-dad7-4a82-8e10-77acdd1eefdc",
+    "name" : "roles",
+    "description" : "OpenID Connect scope for add user roles to the access token",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "false",
+      "display.on.consent.screen" : "true",
+      "consent.screen.text" : "${rolesScopeConsentText}"
+    },
+    "protocolMappers" : [ {
+      "id" : "3b6b6914-8ad1-4a71-88ec-444f754aaacb",
+      "name" : "audience resolve",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-audience-resolve-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    }, {
+      "id" : "2defedf5-9af3-4531-822c-a879dedcd29d",
+      "name" : "realm roles",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "user.attribute" : "foo",
+        "access.token.claim" : "true",
+        "claim.name" : "realm_access.roles",
+        "jsonType.label" : "String",
+        "multivalued" : "true"
+      }
+    }, {
+      "id" : "a7bd6723-e58e-47f7-95c0-2925ce99283d",
+      "name" : "client roles",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-client-role-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "user.attribute" : "foo",
+        "access.token.claim" : "true",
+        "claim.name" : "resource_access.${client_id}.roles",
+        "jsonType.label" : "String",
+        "multivalued" : "true"
+      }
+    } ]
+  } ],
+  "defaultDefaultClientScopes" : [ "rabbitmq.tag:administrator", "rabbitmq.tag:management" ],
+  "defaultOptionalClientScopes" : [ "rabbitmq.write:*/*", "offline_access", "rabbitmq.configure:*/*", "roles", "role_list", "address", "phone", "acr", "microprofile-jwt", "email", "attributes", "profile", "rabbitmq.read:*/*", "web-origins" ],
+  "browserSecurityHeaders" : {
+    "contentSecurityPolicyReportOnly" : "",
+    "xContentTypeOptions" : "nosniff",
+    "referrerPolicy" : "no-referrer",
+    "xRobotsTag" : "none",
+    "xFrameOptions" : "SAMEORIGIN",
+    "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+    "xXSSProtection" : "1; mode=block",
+    "strictTransportSecurity" : "max-age=31536000; includeSubDomains"
+  },
+  "smtpServer" : { },
+  "eventsEnabled" : false,
+  "eventsListeners" : [ "jboss-logging" ],
+  "enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_CONSENT_ERROR", "GRANT_CONSENT", "VERIFY_PROFILE_ERROR", "REMOVE_TOTP", "REVOKE_GRANT", "UPDATE_TOTP", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", "RESTART_AUTHENTICATION", "IMPERSONATE", "UPDATE_PROFILE_ERROR", "LOGIN", "OAUTH2_DEVICE_VERIFY_USER_CODE", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "TOKEN_EXCHANGE", "AUTHREQID_TO_TOKEN", "LOGOUT", "REGISTER", "DELETE_ACCOUNT_ERROR", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "DELETE_ACCOUNT", "UPDATE_PASSWORD", "CLIENT_DELETE", "FEDERATED_IDENTITY_LINK_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN", "CLIENT_DELETE_ERROR", "VERIFY_EMAIL", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "EXECUTE_ACTIONS", "REMOVE_FEDERATED_IDENTITY_ERROR", "TOKEN_EXCHANGE_ERROR", "PERMISSION_TOKEN", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "SEND_VERIFY_EMAIL", "OAUTH2_DEVICE_AUTH", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "OAUTH2_DEVICE_CODE_TO_TOKEN", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "EXECUTE_ACTION_TOKEN", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "CLIENT_UPDATE_ERROR", "AUTHREQID_TO_TOKEN_ERROR", "UPDATE_PROFILE", "CLIENT_REGISTER_ERROR", "FEDERATED_IDENTITY_LINK", "SEND_IDENTITY_PROVIDER_LINK", "SEND_VERIFY_EMAIL_ERROR", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "OAUTH2_DEVICE_AUTH_ERROR", "UPDATE_CONSENT", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "CUSTOM_REQUIRED_ACTION_ERROR", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "VERIFY_PROFILE", "GRANT_CONSENT_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ],
+  "adminEventsEnabled" : false,
+  "adminEventsDetailsEnabled" : false,
+  "identityProviders" : [ ],
+  "identityProviderMappers" : [ ],
+  "components" : {
+    "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
+      "id" : "4d3f9f14-f5d2-4b0c-8ea7-e6d078aa2191",
+      "name" : "Max Clients Limit",
+      "providerId" : "max-clients",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "max-clients" : [ "200" ]
+      }
+    }, {
+      "id" : "f35bce67-1e75-408b-b065-52183368d4fd",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    }, {
+      "id" : "0efa669d-1017-4b4a-82e1-c2eaf72de2c9",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    }, {
+      "id" : "528fb423-d66e-472e-9120-1f03ba9e0f18",
+      "name" : "Consent Required",
+      "providerId" : "consent-required",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    }, {
+      "id" : "3ab11d74-5e76-408a-b85a-26bf8950f979",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "saml-role-list-mapper" ]
+      }
+    }, {
+      "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1",
+      "name" : "Trusted Hosts",
+      "providerId" : "trusted-hosts",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "host-sending-registration-request-must-match" : [ "true" ],
+        "client-uris-must-match" : [ "true" ]
+      }
+    }, {
+      "id" : "f565cb47-3bcf-4078-8f94-eb4179c375b8",
+      "name" : "Full Scope Disabled",
+      "providerId" : "scope",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    }, {
+      "id" : "104ec5a9-025b-4c44-8ac0-82d22887ca3e",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper" ]
+      }
+    } ],
+    "org.keycloak.userprofile.UserProfileProvider" : [ {
+      "id" : "fb763636-e1ea-49c7-adca-ea105cdec4ad",
+      "providerId" : "declarative-user-profile",
+      "subComponents" : { },
+      "config" : {
+        "kc.user.profile.config" : [ "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}],\"unmanagedAttributePolicy\":\"ENABLED\"}" ]
+      }
+    } ],
+    "org.keycloak.keys.KeyProvider" : [ {
+      "id" : "2f53ccf3-37b0-4d34-83e7-ed497499ee51",
+      "name" : "rsa-enc-generated",
+      "providerId" : "rsa-enc-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEowIBAAKCAQEA3b1tNLfcjFLUw9UShVDNf+ZD8sQqb4YBaIXcSJTX/zDQUPiCp176BBGI3s4VplDArnOW+LumozmKogeoHEnGEIDW8ovgK5uMU9tSA2p0qqGBUMOdR8YATTIfCJe7qGiiuGa3WZy3sQLM70SuRzx02YU8gvUcvl2Js4KyqAziOUX/w3Wa59H9jjGNUXYyqaPWJp73eHzbVYWySzyLG22mVlcUtBx5siL5T2/Xu0p9z4l7/bapwwmOVi1ZrcHjbEAwdGEiSMGI/uWqAF+r1BRpmJLR7HNXcL3eK4/56VYLaiwSejfyYeRFMITEn/UxGYhcXZ5xMUUCG0TxjBhLYpTBuwIDAQABAoIBAA4dwebcxkrH99Poa8+WkiE7JgaS9sahx9OBI2xwJANoIU2TpzGuNLQZ76uLgB+rPWZTD9Xm5a1iJjwOyQ9/937TzPCk91D0tpgcusRikb8jx/6TGB9acL4kBjYUVCCHr3BA2G75MKKGtJ2OMvAbCQSosZj+r2VDwYFEPUkV2jheE5JHSBkwyIRrus3JCwu8gu5fyCg9z8ljcxJxI5HIsi4v8Z21aCw/cLj7h5cMt44wCjQz4rOfYNBEFeHDtlfR1QtWKgjm4ZHHJbKrzf9b2kQXclziceEbSM0tYbROEXKi+s0Zc+z3HEG89vv0vfN400clmzzIAijKY6gg3pPRWdECgYEA+lnWYbSlXDMNYx6RBXm1RnlMUYIm4oy4/9ljgnoGJ6WCn3SjFkgaDtiKfGIG1BSB85r04pAPANgcWHf5tWDnq0ARvBVG0BX2bKd++7B3D4d3CRYKCwm88SslJXv9dfHVhq4+zViFPiUWwT20A72jCuUCvL88y5fh/YBecfdh+jECgYEA4r5RD0NB9dMaeg5/jk/GEHIo4Z9KLc6FrSoOFo2xFkPOy1sgDpDOiNtypuWvniO7k7Ose3DS3hlfTMsKzIW/CgQJ20+Y4cvBWDaOsRxfjj7w3d+jH5OSJdKKSzTrgLKc9ZhlRzVXy0J0hipIA6HG5kdVdLXmh85ITmf1CbJhE6sCgYBjPVeBNbXTHZ2x6/z62aslO5IoQVqetb/kE82hfDOSZcao5Ph9Lam+ttH2ynkAevykj4mBgi+gWwqpey2uW7KaLPSaxShj9kDQA3mP1fzsV/u0y1rB02Nlin/YIxVvOqU1FT9p8SwoXVVu1sHUNck62VtDbN9xqUx5S/ikXrclEQKBgQCoTssOwEcK+Vty9KYcdfy4onTUHZBLdjxl8Iyqkxy7QTQUYRznkvesQPDXEDGO+kk3dyx2KKZt9Hl4IFNww2quPZcvcuMx4DQxjbXXpA8OIIxcta95NepLJwA+mRai3nKCH1A2TlNP7pFeMa5o+8IPly3Ix2lKr4Wepa4PN5i1pwKBgCZ1QP6XAOERl9NznNmU0rXVcvYNP4PIIfQWfvGsldZ4QKkmjjAGiS0/oYqdWs+UDRZyCRChaVjDXO9fk0PEG5OGKAj9nyiYCT/M8xtJ3UeP5ffZZvJ/vnye3QdDIo1e38ZzsWwJHmLYw7fRqY9W5Vxo0Vsy22U3CJY70KTxVdTy" ],
+        "keyUse" : [ "ENC" ],
+        "certificate" : [ "MIICmzCCAYMCBgGG3GWycDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZkYnJlcG8wHhcNMjMwMzEzMTkxMzE3WhcNMzMwMzEzMTkxNDU3WjARMQ8wDQYDVQQDDAZkYnJlcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdvW00t9yMUtTD1RKFUM1/5kPyxCpvhgFohdxIlNf/MNBQ+IKnXvoEEYjezhWmUMCuc5b4u6ajOYqiB6gcScYQgNbyi+Arm4xT21IDanSqoYFQw51HxgBNMh8Il7uoaKK4ZrdZnLexAszvRK5HPHTZhTyC9Ry+XYmzgrKoDOI5Rf/DdZrn0f2OMY1RdjKpo9Ymnvd4fNtVhbJLPIsbbaZWVxS0HHmyIvlPb9e7Sn3PiXv9tqnDCY5WLVmtweNsQDB0YSJIwYj+5aoAX6vUFGmYktHsc1dwvd4rj/npVgtqLBJ6N/Jh5EUwhMSf9TEZiFxdnnExRQIbRPGMGEtilMG7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAK3kQ1VkQrzvSWvmXmazmNoA1ZiPzRDs1XhGUWxgsxzgPylr3dGBuqQbKvgnLUBQLSqlJHpI4fZflHswu1qrvVZYtekPcGef4WhcKAu2i1RwxrKa6RJQ1tRbrLuVYCzPv5p/DWgltWVn88aoLnqQn0SK/0PB/o4a4Cm7Kq2ZzCr1dACBr06LvOHsc7249OySmbG4HH+pLK6jVURhZ9VaObqAHe2FJBVVoIzURbdiRRURqumrIvbnpeaU1aFyg6ED5wTnXvmMPmVPt9F79mcB33bASO5wyu00X8t1hyN2Show2l2vxLACGUzVkTQt15s7uDLKE7qLmKSR3EuSGXWv3wA=" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "RSA-OAEP" ]
+      }
+    }, {
+      "id" : "230cb681-9ceb-4b1b-8a4c-929a11b08de0",
+      "name" : "hmac-generated-hs512",
+      "providerId" : "hmac-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "8a489935-9a95-459b-9059-59b438ef0fa8" ],
+        "secret" : [ "xSCVgBlrLPWoF54gKQdR7BqXlfNaCD43xtS_ZgQRC0tGNAbqhy2Q9y8LdD2IR7K__8VGaDGYtyZayopgTebhDBb4gHDjDOBX7flhFYRrm0G3aTIuCIyFG-bPULwmyP_oHeC6tjwdQhqx5G0tE2mQQqPC9dDZuUA5I7QREIGK8cI" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "HS512" ]
+      }
+    }, {
+      "id" : "28ca0b6d-b2e2-4785-b04b-2391e6344e30",
+      "name" : "aes-generated",
+      "providerId" : "aes-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "6dc4834f-a1de-4cfe-a29d-e84ac8e9b1a8" ],
+        "secret" : [ "HpuzG_jWYKwypLeoPEMC4A" ],
+        "priority" : [ "100" ]
+      }
+    }, {
+      "id" : "bd7945cf-6d35-4e03-9c3a-197f2dc76973",
+      "name" : "hmac-generated",
+      "providerId" : "hmac-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "5034d264-cb50-4006-a59e-2ce636eb5f38" ],
+        "secret" : [ "ToVIw-a4IE-Yp9JpP8ztb8NAICYO8CT3tUiDPT6DdiBcgzKJ9Ym9vspxGVdmPceX3mAgbnGLAcTx1PkInSVrbZs-tX9QXFwdlyGbewhKiNpH8wEg32Wk4GuUDpTv8JCsymgWyQBY681jvIMv05eCoK2QWpqCzcgP828KM5peCzo" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "HS256" ]
+      }
+    }, {
+      "id" : "2293ff99-3c6d-46d1-8635-5e679d5b134a",
+      "name" : "rsa-generated",
+      "providerId" : "rsa-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEpAIBAAKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQABAoIBADNcMt6hAHub4JTAYS6Mra0EPRBO2XhWmACBrv3+8ETClXd5475KPLDewgRVtlmtbwU8G8awUXESQgPS9lfiqvQhPreA3cHlm6oP2WMKOEtakr2s8I+frsTBLCo0Ini9RaSzjoVVgS0zofyhASKi+T970MafSj5P3XNb8YBFdXgoYDiA7FXLH6a/+m7LScL+wGcFMAAeYESxZbMQLfH3v8L+4EcTraiwjLG17ZdlF3dpybMyUSse6ZQ/PdlyvBuzzLXhN6Ce2gd9ATfS+YWTzo7Yf+GU+ex5bIpVOfHqtuM/hyq7YGKENClsXwNZIAoFnvGCbvECAfgyapVrD30IfykCgYEA0rgsSZ82pxT40NxwgBD1g9lbNVBKXphRB/3S078qusUzJjT7AldEj4imGPhAbI7bI8gAeWJsp1XJWkjM8ktaVrh+NQl7p8e9OPh0pQF/5Bdg8ajbjXESpjnaU66pVYRQy/d+jNli/YRAHX5RUfsBl+6W4+WSVMGmKBiqJsur+ecCgYEAz1YVXClcmUnyZem5B+2E9noIzjF6ROE+jIb6rawM85P3Xd0lXtECQavtxw+Qk7I32qOwrxl1UpK2foVel3pazi+4OpMfmqtYGenRP1Zk1cZwrDo0cIemTDGjj3kJ8tYn12CGolFQpJZgK6OHzvG0tOxI5VZgjIViWNPe1PGWXtUCgYEAxXGNDe8BZs1f11S2lUlOw5yGug3hoYFXbAWJ5p7Ziuf8ZXB/QlJDC7se54a11wKEk6Jzz0lKRgE8CjzszJuOqnN0zn10QGIIC7nCklo1W6QMUmPGVWH994N976tZP6gbjQL6sT+AYcvpx7j0ubxYYeRNvnz+ACzzY964kGGHY0ECgYEAumlwPPNnMN7+VEjGNm2D7UMdJZ3wi3tkjF5ThdA5uMohTsAk+FG80KSu3RmOaGyEsUwY7+VYyYvlDm4E9PZqLBVVczyR3rMNPAcwPd0EPfvzk7WlLkOX7ct3fehaXH3VRlyfz9KCSeh1wOZ/lT1VtpD2nVOC7PSDzs92+kfXZZ0CgYAnrD1y4skgXkdwolZ3unn3EFyGm2d+X5aMTHwQPdWxqoNIAl/9wdghlzihwnPhhsxq1WzlxuC3V2IMrNPtRx70Mi+FbSmR5m4Xx5RptgMtMlwno+L40PzNJgMjHGjt0wcx3Vel8wuohDtnqMyS7P5nG1/TQx0Cyzwn7QOXlNpgbQ==" ],
+        "keyUse" : [ "SIG" ],
+        "certificate" : [ "MIICmzCCAYMCBgGG3GWyBTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZkYnJlcG8wHhcNMjMwMzEzMTkxMzE3WhcNMzMwMzEzMTkxNDU3WjARMQ8wDQYDVQQDDAZkYnJlcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqqcdDYFZZb28M0tEJzEP77FmD/Xqioyj9zWX6VwUSOMAgmMmn8eqs9hT9T0a+q4YTo9tUW1PNbUpwprA5b4Uk04DcIajxDVMUR/PjcHytmkqwVskq9AZW/Vngdoo+8tSbuIybwe/3Vwt266hbHpDcM97a+DXcYooRl7tQWCEX7RP27wQrMD9epDQ6IgKayZg9vC9/03dsIqwH9jXQRiZlFvwiEKhX2aY7lPGBaCK414JO00K/Z49iov9TRa/IYVbSt5qwgrx6DcqsBSPwOnI6A85UGfeUEZ/7coVJiL7RvBlsllapsL9eWTbQajVh94k9Ei3sibEPbtH+U2OAM78zAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAASnN1Cuif1sdfEK2kWAURSXGJCohCROLWdKFjaeHPRaEfpbFJsgxW0Yj3nwX5O3bUlOWoTyENwnXSsXMQsqnNi+At32CKaKO8+AkhAbgQL9F0B+KeJwmYv3cUj5N/LYkJjBvZBzUZ4Ugu5dcxH0k7AktLAIwimkyEnxTNolOA3UyrGGpREr8MCKWVr10RFuOpF/0CsJNNwbHXzalO9D756EUcRWZ9VSg6QVNso0YYRKTnILWDn9hcTRnqGy3SHo3anFTqQZ+BB57YbgFWy6udC0LYRB3zdp6zNti87eu/VEymiDY/mmo1AB8Tm0b6vxFz4AKcL3ax5qS6YnZ9efSzk=" ],
+        "priority" : [ "100" ]
+      }
+    } ]
+  },
+  "internationalizationEnabled" : false,
+  "supportedLocales" : [ ],
+  "authenticationFlows" : [ {
+    "id" : "88e5d526-2298-413c-a904-133ad839d47f",
+    "alias" : "Account verification options",
+    "description" : "Method with which to verity the existing account",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "idp-email-verification",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Verify Existing Account by Re-authentication",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "a690c715-fbae-4c20-b680-bd4010718761",
+    "alias" : "Browser - Conditional OTP",
+    "description" : "Flow to determine if the OTP is required for the authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "conditional-user-configured",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "ad6d407e-c73e-4439-baf3-d7c99c6cb6ad",
+    "alias" : "Direct Grant - Conditional OTP",
+    "description" : "Flow to determine if the OTP is required for the authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "conditional-user-configured",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "direct-grant-validate-otp",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "e5d03405-e10a-408a-adb2-41dbb4f24515",
+    "alias" : "First broker login - Conditional OTP",
+    "description" : "Flow to determine if the OTP is required for the authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "conditional-user-configured",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "96b93843-62d0-44f1-84dd-21cc5f95f523",
+    "alias" : "Handle Existing Account",
+    "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "idp-confirm-link",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Account verification options",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "088f4051-36ab-4952-a4f2-4ba53c408083",
+    "alias" : "Reset - Conditional OTP",
+    "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "conditional-user-configured",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "reset-otp",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "05f37bb2-779d-4e3f-ad1b-f6eb33bb3de4",
+    "alias" : "User creation or linking",
+    "description" : "Flow for the existing/non-existing user alternatives",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticatorConfig" : "create unique user config",
+      "authenticator" : "idp-create-user-if-unique",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Handle Existing Account",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "300a5647-7d2c-4348-9f1f-51504bfda1c4",
+    "alias" : "Verify Existing Account by Re-authentication",
+    "description" : "Reauthentication of existing account",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "idp-username-password-form",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "CONDITIONAL",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "First broker login - Conditional OTP",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "26afc672-314b-4ad9-9711-7aaeafd7c00c",
+    "alias" : "browser",
+    "description" : "browser based authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-cookie",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "auth-spnego",
+      "authenticatorFlow" : false,
+      "requirement" : "DISABLED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "identity-provider-redirector",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 25,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "autheticatorFlow" : true,
+      "flowAlias" : "forms",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "9b301f6c-eda7-4da0-ba09-1a6454ff910d",
+    "alias" : "clients",
+    "description" : "Base authentication for clients",
+    "providerId" : "client-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "client-secret",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "client-jwt",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "client-secret-jwt",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "client-x509",
+      "authenticatorFlow" : false,
+      "requirement" : "ALTERNATIVE",
+      "priority" : 40,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "6e54f1be-dbad-4b6d-8eee-8e048d413c63",
+    "alias" : "direct grant",
+    "description" : "OpenID Connect Resource Owner Grant",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "direct-grant-validate-username",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "direct-grant-validate-password",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "CONDITIONAL",
+      "priority" : 30,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Direct Grant - Conditional OTP",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "31da4b94-03c4-4d79-9ac3-5df1445c0781",
+    "alias" : "docker auth",
+    "description" : "Used by Docker clients to authenticate against the IDP",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "docker-http-basic-authenticator",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "2e16651d-681f-4d9b-9dd4-9acdb465cd43",
+    "alias" : "first broker login",
+    "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticatorConfig" : "review profile config",
+      "authenticator" : "idp-review-profile",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "User creation or linking",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "da109a26-fefa-48a4-ae8e-1d49627c2db8",
+    "alias" : "forms",
+    "description" : "Username, password, otp and other auth forms.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-username-password-form",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "CONDITIONAL",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Browser - Conditional OTP",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "4c983c77-241f-41c5-8b8a-e2cd6fc08914",
+    "alias" : "registration",
+    "description" : "registration flow",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "registration-page-form",
+      "authenticatorFlow" : true,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : true,
+      "flowAlias" : "registration form",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "d62c8dd6-633c-408a-aa99-43071510efb4",
+    "alias" : "registration form",
+    "description" : "registration form",
+    "providerId" : "form-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "registration-user-creation",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "registration-password-action",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 50,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "registration-recaptcha-action",
+      "authenticatorFlow" : false,
+      "requirement" : "DISABLED",
+      "priority" : 60,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "c8ca5be7-e76d-4e16-b5ca-3ced99d92dbb",
+    "alias" : "reset credentials",
+    "description" : "Reset credentials for a user if they forgot their password or something",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "reset-credentials-choose-user",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "reset-credential-email",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "reset-password",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 30,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "CONDITIONAL",
+      "priority" : 40,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Reset - Conditional OTP",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "389c1c37-e8af-4610-a507-e1257f55b954",
+    "alias" : "saml ecp",
+    "description" : "SAML ECP Profile Authentication Flow",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "http-basic-authenticator",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  } ],
+  "authenticatorConfig" : [ {
+    "id" : "d66ca9d0-1645-4c84-abfe-c0a696f17de4",
+    "alias" : "create unique user config",
+    "config" : {
+      "require.password.update.after.registration" : "false"
+    }
+  }, {
+    "id" : "061cc6b8-90be-4423-9bf9-974ead709b5d",
+    "alias" : "review profile config",
+    "config" : {
+      "update.profile.on.first.login" : "missing"
+    }
+  } ],
+  "requiredActions" : [ {
+    "alias" : "CONFIGURE_TOTP",
+    "name" : "Configure OTP",
+    "providerId" : "CONFIGURE_TOTP",
+    "enabled" : true,
+    "defaultAction" : false,
+    "priority" : 10,
+    "config" : { }
+  }, {
+    "alias" : "TERMS_AND_CONDITIONS",
+    "name" : "Terms and Conditions",
+    "providerId" : "TERMS_AND_CONDITIONS",
+    "enabled" : false,
+    "defaultAction" : false,
+    "priority" : 20,
+    "config" : { }
+  }, {
+    "alias" : "UPDATE_PASSWORD",
+    "name" : "Update Password",
+    "providerId" : "UPDATE_PASSWORD",
+    "enabled" : false,
+    "defaultAction" : false,
+    "priority" : 30,
+    "config" : { }
+  }, {
+    "alias" : "UPDATE_PROFILE",
+    "name" : "Update Profile",
+    "providerId" : "UPDATE_PROFILE",
+    "enabled" : true,
+    "defaultAction" : false,
+    "priority" : 40,
+    "config" : { }
+  }, {
+    "alias" : "VERIFY_EMAIL",
+    "name" : "Verify Email",
+    "providerId" : "VERIFY_EMAIL",
+    "enabled" : false,
+    "defaultAction" : false,
+    "priority" : 50,
+    "config" : { }
+  }, {
+    "alias" : "delete_account",
+    "name" : "Delete Account",
+    "providerId" : "delete_account",
+    "enabled" : false,
+    "defaultAction" : false,
+    "priority" : 60,
+    "config" : { }
+  }, {
+    "alias" : "webauthn-register",
+    "name" : "Webauthn Register",
+    "providerId" : "webauthn-register",
+    "enabled" : true,
+    "defaultAction" : false,
+    "priority" : 70,
+    "config" : { }
+  }, {
+    "alias" : "webauthn-register-passwordless",
+    "name" : "Webauthn Register Passwordless",
+    "providerId" : "webauthn-register-passwordless",
+    "enabled" : true,
+    "defaultAction" : false,
+    "priority" : 80,
+    "config" : { }
+  }, {
+    "alias" : "delete_credential",
+    "name" : "Delete Credential",
+    "providerId" : "delete_credential",
+    "enabled" : true,
+    "defaultAction" : false,
+    "priority" : 100,
+    "config" : { }
+  }, {
+    "alias" : "update_user_locale",
+    "name" : "Update User Locale",
+    "providerId" : "update_user_locale",
+    "enabled" : true,
+    "defaultAction" : false,
+    "priority" : 1000,
+    "config" : { }
+  } ],
+  "browserFlow" : "browser",
+  "registrationFlow" : "registration",
+  "directGrantFlow" : "direct grant",
+  "resetCredentialsFlow" : "reset credentials",
+  "clientAuthenticationFlow" : "clients",
+  "dockerAuthenticationFlow" : "docker auth",
+  "firstBrokerLoginFlow" : "first broker login",
+  "attributes" : {
+    "cibaBackchannelTokenDeliveryMode" : "poll",
+    "cibaAuthRequestedUserHint" : "login_hint",
+    "clientOfflineSessionMaxLifespan" : "0",
+    "oauth2DevicePollingInterval" : "5",
+    "clientSessionIdleTimeout" : "0",
+    "actionTokenGeneratedByUserLifespan-execute-actions" : "",
+    "actionTokenGeneratedByUserLifespan-verify-email" : "",
+    "clientOfflineSessionIdleTimeout" : "0",
+    "actionTokenGeneratedByUserLifespan-reset-credentials" : "",
+    "cibaInterval" : "5",
+    "realmReusableOtpCode" : "false",
+    "cibaExpiresIn" : "120",
+    "oauth2DeviceCodeLifespan" : "600",
+    "actionTokenGeneratedByUserLifespan-idp-verify-account-via-email" : "",
+    "parRequestUriLifespan" : "60",
+    "clientSessionMaxLifespan" : "0",
+    "shortVerificationUri" : ""
+  },
+  "keycloakVersion" : "24.0.5",
+  "userManagedAccessAllowed" : false,
+  "clientProfiles" : {
+    "profiles" : [ ]
+  },
+  "clientPolicies" : {
+    "policies" : [ ]
+  }
+}
\ No newline at end of file
diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar
new file mode 100644
index 0000000000000000000000000000000000000000..a23243d39509ec3821219e5799a25740c93e2ca1
GIT binary patch
literal 10130
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
Wz?+o~q)324fZ-Yo1H&>U5Dx%g8Hq0d

literal 0
HcmV?d00001

diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java
new file mode 100644
index 0000000000..16f45aec4d
--- /dev/null
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java
@@ -0,0 +1,46 @@
+package at.tuwien.api.auth;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.*;
+import lombok.extern.jackson.Jacksonized;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+@Builder
+@EqualsAndHashCode
+@NoArgsConstructor
+@AllArgsConstructor
+@Jacksonized
+@ToString
+public class CreateUserDto {
+
+    @NotNull
+    @Schema(example = "3b91bc36-3eae-4662-a4be-8993624ab0cb", description = "The user id generated by Keycloak")
+    private UUID id;
+
+    @NotNull
+    @JsonProperty("ldap_id")
+    @Schema(example = "ea022d6d-b4a4-42f3-836f-ff4e596a527a", description = "The user id generated by OpenLDAP")
+    private UUID ldapId;
+
+    @NotBlank
+    @Schema(example = "user")
+    private String username;
+
+    @JsonProperty("given_name")
+    @Schema(example = "foo")
+    private String givenName;
+
+    @JsonProperty("family_name")
+    @Schema(example = "bar")
+    private String familyName;
+
+    @Schema(example = "foo.bar@example.com")
+    private String email;
+
+}
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/DbrepoMetadataServiceApplication.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/DbrepoMetadataServiceApplication.java
index bd979054e6..e931ce7509 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/DbrepoMetadataServiceApplication.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/DbrepoMetadataServiceApplication.java
@@ -5,11 +5,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
-import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 @EnableJpaAuditing
-@EnableScheduling
 @EnableTransactionManagement
 @EntityScan(basePackages = {"at.tuwien.entities"})
 @EnableJpaRepositories(basePackages = {"at.tuwien.repository"})
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
index c4dd579b3d..51f323c30f 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
@@ -1,5 +1,6 @@
 package at.tuwien.endpoints;
 
+import at.tuwien.api.auth.CreateUserDto;
 import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.api.user.UserBriefDto;
 import at.tuwien.api.user.UserDto;
@@ -89,6 +90,62 @@ public class UserEndpoint extends AbstractEndpoint {
         }
     }
 
+    @PostMapping
+    @Transactional(rollbackFor = {Exception.class})
+    @PreAuthorize("hasAuthority('system')")
+    @Observed(name = "dbrepo_user_create")
+    @Operation(summary = "Create user",
+            description = "This webhook is called from the auth service to add a user to the metadata database. Requires role `system`.",
+            hidden = true)
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "201",
+                    description = "Created user",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = UserDto.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Parameters are not well-formed (likely email)",
+                    content = {@Content(mediaType = "application/json")}),
+            @ApiResponse(responseCode = "403",
+                    description = "Internal authentication to the auth service is invalid",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Default role not found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "409",
+                    description = "User with username already exists",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "417",
+                    description = "User with e-mail already exists",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "502",
+                    description = "Failed to create in auth service",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "503",
+                    description = "Failed to create in auth service",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+    })
+    public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody CreateUserDto data)
+            throws UserExistsException, EmailExistsException, AuthServiceException, AuthServiceConnectionException,
+            UserNotFoundException, CredentialsInvalidException {
+        log.debug("endpoint create user, data.id={}, data.username={}", data.getId(), data.getUsername());
+        return ResponseEntity.status(HttpStatus.CREATED)
+                .body(userMapper.userToUserBriefDto(
+                        userService.create(data)));
+    }
+
     @GetMapping("/{userId}")
     @Transactional(readOnly = true)
     @PreAuthorize("isAuthenticated()")
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java
index 7240b8e1d1..b3612fcc0f 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java
@@ -9,8 +9,6 @@ import lombok.extern.log4j.Log4j2;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Primary;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
@@ -24,13 +22,6 @@ public class KeycloakUtils {
     private final KeycloakConfig keycloakConfig;
     private final MetadataMapper metadataMapper;
 
-    @Bean
-    @Primary
-    public Keycloak keycloak() {
-        return Keycloak.getInstance(keycloakConfig.getKeycloakEndpoint(), "master",
-                keycloakConfig.getKeycloakUsername(), keycloakConfig.getKeycloakPassword(), "admin-cli");
-    }
-
     @Autowired
     public KeycloakUtils(Keycloak keycloak, KeycloakConfig keycloakConfig, MetadataMapper metadataMapper) {
         this.keycloak = keycloak;
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java
index c1ebc38007..4b62b61dcb 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java
@@ -1,16 +1,12 @@
 package at.tuwien.config;
 
 import lombok.Getter;
-import lombok.extern.log4j.Log4j2;
-import org.keycloak.OAuth2Constants;
 import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.KeycloakBuilder;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.client.RestTemplate;
 
-@Log4j2
 @Getter
 @Configuration
 public class KeycloakConfig {
@@ -39,14 +35,6 @@ public class KeycloakConfig {
 
     @Bean
     public Keycloak keycloak() {
-        return KeycloakBuilder.builder()
-                .serverUrl(keycloakEndpoint)
-                .realm("master")
-                .clientId("admin-cli")
-                .grantType(OAuth2Constants.PASSWORD)
-                .scope(OAuth2Constants.SCOPE_OPENID)
-                .username(keycloakUsername)
-                .password(keycloakPassword)
-                .build();
+        return Keycloak.getInstance(keycloakEndpoint, "master", keycloakUsername, keycloakPassword, "admin-cli");
     }
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/KeycloakListener.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/KeycloakListener.java
deleted file mode 100644
index f3028b2420..0000000000
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/KeycloakListener.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package at.tuwien.listener;
-
-public interface KeycloakListener {
-    void syncUsers();
-}
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/KeycloakListenerImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/KeycloakListenerImpl.java
deleted file mode 100644
index 71fb09e172..0000000000
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/KeycloakListenerImpl.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package at.tuwien.listener.impl;
-
-import at.tuwien.config.KeycloakConfig;
-import at.tuwien.entities.user.User;
-import at.tuwien.listener.KeycloakListener;
-import at.tuwien.repository.UserRepository;
-import at.tuwien.service.UserService;
-import lombok.extern.log4j.Log4j2;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.keycloak.admin.client.Keycloak;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-import java.util.UUID;
-
-@Log4j2
-@Component
-public class KeycloakListenerImpl implements KeycloakListener {
-
-    private final Keycloak keycloak;
-    private final UserService userService;
-    private final KeycloakConfig keycloakConfig;
-    private final UserRepository userRepository;
-
-    @Autowired
-    public KeycloakListenerImpl(Keycloak keycloak, UserService userService, KeycloakConfig keycloakConfig,
-                                UserRepository userRepository) {
-        this.keycloak = keycloak;
-        this.userService = userService;
-        this.keycloakConfig = keycloakConfig;
-        this.userRepository = userRepository;
-    }
-
-    @Override
-    @Scheduled(fixedRate = 5000)
-    public void syncUsers() {
-        final List<String> knownUsernames = userService.findAll()
-                .stream()
-                .map(User::getUsername)
-                .toList();
-        final List<User> unknownUsers = keycloak.realm(keycloakConfig.getRealm())
-                .users()
-                .list()
-                .stream()
-                .filter(user -> !knownUsernames.contains(user.getUsername()))
-                .map(user -> User.builder()
-                        .id(UUID.fromString(user.firstAttribute("LDAP_ID")))
-                        .keycloakId(UUID.fromString(user.getId()))
-                        .username(user.getUsername())
-                        .theme("light")
-                        .mariadbPassword(userService.getMariaDbPassword(RandomStringUtils.randomAlphabetic(10))) /* user needs to set it later to access */
-                        .language("en")
-                        .firstname(user.getFirstName())
-                        .lastname(user.getLastName())
-                        .isInternal(false)
-                        .build())
-                .toList();
-        if (unknownUsers.isEmpty()) {
-            return;
-        }
-        userRepository.saveAll(unknownUsers);
-        log.info("Synced {} unknown user(s) to metadata database", unknownUsers.size());
-    }
-}
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
index 4a3c80028a..581641a93a 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
@@ -1,8 +1,10 @@
 package at.tuwien.service;
 
+import at.tuwien.api.auth.CreateUserDto;
 import at.tuwien.api.user.UserPasswordDto;
 import at.tuwien.api.user.UserUpdateDto;
 import at.tuwien.entities.user.User;
+import at.tuwien.exception.AuthServiceConnectionException;
 import at.tuwien.exception.AuthServiceException;
 import at.tuwien.exception.UserExistsException;
 import at.tuwien.exception.UserNotFoundException;
@@ -39,6 +41,14 @@ public interface UserService {
      */
     User findById(UUID id) throws UserNotFoundException;
 
+    /**
+     * Creates a user in the metadata database managed by Keycloak in the given realm.
+     *
+     * @param data The user data.
+     * @return The user, if successful.
+     */
+    User create(CreateUserDto data) throws UserNotFoundException, AuthServiceException;
+
     /**
      * Updates the user information for a user with given id in the metadata database.
      *
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
index 7d455ad4e2..1d582bb975 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
@@ -1,5 +1,6 @@
 package at.tuwien.service.impl;
 
+import at.tuwien.api.auth.CreateUserDto;
 import at.tuwien.api.user.UserPasswordDto;
 import at.tuwien.api.user.UserUpdateDto;
 import at.tuwien.entities.user.User;
@@ -7,11 +8,11 @@ import at.tuwien.exception.AuthServiceException;
 import at.tuwien.exception.UserExistsException;
 import at.tuwien.exception.UserNotFoundException;
 import at.tuwien.gateway.KeycloakGateway;
-import at.tuwien.mapper.MetadataMapper;
 import at.tuwien.repository.UserRepository;
 import at.tuwien.service.UserService;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -24,14 +25,11 @@ import java.util.UUID;
 @Service
 public class UserServiceImpl implements UserService {
 
-    private final MetadataMapper metadataMapper;
     private final UserRepository userRepository;
     private final KeycloakGateway keycloakGateway;
 
     @Autowired
-    public UserServiceImpl(MetadataMapper metadataMapper, UserRepository userRepository,
-                           KeycloakGateway keycloakGateway) {
-        this.metadataMapper = metadataMapper;
+    public UserServiceImpl(UserRepository userRepository, KeycloakGateway keycloakGateway) {
         this.userRepository = userRepository;
         this.keycloakGateway = keycloakGateway;
     }
@@ -66,6 +64,26 @@ public class UserServiceImpl implements UserService {
         return optional.get();
     }
 
+    @Override
+    public User create(CreateUserDto data) throws UserNotFoundException, AuthServiceException {
+        /* create at authentication service */
+        final User entity = User.builder()
+                .id(data.getLdapId())
+                .keycloakId(data.getId())
+                .username(data.getUsername())
+                .theme("light")
+                .mariadbPassword(getMariaDbPassword(RandomStringUtils.randomAlphabetic(10))) /* user needs to set it later to access */
+                .language("en")
+                .firstname(data.getGivenName())
+                .lastname(data.getFamilyName())
+                .isInternal(false)
+                .build();
+        /* save in metadata database */
+        final User user = userRepository.save(entity);
+        log.info("Created user with id: {}", user.getId());
+        return user;
+    }
+
     @Override
     public User modify(User user, UserUpdateDto data) throws UserNotFoundException, AuthServiceException {
         user.setFirstname(data.getFirstname());
diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue
index acb5b61d4d..a26c6d2539 100644
--- a/dbrepo-ui/layouts/default.vue
+++ b/dbrepo-ui/layouts/default.vue
@@ -357,9 +357,6 @@ export default {
     if (this.$route.query && this.$route.query.q) {
       this.search = this.$route.query.q
     }
-    if (!this.cacheUser) {
-      return
-    }
     this.setTheme()
     this.setLocale()
   },
diff --git a/dbrepo-ui/pages/user/info.vue b/dbrepo-ui/pages/user/info.vue
index 470b7bc438..8674c57e2d 100644
--- a/dbrepo-ui/pages/user/info.vue
+++ b/dbrepo-ui/pages/user/info.vue
@@ -222,7 +222,7 @@ export default {
       }
       const userService = useUserService()
       userService.update(this.cacheUser.uid, payload)
-        .then((user) => {
+        .then(() => {
           console.info('Updated user information')
           const toast = useToastInstance()
           toast.success(this.$t('success.user.info'))
@@ -245,8 +245,12 @@ export default {
               break
           }
         })
-        .catch(() => {
-          this.loadingUpdate = false
+        .catch(({code, message}) => {
+          const toast = useToastInstance()
+          if (typeof code !== 'string') {
+            return
+          }
+          toast.error(message)
         })
         .finally(() => {
           this.loadingUpdate = false
diff --git a/docker-compose.yml b/docker-compose.yml
index bd7e68eb9d..9176f6404a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -85,6 +85,7 @@ services:
       - ./dbrepo-auth-service/import-realms.sh:/docker-entrypoint-initdb.d/import-realms.sh
       - ./dbrepo-auth-service/master-realm.json:/opt/keycloak/data/import/master-realm.json
       - ./dbrepo-auth-service/dbrepo-realm.json:/opt/keycloak/data/import/dbrepo-realm.json
+      - ./dbrepo-auth-service/listeners/target/create-event-listener.jar:/opt/bitnami/keycloak/providers/create-event-listener.jar
     ports:
       - "8080:8080"
     environment:
@@ -95,6 +96,9 @@ services:
       KEYCLOAK_DATABASE_NAME: "${AUTH_DB_NAME:-keycloak}"
       KEYCLOAK_DATABASE_USER: "${AUTH_DB_USERNAME:-keycloak}"
       KEYCLOAK_DATABASE_PASSWORD: "${AUTH_DB_PASSWORD:-dbrepo}"
+      METADATA_SERVICE_ENDPOINT: "${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}/api/user"
+      SYSTEM_USERNAME: "${SYSTEM_USERNAME:-admin}"
+      SYSTEM_PASSWORD: "${SYSTEM_PASSWORD:-admin}"
     healthcheck:
       test: curl -fsS http://localhost:8080/realms/master
       interval: 10s
diff --git a/helm/dbrepo/files/create-event-listener.jar b/helm/dbrepo/files/create-event-listener.jar
new file mode 100644
index 0000000000000000000000000000000000000000..a23243d39509ec3821219e5799a25740c93e2ca1
GIT binary patch
literal 10130
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
Wz?+o~q)324fZ-Yo1H&>U5Dx%g8Hq0d

literal 0
HcmV?d00001

diff --git a/helm/dbrepo/templates/auth-configmap.yaml b/helm/dbrepo/templates/auth-configmap.yaml
index 534e901b42..28ad32d664 100644
--- a/helm/dbrepo/templates/auth-configmap.yaml
+++ b/helm/dbrepo/templates/auth-configmap.yaml
@@ -4,6 +4,9 @@ kind: ConfigMap
 metadata:
   name: auth-service-config
   namespace: {{ include "common.names.namespace" . | quote }}
+binaryData:
+  create-event-listener.jar: |-
+    {{ .Files.Get "files/create-event-listener.jar" | b64enc }}
 data:
   dbrepo-realm.json: |-
     {
@@ -2336,7 +2339,7 @@ data:
       "adminTheme" : "",
       "emailTheme" : "",
       "eventsEnabled" : false,
-      "eventsListeners" : [ "jboss-logging" ],
+      "eventsListeners" : [ "create-event-listener", "jboss-logging" ],
       "enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_CONSENT_ERROR", "GRANT_CONSENT", "VERIFY_PROFILE_ERROR", "REMOVE_TOTP", "REVOKE_GRANT", "UPDATE_TOTP", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", "RESTART_AUTHENTICATION", "IMPERSONATE", "UPDATE_PROFILE_ERROR", "LOGIN", "OAUTH2_DEVICE_VERIFY_USER_CODE", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "TOKEN_EXCHANGE", "AUTHREQID_TO_TOKEN", "LOGOUT", "REGISTER", "DELETE_ACCOUNT_ERROR", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "DELETE_ACCOUNT", "UPDATE_PASSWORD", "CLIENT_DELETE", "FEDERATED_IDENTITY_LINK_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN", "CLIENT_DELETE_ERROR", "VERIFY_EMAIL", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "EXECUTE_ACTIONS", "REMOVE_FEDERATED_IDENTITY_ERROR", "TOKEN_EXCHANGE_ERROR", "PERMISSION_TOKEN", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "SEND_VERIFY_EMAIL", "OAUTH2_DEVICE_AUTH", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "OAUTH2_DEVICE_CODE_TO_TOKEN", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "EXECUTE_ACTION_TOKEN", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "CLIENT_UPDATE_ERROR", "AUTHREQID_TO_TOKEN_ERROR", "UPDATE_PROFILE", "CLIENT_REGISTER_ERROR", "FEDERATED_IDENTITY_LINK", "SEND_IDENTITY_PROVIDER_LINK", "SEND_VERIFY_EMAIL_ERROR", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "OAUTH2_DEVICE_AUTH_ERROR", "UPDATE_CONSENT", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "CUSTOM_REQUIRED_ACTION_ERROR", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "VERIFY_PROFILE", "GRANT_CONSENT_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ],
       "adminEventsEnabled" : false,
       "adminEventsDetailsEnabled" : false,
diff --git a/make/build.mk b/make/build.mk
index 3a10b568e9..270b2cee6f 100644
--- a/make/build.mk
+++ b/make/build.mk
@@ -14,6 +14,10 @@ build-data-service: ## Build the Data Service.
 build-metadata-service: ## Build the Metadata Service.
 	mvn -f ./dbrepo-metadata-service/pom.xml clean package -DskipTests
 
+.PHONY: build-auth-event-listener
+build-auth-event-listener: ## Build the Auth Service Event Listener.
+	mvn -f ./dbrepo-auth-service/listeners/pom.xml clean package -DskipTests
+
 .PHONY: build-ui
 build-ui: ## Build the UI.
 	bun --cwd ./dbrepo-ui build
diff --git a/make/dev.mk b/make/dev.mk
index c20b4dd229..1c7d62d7ee 100644
--- a/make/dev.mk
+++ b/make/dev.mk
@@ -1,7 +1,7 @@
 ##@ Development
 
 .PHONY: start-dev
-start-dev: build-images ## Start the development deployment.
+start-dev: build-images build-auth-event-listener ## Start the development deployment.
 	docker container stop dbrepo-gateway-service || true
 	docker container rm dbrepo-gateway-service || true
 	docker compose up -d
-- 
GitLab