diff --git a/README.md b/README.md
index 1c70ece8208d35f3dcc82a14c963211d7b1258e2..27d0110791315c6e801ddde881588825d5430e8f 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,18 @@ This project uses Quarkus, the Supersonic Subatomic Java Framework.
 
 If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ .
 
+## Configuring the application
+This properties mist be configured to run the application
+
+quarkus.mongodb.connection-string=<The connection string for the mongo db database>
+quarkus.mongodb.database=<name of the mongo db database>
+usermanager.keycloak.sync.cron=<default is "0 15 2 * * ?" >
+usermanager.keycloak.api.user=< the name of the keycloak admin api user, default: goofyApiUser>
+usermanager.keycloak.api.password=< the password of the keycloak admin api user>
+usermanager.keycloak.api.realm=<The name of the realm>
+usermanager.keycloak.api.organisations-einheit-id-key=< The key where the organisationsEinheitId of the group is saved, default is 'organisationseinheitId'>
+
+
 ## Running the application in dev mode
 
 You can run your application in dev mode that enables live coding using:
@@ -65,3 +77,11 @@ Easily start your Reactive RESTful Web Services
 Monitor your application's health using SmallRye Health
 
 [Related guide section...](https://quarkus.io/guides/smallrye-health)
+
+## Best parctice
+
+### User package-private fields for injected fields
+
+This involves injection fields, constructors and initializers, observer methods, producer methods and fields, disposers and interceptor methods.
+
+[See section 2 of quarkus guide ](https://quarkus.io/guides/cdi-reference#native-executables-and-private-members)
diff --git a/lombok.config b/lombok.config
new file mode 100644
index 0000000000000000000000000000000000000000..4cbb865834f6128b8ddc16fc9b1966af99e52653
--- /dev/null
+++ b/lombok.config
@@ -0,0 +1,6 @@
+lombok.log.fieldName=LOG
+lombok.log.slf4j.flagUsage = ERROR
+lombok.log.log4j.flagUsage = ERROR
+lombok.data.flagUsage = ERROR
+lombok.nonNull.exceptionType = IllegalArgumentException
+lombok.addLombokGeneratedAnnotation = true
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3daf0219a83806d133fa5baba948b860e95527a9..2eedc3b34b128ce7a269b8ff82f5f49f22cba7a9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,10 +1,7 @@
 <?xml version="1.0"?>
-<project
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
-	xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 	<modelVersion>4.0.0</modelVersion>
-	
+
 	<groupId>de.itvsh.kop.user</groupId>
 	<artifactId>user-manager</artifactId>
 	<version>0.2.0-SNAPSHOT</version>
@@ -12,14 +9,14 @@
 
 	<properties>
 		<skipITs>true</skipITs>
-		
+
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 		<compiler-plugin.version>3.8.1</compiler-plugin.version>
 		<maven.compiler.release>17</maven.compiler.release>
-		
-		<!-- <kop-common.version>1.1.4-SNAPSHOT</kop-common.version> -->
-		
+
+		<kop-common.version>1.1.4-SNAPSHOT</kop-common.version>
+
 		<jacoco.plugin.version>0.8.8</jacoco.plugin.version>
 		<quarkus.platform.version>2.10.3.Final</quarkus.platform.version>
 		<surefire-plugin.version>3.0.0-M7</surefire-plugin.version>
@@ -27,10 +24,10 @@
 		<git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>
 		<quarkus-logging-json.version>1.1.1</quarkus-logging-json.version>
 		
-		<!-- TODO Properties entfernen, sobald der Testcode draussen ist -->	
-		<org.assertj-core.version>3.23.1</org.assertj-core.version>	
-		<org.projectlombok.version>1.18.24</org.projectlombok.version>	
-		<!--  -->
+		<!-- Versions already declared in kop-common-dependencies bom -> use bom as parent!? -->
+		<mapstruct.version>1.5.1.Final</mapstruct.version>
+		<lombok.version>1.18.24</lombok.version>
+		<commons-lang3.version>3.12.0</commons-lang3.version>
 	</properties>
 
 	<dependencyManagement>
@@ -42,17 +39,17 @@
 				<type>pom</type>
 				<scope>import</scope>
 			</dependency>
-			<!-- <dependency>
+			<dependency>
 				<groupId>de.itvsh.kop.common</groupId>
 				<artifactId>kop-common-dependencies</artifactId>
 				<version>${kop-common.version}</version>
 				<type>pom</type>
 				<scope>import</scope>
-			</dependency>-->
+			</dependency>
 		</dependencies>
 	</dependencyManagement>
 
-	<dependencies>		
+	<dependencies>
 		<!-- Quarkus -->
 		<dependency>
 			<groupId>io.quarkus</groupId>
@@ -67,88 +64,124 @@
 			<artifactId>quarkus-config-yaml</artifactId>
 		</dependency>
 		<dependency>
-		    <groupId>io.quarkiverse.loggingjson</groupId>
-		    <artifactId>quarkus-logging-json</artifactId>
-		    <version>${quarkus-logging-json.version}</version>
+			<groupId>io.quarkus</groupId>
+			<artifactId>quarkus-micrometer-registry-prometheus</artifactId>
 		</dependency>
 		<dependency>
-		    <groupId>io.quarkus</groupId>
-		    <artifactId>quarkus-micrometer-registry-prometheus</artifactId>
+			<groupId>io.quarkus</groupId>
+			<artifactId>quarkus-smallrye-health</artifactId>
 		</dependency>
 		<dependency>
-		    <groupId>io.quarkus</groupId>
-		    <artifactId>quarkus-smallrye-health</artifactId>
+			<groupId>io.quarkus</groupId>
+			<artifactId>quarkus-keycloak-admin-client</artifactId>
 		</dependency>
-			
-		<!-- Test -->
 		<dependency>
 			<groupId>io.quarkus</groupId>
-			<artifactId>quarkus-junit5</artifactId>
-			<scope>test</scope>
+			<artifactId>quarkus-mongodb-client</artifactId>
 		</dependency>
 		<dependency>
-			<groupId>io.rest-assured</groupId>
-			<artifactId>rest-assured</artifactId>
-			<scope>test</scope>
+			<groupId>io.quarkus</groupId>
+			<artifactId>quarkus-mongodb-panache</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.quarkus</groupId>
+			<artifactId>quarkus-resteasy-reactive</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.quarkus</groupId>
+			<artifactId>quarkus-scheduler</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-collections4</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.quarkus</groupId>
+			<artifactId>quarkus-oidc</artifactId>
 		</dependency>
 		
+		<!-- Logging -->
+		<dependency>
+			<groupId>io.quarkiverse.loggingjson</groupId>
+			<artifactId>quarkus-logging-json</artifactId>
+			<version>${quarkus-logging-json.version}</version>
+		</dependency>
+		<dependency>
+		    <groupId>org.jboss.logmanager</groupId>
+		    <artifactId>log4j2-jboss-logmanager</artifactId> 
+		</dependency>
+
 		<!-- Tools -->
 		<dependency>
 			<groupId>io.quarkus</groupId>
 			<artifactId>quarkus-jacoco</artifactId>
 			<scope>test</scope>
 		</dependency>
-		 <dependency>
+		<dependency>
 			<groupId>io.quarkus</groupId>
 			<artifactId>quarkus-container-image-jib</artifactId>
 		</dependency>
-		
-		<!-- TODO Dependency entfernen, sobald der Testcode draussen ist -->
+		<dependency>
+			<groupId>org.mapstruct</groupId>
+			<artifactId>mapstruct</artifactId>
+			<scope>provided</scope>
+		</dependency>
 		<dependency>
 			<groupId>io.quarkus</groupId>
-			<artifactId>quarkus-spring-web</artifactId>
+			<artifactId>quarkus-test-keycloak-server</artifactId>
+			<scope>test</scope>
 		</dependency>
 		<dependency>
-			<groupId>org.projectlombok</groupId>
-			<artifactId>lombok</artifactId>
-			<version>${org.projectlombok.version}</version>
+			<groupId>org.mapstruct</groupId>
+			<artifactId>mapstruct-processor</artifactId>
+			<version>${mapstruct.version}</version>
 			<scope>provided</scope>
 		</dependency>
-		<!-- <dependency>
-			<groupId>org.testcontainers</groupId>
-			<artifactId>mongodb</artifactId>
+		<dependency>
+			<groupId>com.thedeanda</groupId>
+			<artifactId>lorem</artifactId>
 			<scope>test</scope>
 		</dependency>
+
+		<!-- Test -->
 		<dependency>
 			<groupId>io.quarkus</groupId>
-			<artifactId>quarkus-mongodb-panache</artifactId>
-		</dependency> -->
+			<artifactId>quarkus-junit5</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+		    <groupId>io.quarkus</groupId>
+		    <artifactId>quarkus-junit5-mockito</artifactId>
+		    <scope>test</scope>
+		</dependency>
 		<dependency>
 			<groupId>io.quarkus</groupId>
-			<artifactId>quarkus-resteasy-reactive</artifactId>
-		</dependency> 
+			<artifactId>quarkus-panache-mock</artifactId>
+			<scope>test</scope>
+		</dependency>
 		<dependency>
-			<groupId>org.testcontainers</groupId>
-			<artifactId>testcontainers</artifactId>
+			<groupId>io.rest-assured</groupId>
+			<artifactId>rest-assured</artifactId>
 			<scope>test</scope>
 		</dependency>
 		<dependency>
 			<groupId>org.assertj</groupId>
 			<artifactId>assertj-core</artifactId>
-			<version>${org.assertj-core.version}</version>
 			<scope>test</scope>
-		</dependency> 
-		
-		<!--
-		<dependency>
-			<groupId>io.quarkus</groupId>
-			<artifactId>quarkus-container-image-docker</artifactId>
 		</dependency>
 		<dependency>
-			<groupId>io.quarkus</groupId>
-			<artifactId>quarkus-container-image-docker-deployment</artifactId>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-junit-jupiter</artifactId>
+			<scope>test</scope>
 		</dependency>
-		  -->
 	</dependencies>
 
 	<build>
@@ -172,10 +205,30 @@
 				<artifactId>maven-compiler-plugin</artifactId>
 				<version>${compiler-plugin.version}</version>
 				<configuration>
+					<fork>true</fork>
+						<annotationProcessorPaths>
+							<path>
+								<groupId>org.projectlombok</groupId>
+								<artifactId>lombok</artifactId>
+								<version>${lombok.version}</version>
+							</path>
+							<path>
+								<groupId>org.mapstruct</groupId>
+								<artifactId>mapstruct-processor</artifactId>
+								<version>${mapstruct.version}</version>
+							</path>
+							<!-- other annotation processors -->
+						</annotationProcessorPaths>
 					<showWarnings>true</showWarnings>
 					<compilerArgs>
 						<arg>-parameters</arg>
-					</compilerArgs>
+						<compilerArg>
+								-Amapstruct.defaultComponentModel=cdi
+							</compilerArg>
+							<compilerArg>
+								-Amapstruct.unmappedTargetPolicy=WARN
+							</compilerArg>
+					</compilerArgs>					
 				</configuration>
 			</plugin>
 			<plugin>
diff --git a/src/main/java/de/itvsh/kop/user/MyLivenessCheck.java b/src/main/java/de/itvsh/kop/user/LivenessCheck.java
similarity index 84%
rename from src/main/java/de/itvsh/kop/user/MyLivenessCheck.java
rename to src/main/java/de/itvsh/kop/user/LivenessCheck.java
index 96ba689ae99563a1209225ca2eec2d456f6ebf74..fd0e082d495fa4834483ec6540cae8ce04d21f55 100644
--- a/src/main/java/de/itvsh/kop/user/MyLivenessCheck.java
+++ b/src/main/java/de/itvsh/kop/user/LivenessCheck.java
@@ -5,7 +5,7 @@ import org.eclipse.microprofile.health.HealthCheckResponse;
 import org.eclipse.microprofile.health.Liveness;
 
 @Liveness
-public class MyLivenessCheck implements HealthCheck {
+public class LivenessCheck implements HealthCheck {
 
 	@Override
 	public HealthCheckResponse call() {
diff --git a/src/main/java/de/itvsh/kop/user/RemoteUserIterator.java b/src/main/java/de/itvsh/kop/user/RemoteUserIterator.java
new file mode 100644
index 0000000000000000000000000000000000000000..93958622763c86fb9c693f5316876d93434382e8
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/RemoteUserIterator.java
@@ -0,0 +1,47 @@
+package de.itvsh.kop.user;
+
+import java.util.Iterator;
+
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.UsersResource;
+import org.keycloak.representations.idm.UserRepresentation;
+
+import com.cronutils.utils.StringUtils;
+
+public class RemoteUserIterator implements Iterator<UserRepresentation> {
+
+	private static final int PAGE_SIZE = 10;// TODO
+
+	private final UsersResource users;
+	private final int count;
+
+	private int step = 0;
+	private Iterator<UserRepresentation> loadedUserIterator;
+
+	public RemoteUserIterator(RealmResource resource) {
+		users = resource.users();
+		count = users.count();
+		loadNextStep();
+	}
+
+	@Override
+	public boolean hasNext() {
+		if (loadedUserIterator.hasNext()) {
+			return true;
+		}
+		if (count > step * PAGE_SIZE) {
+			loadNextStep();
+			return loadedUserIterator.hasNext();
+		}
+		return false;
+	}
+
+	private void loadNextStep() {
+		loadedUserIterator = users.search(StringUtils.EMPTY, step * PAGE_SIZE, ++step * PAGE_SIZE).iterator();
+	}
+
+	@Override
+	public UserRepresentation next() {
+		return loadedUserIterator.next();
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/User.java b/src/main/java/de/itvsh/kop/user/User.java
index 555588442b668e7d76741fd350ee10febb737a32..9b4f2dcb7babc42d9fe48757b29ec021fa3f63d0 100644
--- a/src/main/java/de/itvsh/kop/user/User.java
+++ b/src/main/java/de/itvsh/kop/user/User.java
@@ -1,17 +1,46 @@
 package de.itvsh.kop.user;
 
+import java.util.Collection;
+import java.util.Date;
+
+import org.bson.codecs.pojo.annotations.BsonId;
+import org.bson.types.ObjectId;
+
+import io.quarkus.mongodb.panache.common.MongoEntity;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
 
-@Builder
+@Builder(toBuilder = true)
 @NoArgsConstructor
 @AllArgsConstructor
 @Getter
+@Setter
+@ToString
 public class User {
 
-	public String id;
-	public String name;
-	public String lastName;
+	public static final String EXTERNAL_ID_FIELD = "externalId";
+	public static final String EMAIL_FIELD = "email";
+	public static final String DELETED_FIELD = "deleted";
+	public static final String LAST_SYNC_TIMESTAMP_FIELD = "lastSyncTimestamp";
+
+	@BsonId
+	private ObjectId id;
+	private String externalId;
+	private String firstName;
+	private String lastName;
+	private String username;
+	private String email;
+	private Collection<String> roles;
+	private Collection<String> organisationsEinheitIds;
+	private Date createdAt;
+	private Long lastSyncTimestamp;
+	private boolean deleted;
+
+	public String getFullName() {
+		return String.format("%s %s", firstName, lastName);
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/UserController.java b/src/main/java/de/itvsh/kop/user/UserController.java
deleted file mode 100644
index 7489e73fe5adcaa73034ae1e21de72ad0e8de587..0000000000000000000000000000000000000000
--- a/src/main/java/de/itvsh/kop/user/UserController.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package de.itvsh.kop.user;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
-
-@Path("/api/user")
-public class UserController {
-
-	@Inject
-	private UserService userService;
-
-	@Path("/{userId}")
-	@GET
-	@Produces(MediaType.TEXT_PLAIN)
-	public ResponseEntity<String> getById(@PathVariable String userId) {
-		var user = userService.getById(userId);
-
-		return ResponseEntity.ok(user.getName());
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/UserRepository.java b/src/main/java/de/itvsh/kop/user/UserRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..06ea421478689d743906a680a75d0733b300851e
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/UserRepository.java
@@ -0,0 +1,29 @@
+package de.itvsh.kop.user;
+
+import java.util.Optional;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import org.apache.commons.lang3.StringUtils;
+
+import io.quarkus.mongodb.panache.PanacheMongoRepository;
+
+@ApplicationScoped
+public class UserRepository implements PanacheMongoRepository<User> {
+
+	public Optional<User> findByExternalId(String externalId) {
+		return find(User.EXTERNAL_ID_FIELD, externalId).firstResultOptional();
+	}
+
+	public Optional<User> findByEmail(String email) {
+		if (StringUtils.isNotEmpty(email)) {
+			return find(User.EMAIL_FIELD, email).firstResultOptional();
+		} else {
+			return Optional.empty();
+		}
+	}
+
+	public long updateUnsyncedUsers(long lastSyncTimestamp) {
+		return update(User.DELETED_FIELD, true).where(User.LAST_SYNC_TIMESTAMP_FIELD + " < ?1", lastSyncTimestamp);
+	}
+}
diff --git a/src/main/java/de/itvsh/kop/user/UserResourceMapper.java b/src/main/java/de/itvsh/kop/user/UserResourceMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa1bc9b91404c371605623a97412eb18173667ca
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/UserResourceMapper.java
@@ -0,0 +1,103 @@
+package de.itvsh.kop.user;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.representations.idm.ClientMappingsRepresentation;
+import org.keycloak.representations.idm.GroupRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.ReportingPolicy;
+
+import de.itvsh.kop.user.keycloak.KeycloakApiProperties;
+
+@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
+public abstract class UserResourceMapper {
+
+	@Inject
+	KeycloakApiProperties properties;
+
+	@Inject
+	RealmResource realm;
+
+	@Mapping(target = "createdAt", expression = "java(mapCreatedAt(userRes))")
+	@Mapping(target = "email", expression = "java(mapEmail(userRes))")
+	@Mapping(target = "firstName", expression = "java(mapFirstName(userRes))")
+	@Mapping(target = "lastName", expression = "java(mapLastName(userRes))")
+	@Mapping(target = "username", expression = "java(mapUsername(userRes))")
+	@Mapping(target = "externalId", expression = "java(mapId(userRes))")
+	@Mapping(target = "organisationsEinheitIds", expression = "java(mapOrganisationsEinheitIds(userRes))")
+	@Mapping(target = "roles", expression = "java(mapRoles(userRes))")
+	@Mapping(target = "lastSyncTimestamp", ignore = true)
+	@Mapping(target = "deleted", ignore = true)
+	public abstract User toKopUser(UserResource userRes);
+
+	Date mapCreatedAt(UserResource userRes) {
+		var createdAt = userRes.toRepresentation().getCreatedTimestamp();
+
+		return createdAt != null ? new Date(createdAt) : new Date();
+	}
+
+	Set<String> mapOrganisationsEinheitIds(UserResource userRes) {
+		var groups = userRes.groups();
+		var organisationsEinheitIds = getOrganisationsEinheitIdsFromGroups(groups);
+		return new HashSet<>(organisationsEinheitIds);
+	}
+
+	private List<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) {
+		return groups.stream()
+				.map(group -> {
+					var groupFromRealm = realm.getGroupByPath(group.getPath());
+					return groupFromRealm != null ? groupFromRealm.getAttributes() : null;
+				})
+				.filter(Objects::nonNull)
+				.map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey()))
+				.filter(Objects::nonNull)
+				.map(attributeValues -> attributeValues.get(0))
+				.toList();
+	}
+
+	List<String> mapRoles(UserResource userRes) {
+		var roleRepresentation = Optional.ofNullable(userRes.roles().getAll().getClientMappings())
+				.filter(Objects::nonNull)
+				.filter(map -> map.containsKey(properties.client()))
+				.map(map -> map.get(properties.client()))
+				.map(ClientMappingsRepresentation::getMappings)
+				.orElseGet(Collections::emptyList);
+
+		return roleRepresentation.stream().map(RoleRepresentation::getName).toList();
+	}
+
+	String mapId(UserResource userRes) {
+		var userRepresentation = userRes.toRepresentation();
+		var attributes = userRepresentation.getAttributes();
+		var id = attributes != null ? attributes.get(properties.ldapIdKey()) : null;
+		return id != null ? id.get(0) : userRepresentation.getId();
+	}
+
+	String mapEmail(UserResource userRes) {
+		return userRes.toRepresentation().getEmail();
+	}
+
+	String mapFirstName(UserResource userRes) {
+		return userRes.toRepresentation().getFirstName();
+	}
+
+	String mapLastName(UserResource userRes) {
+		return userRes.toRepresentation().getLastName();
+	}
+
+	String mapUsername(UserResource userRes) {
+		return userRes.toRepresentation().getUsername();
+	}
+}
diff --git a/src/main/java/de/itvsh/kop/user/UserService.java b/src/main/java/de/itvsh/kop/user/UserService.java
index ff5b73b3be1c79c4c4ca203ff24205777c7011c3..b7c622d7f93bdb1314a20fa4e855d683b866a51a 100644
--- a/src/main/java/de/itvsh/kop/user/UserService.java
+++ b/src/main/java/de/itvsh/kop/user/UserService.java
@@ -1,21 +1,35 @@
 package de.itvsh.kop.user;
 
-import java.util.UUID;
+import java.util.Optional;
 
 import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
 
 @ApplicationScoped
-class UserService {
+public class UserService {
 
-	User getById(String id) {
-		return buildUser(id);
+	@Inject
+	UserRepository repository;
+
+	public void save(User user) {
+		findUser(user).ifPresentOrElse(persistedUser -> repository.update(addIdUser(user, persistedUser)),
+				() -> repository.persist(user));
+	}
+
+	private Optional<User> findUser(User user) {
+		var dbUser = repository.findByExternalId(user.getExternalId());
+
+		if (dbUser.isEmpty()) {
+			dbUser = repository.findByEmail(user.getEmail());
+		}
+		return dbUser;
+	}
+
+	private User addIdUser(User user, User persistedUser) {
+		return user.toBuilder().id(persistedUser.getId()).build();
 	}
 
-	private User buildUser(String id) {
-		return User.builder()
-				.id(UUID.randomUUID().toString())
-				.name("Max " + id)
-				.lastName("Mustermann" + id)
-				.build();
+	public void markUnsyncedUsersAsDeleted(long lastSyncTimestamp) {
+		repository.updateUnsyncedUsers(lastSyncTimestamp);
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakClientException.java b/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakClientException.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f4a77c69b720246c5e3aa0f24377d4558f4c3fe
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakClientException.java
@@ -0,0 +1,12 @@
+package de.itvsh.kop.user.common.errorhandling;
+
+public class KeycloakClientException extends TechnicalException {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final String MESSAGE_TEMPLATE = "Access Denied for admin user: %s, realm: %s, url: %s";
+
+	public KeycloakClientException(String user, String realm, String url, Throwable cause) {
+		super(String.format(MESSAGE_TEMPLATE, user, realm, url), cause);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakUnavailableException.java b/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakUnavailableException.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1dc84229ab5ee2c3975f8653335cffe6297c104
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakUnavailableException.java
@@ -0,0 +1,12 @@
+package de.itvsh.kop.user.common.errorhandling;
+
+public class KeycloakUnavailableException extends TechnicalException {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final String MESSAGE_TEMPLATE = "Error performing on keycloak using admin user: %s, realm: %s, url: %s";
+
+	public KeycloakUnavailableException(String user, String realm, String url, Throwable cause) {
+		super(String.format(MESSAGE_TEMPLATE, user, realm, url, cause), cause);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/common/errorhandling/LockCreationException.java b/src/main/java/de/itvsh/kop/user/common/errorhandling/LockCreationException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ee7a37e2ca833c9a53afd9e9d9f8cc64cd8abed
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/common/errorhandling/LockCreationException.java
@@ -0,0 +1,12 @@
+package de.itvsh.kop.user.common.errorhandling;
+
+public class LockCreationException extends TechnicalException {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final String MESSAGE = "Unable to find created lock.";
+
+	public LockCreationException() {
+		super(MESSAGE);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/common/errorhandling/TechnicalException.java b/src/main/java/de/itvsh/kop/user/common/errorhandling/TechnicalException.java
new file mode 100644
index 0000000000000000000000000000000000000000..aec1d123d7ab6487a034bbfe055fe97f4c5d525c
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/common/errorhandling/TechnicalException.java
@@ -0,0 +1,27 @@
+package de.itvsh.kop.user.common.errorhandling;
+
+import java.util.UUID;
+
+public class TechnicalException extends RuntimeException {
+
+	private static final long serialVersionUID = 1L;
+
+	private final String exceptionId = UUID.randomUUID().toString();
+
+	public TechnicalException(String msg) {
+		super(msg);
+	}
+
+	public TechnicalException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+
+	@Override
+	public String getMessage() {
+		return formatMessage();
+	}
+
+	private String formatMessage() {
+		return String.format("%s (ExceptionId: %s)", super.getMessage(), exceptionId);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/common/errorhandling/UserNotFoundException.java b/src/main/java/de/itvsh/kop/user/common/errorhandling/UserNotFoundException.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0b53d0f59e1497f273539139650489f2e8130cb
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/common/errorhandling/UserNotFoundException.java
@@ -0,0 +1,12 @@
+package de.itvsh.kop.user.common.errorhandling;
+
+public class UserNotFoundException extends TechnicalException {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final String MESSAGE_WITH_EXTERNALID_TEMPLATE = "User not found for keycloak id %s";
+
+	public UserNotFoundException(String externalId, Throwable cause) {
+		super(String.format(MESSAGE_WITH_EXTERNALID_TEMPLATE, externalId), cause);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiProperties.java b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6b1776ebbb3c8e49bde40dde1beece6fdbda13a
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiProperties.java
@@ -0,0 +1,23 @@
+package de.itvsh.kop.user.keycloak;
+
+import javax.validation.constraints.NotBlank;
+
+import io.smallrye.config.ConfigMapping;
+
+@ConfigMapping(prefix = "usermanager.keycloak.api")
+public interface KeycloakApiProperties {
+
+	@NotBlank
+	String user();
+
+	@NotBlank
+	String password();
+
+	String realm();
+
+	String client();
+
+	String organisationsEinheitIdKey();
+
+	String ldapIdKey();
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiService.java b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e98bc4b43da8940e5a12c6bee1324e18642cb4f6
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiService.java
@@ -0,0 +1,67 @@
+package de.itvsh.kop.user.keycloak;
+
+import java.util.Spliterators;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.ClientErrorException;
+import javax.ws.rs.ProcessingException;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.representations.idm.UserRepresentation;
+
+import de.itvsh.kop.user.RemoteUserIterator;
+import de.itvsh.kop.user.User;
+import de.itvsh.kop.user.UserResourceMapper;
+import de.itvsh.kop.user.common.errorhandling.KeycloakClientException;
+import de.itvsh.kop.user.common.errorhandling.KeycloakUnavailableException;
+import io.quarkus.logging.Log;
+
+@ApplicationScoped
+class KeycloakApiService {
+
+	@Inject
+	RealmResource realmResource;
+	@Inject
+	UserResourceMapper mapper;
+	@Inject
+	KeycloakApiProperties properties;
+
+	@ConfigProperty(name = "keycloak.url")
+	String keycloakUrl;
+
+	public Stream<User> findAllUser() {
+		return handlingKeycloakException(() -> getAllUserRepresentation().map(this::toUser));
+	}
+
+	Stream<UserRepresentation> getAllUserRepresentation() {
+		var iterator = createRealmUserIterator();
+		return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
+	}
+
+	private RemoteUserIterator createRealmUserIterator() {
+		return new RemoteUserIterator(realmResource);
+	}
+
+	private User toUser(UserRepresentation userRepresentation) {
+		return mapper.toKopUser(realmResource.users().get(userRepresentation.getId()));
+	}
+
+	private <T> T handlingKeycloakException(Supplier<T> runnable) {
+		try {
+			return runnable.get();
+		} catch (ClientErrorException e) {
+			var exception = new KeycloakClientException(properties.user(), properties.realm(), keycloakUrl, e);
+			Log.error(exception.getMessage());
+			throw exception;
+		} catch (ProcessingException | IllegalStateException e) {
+			var exception = new KeycloakUnavailableException(properties.user(), properties.realm(), keycloakUrl, e);
+			Log.error(exception.getMessage());
+			throw exception;
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/keycloak/KeycloakProvider.java b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..70e1355f6a6e6f7c031d481a61460fe5ee9931d3
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakProvider.java
@@ -0,0 +1,35 @@
+package de.itvsh.kop.user.keycloak;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.KeycloakBuilder;
+import org.keycloak.admin.client.resource.RealmResource;
+
+public class KeycloakProvider {
+
+	private static final String CLIENT = "admin-cli";
+
+	@Inject
+	KeycloakApiProperties keycloakConfiguration;
+
+	@ConfigProperty(name = "keycloak.url")
+	String keycloakUrl;
+
+	@ApplicationScoped
+	RealmResource provide() {
+		return buildKeycloakInstance().realm(keycloakConfiguration.realm());
+	}
+
+	private Keycloak buildKeycloakInstance() {
+		return KeycloakBuilder.builder()
+				.serverUrl(keycloakUrl)
+				.realm(keycloakConfiguration.realm())
+				.clientId(CLIENT)
+				.username(keycloakConfiguration.user())
+				.password(keycloakConfiguration.password())
+				.build();
+	}
+}
diff --git a/src/main/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteService.java b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteService.java
new file mode 100644
index 0000000000000000000000000000000000000000..56c33762474e079e265d503c28cccafbcbee554a
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteService.java
@@ -0,0 +1,19 @@
+package de.itvsh.kop.user.keycloak;
+
+import java.util.stream.Stream;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import de.itvsh.kop.user.User;
+
+@ApplicationScoped
+public class KeycloakUserRemoteService {
+
+	@Inject
+	KeycloakApiService apiService;
+
+	public Stream<User> getAllUsers() {
+		return apiService.findAllUser();
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/sync/Lock.java b/src/main/java/de/itvsh/kop/user/sync/Lock.java
new file mode 100644
index 0000000000000000000000000000000000000000..a604b1e597b6330aa536d5891c031a8714ba104b
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/sync/Lock.java
@@ -0,0 +1,22 @@
+package de.itvsh.kop.user.sync;
+
+import io.quarkus.mongodb.panache.PanacheMongoEntity;
+import io.quarkus.mongodb.panache.common.MongoEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+@MongoEntity
+public class Lock extends PanacheMongoEntity {
+
+	public static final String TIMESTAMP_FIELD = "timestamp";
+
+	private long timestamp;
+}
diff --git a/src/main/java/de/itvsh/kop/user/sync/LockRepository.java b/src/main/java/de/itvsh/kop/user/sync/LockRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd13f5d1696b681ff0ec1530831723c09895bfaa
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/sync/LockRepository.java
@@ -0,0 +1,20 @@
+package de.itvsh.kop.user.sync;
+
+import java.time.Instant;
+import java.util.Optional;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import io.quarkus.mongodb.panache.PanacheMongoRepository;
+
+@ApplicationScoped
+class LockRepository implements PanacheMongoRepository<Lock> {
+
+	Optional<Lock> findLockBefore(Instant timestamp) {
+		return find(Lock.TIMESTAMP_FIELD + " < ?1", timestamp.toEpochMilli()).firstResultOptional();
+	}
+
+	Optional<Lock> findLock(Instant timestamp) {
+		return find(Lock.TIMESTAMP_FIELD, timestamp.toEpochMilli()).firstResultOptional();
+	}
+}
diff --git a/src/main/java/de/itvsh/kop/user/sync/LockService.java b/src/main/java/de/itvsh/kop/user/sync/LockService.java
new file mode 100644
index 0000000000000000000000000000000000000000..57710a665a312e5e8df854d67f0e67d8fe7497ed
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/sync/LockService.java
@@ -0,0 +1,47 @@
+package de.itvsh.kop.user.sync;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import de.itvsh.kop.user.common.errorhandling.LockCreationException;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+@ApplicationScoped
+public class LockService {
+
+	@Inject
+	LockRepository repository;
+
+	public boolean isNotLocked() {
+		return repository.count() == 0;
+	}
+
+	boolean isLockOlderThanADay() {
+		return repository.findLockBefore(Instant.now())
+				.map(this::isSyncLockOlderThanADay)
+				.orElse(false);
+	}
+
+	private boolean isSyncLockOlderThanADay(Lock syncLock) {
+		var lastSyncTimeStamp = Instant.ofEpochMilli(syncLock.getTimestamp());
+		return lastSyncTimeStamp.plus(1, ChronoUnit.DAYS).isBefore(Instant.now());
+	}
+
+	public void unlock(Lock lock) {
+		repository.delete(lock);
+		LOG.info("Lock deleted");
+	}
+
+	public void lock(Instant timestamp) {
+		repository.persist(Lock.builder().timestamp(timestamp.toEpochMilli()).build());
+		LOG.info("Lock created");
+	}
+
+	public Lock getByTimestamp(Instant timestamp) {
+		return repository.findLock(timestamp).orElseThrow(LockCreationException::new);
+	}
+}
diff --git a/src/main/java/de/itvsh/kop/user/sync/SyncScheduler.java b/src/main/java/de/itvsh/kop/user/sync/SyncScheduler.java
new file mode 100644
index 0000000000000000000000000000000000000000..d72afb46754af0bcd912682e2f09a4a6478bb764
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/sync/SyncScheduler.java
@@ -0,0 +1,29 @@
+package de.itvsh.kop.user.sync;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import io.quarkus.scheduler.Scheduled;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+@ApplicationScoped
+public class SyncScheduler {
+
+	@Inject
+	SyncService syncService;
+	@Inject
+	LockService syncLockService;
+
+	@Scheduled(cron = "{usermanager.keycloak.sync.cron}")
+	public void start() {
+		if (syncLockService.isNotLocked()) {
+			syncService.sync();
+		} else {
+			LOG.warn("UserManager: Database is locked, no sync happend.");
+			if (syncLockService.isLockOlderThanADay()) {
+				LOG.warn("Database lock is older than a day");
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/itvsh/kop/user/sync/SyncService.java b/src/main/java/de/itvsh/kop/user/sync/SyncService.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a597fb129821b3385f44dd8aa006bf036eba373
--- /dev/null
+++ b/src/main/java/de/itvsh/kop/user/sync/SyncService.java
@@ -0,0 +1,55 @@
+package de.itvsh.kop.user.sync;
+
+import java.time.Instant;
+import java.util.function.Predicate;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+import de.itvsh.kop.user.User;
+import de.itvsh.kop.user.UserService;
+import de.itvsh.kop.user.keycloak.KeycloakUserRemoteService;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+@ApplicationScoped
+class SyncService {
+
+	private final Predicate<User> HAS_ANY_ROLE = user -> CollectionUtils.isNotEmpty(user.getRoles());// NOSONAR
+
+	@Inject
+	UserService userService;
+	@Inject
+	KeycloakUserRemoteService keycloakService;
+	@Inject
+	LockService lockService;
+
+	public void sync() {
+		var now = Instant.now();
+		lockService.lock(now);
+
+		doSync(lockService.getByTimestamp(now));
+	}
+
+	void doSync(Lock lock) {
+		LOG.info("Start sync...");
+		try {
+			keycloakService.getAllUsers()
+					.filter(HAS_ANY_ROLE)
+					.forEach(user -> userService.save(addLastSyncTimestamp(user, lock)));
+
+			userService.markUnsyncedUsersAsDeleted(lock.getTimestamp());
+			LOG.info("sync successful.");
+		} catch (Exception e) {
+			LOG.error("Error syncing user", e);
+		} finally {
+			lockService.unlock(lock);
+		}
+	}
+
+	private User addLastSyncTimestamp(User user, Lock lock) {
+		return user.toBuilder().lastSyncTimestamp(lock.getTimestamp()).build();
+	}
+}
\ No newline at end of file
diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ef51b4d92c3dfbae315ed3f489e8060dec02034b
--- /dev/null
+++ b/src/main/resources/application-dev.yaml
@@ -0,0 +1,17 @@
+quarkus:
+  mongodb:
+    database: dev-user-manager
+  keycloak:
+    devservices:
+      create-realm: true
+      realm-name: dev
+      realm-path: dev-realm.json
+usermanager:
+  keycloak:
+    sync:
+      cron: "0 */10 * * * ?"
+    api:
+      user: goofyApiUser
+      password: S9UEMuLG9y9ev99
+      realm: dev
+      organisations-einheit-id-key: organisationsEinheitId
diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d3116f7d59443a751cf1710f42947e3eebe952fb
--- /dev/null
+++ b/src/main/resources/application-local.yaml
@@ -0,0 +1,6 @@
+quarkus:
+  port: 8082
+  mongodb:
+    connection-string: mongodb://localhost:27017
+keycloak:
+  url: http://localhost:8088 
\ No newline at end of file
diff --git a/src/main/resources/application-remotekc.yaml b/src/main/resources/application-remotekc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f16c633e13820f042de61db668301921d9e4ffb1
--- /dev/null
+++ b/src/main/resources/application-remotekc.yaml
@@ -0,0 +1,11 @@
+usermanager:
+  keycloak:
+    sync:
+      cron: "* */10 * * * ?"
+    api:
+      user: goofyApiUser
+      password: S9UEMuLG9y9ev99
+      realm: sh-kiel-dev
+      organisations-einheit-id-key: organisationseinheitId
+keycloak:
+  url: https://sso.dev.ozg-sh.de/auth
\ No newline at end of file
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index f86dccd2cc523c277713fd8c6b37b2ab37ecb136..14a06cba56e00d0d5462330822b03c752638225d 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -1,10 +1,26 @@
 quarkus:
  application:
-  name: KopUserManager
+  name: kopusermanager
+ mongodb:
+  database: usermanager
+ scheduler:
+  metrics:
+   enabled: true
  log:
   level: INFO
   console:
-    json:
-      fields:
-        level:
-          field-name: log.level
\ No newline at end of file
+   json:
+    fields:
+     level:
+      field-name: log.level
+usermanager:
+ keycloak:
+  sync:
+   cron: "0 15 2 * * ?"
+  api:
+   user: goofyApiUser
+   password: S9UEMuLG9y9ev99
+   realm: sh-kiel-dev
+   organisations-einheit-id-key: organisationseinheitId
+   ldap-id-key: LDAP_ID
+   client: sh-kiel-dev-goofy
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/GroupRepresentationTestFactory.java b/src/test/java/de/itvsh/kop/user/GroupRepresentationTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d1dfadb544dabc643658d869ec769b27ae0d695
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/GroupRepresentationTestFactory.java
@@ -0,0 +1,23 @@
+package de.itvsh.kop.user;
+
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.representations.idm.GroupRepresentation;
+
+class GroupRepresentationTestFactory {
+	static final GroupRepresentation createGroup(String path) {
+		var group = new GroupRepresentation();
+		group.setPath(path);
+		return group;
+	}
+
+	public static GroupRepresentation createByPathAndOrganisationEinheitId(String groupPath, String organisationEinheitId) {
+		var groupRepresentation = new GroupRepresentation();
+		groupRepresentation.setName(groupPath);
+		groupRepresentation.setPath(groupPath);
+		groupRepresentation.setAttributes(Map.of(UserResourceMapperTest.ORGANISATIONS_EINHEIT_ID_KEY,
+				List.of(organisationEinheitId)));
+		return groupRepresentation;
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/UserControllerTest.java b/src/test/java/de/itvsh/kop/user/UserControllerTest.java
deleted file mode 100644
index 9fc989bbbc219228c07def6fca597f2129046c3d..0000000000000000000000000000000000000000
--- a/src/test/java/de/itvsh/kop/user/UserControllerTest.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.itvsh.kop.user;
-
-import static io.restassured.RestAssured.given;
-import static org.hamcrest.CoreMatchers.is;
-
-import org.junit.jupiter.api.Test;
-
-import io.quarkus.test.junit.QuarkusTest;
-
-@QuarkusTest
-class UserControllerTest {
-
-	@Test
-	void getById() {
-		given()
-				.when().get("/api/user/1")
-				.then()
-				.statusCode(200).body(is("Max 1"));
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/UserITCase.java b/src/test/java/de/itvsh/kop/user/UserITCase.java
deleted file mode 100644
index 673e9233e951ac9d90569750406773d4a7317bf0..0000000000000000000000000000000000000000
--- a/src/test/java/de/itvsh/kop/user/UserITCase.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.itvsh.kop.user;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-class UserITCase extends UserControllerTest {
-}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java b/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..442db85e3ecdb9e2d770e01a8b1a94db41abe0c2
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java
@@ -0,0 +1,56 @@
+package de.itvsh.kop.user;
+
+import javax.inject.Inject;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.*;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+class UserRepositoryTest {
+
+	@Inject
+	UserRepository repository;
+
+	private User user1;
+	private User user2;
+
+	@BeforeEach
+	void init() {
+		user1 = UserTestFactory.create();
+		repository.persist(user1);
+
+		user2 = UserTestFactory.createBuilder().externalId("unknown").build();
+		repository.persist(user2);
+		user2 = user2.toBuilder().externalId(null).build();
+	}
+
+	@Test
+	void shouldFindByExternalId() {
+		var res = repository.findByExternalId(user1.getExternalId());
+
+		assertThat(res).isPresent();
+		assertThat(res.get().getExternalId()).isEqualTo(user1.getExternalId());
+	}
+
+	@Test
+	void shouldFindByEmailOnly() {
+		var res = repository.findByEmail(user1.getEmail());
+
+		assertThat(res).isPresent();
+		assertThat(res.get().getExternalId()).isEqualTo(user1.getExternalId());
+	}
+
+	@Test
+	void shouldNotFindByEmptyEmail() {
+		var user = UserTestFactory.createBuilder().externalId("unknown").email(null).build();
+		repository.persist(user);
+		user = user.toBuilder().externalId(null).build();
+		var res = repository.findByEmail(user.getEmail());
+
+		assertThat(res).isEmpty();
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/UserRepresentationTestFactory.java b/src/test/java/de/itvsh/kop/user/UserRepresentationTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1c8a5504cf50231d55f7a78c8afbfc138f76bb9
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/UserRepresentationTestFactory.java
@@ -0,0 +1,52 @@
+package de.itvsh.kop.user;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.representations.idm.UserRepresentation;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+public class UserRepresentationTestFactory {
+
+	static final String EMAIL = LoremIpsum.getInstance().getEmail();
+	static final String FIRST_NAME = LoremIpsum.getInstance().getFirstName();
+	static final String LAST_NAME = LoremIpsum.getInstance().getLastName();
+	static final String USER_NAME = LoremIpsum.getInstance().getName();
+
+	static final String EXTERNAL_ID = "external-id-1-ldap";
+	static final String EXTERNAL_ID_FALLBACK = "external-id-2-keykloak";
+	static final String ROLE_NAME = "VERWALTUNG_USER";
+
+	private static final long CREATED = Instant.now().toEpochMilli();
+
+	static final String ORGANSISATIONS_EINHEIT_ID = "0815";
+
+	private static final String LDAP_ID_KEY = "LDAP_ID";
+	static final Map<String, List<String>> ATTRIBUTES = Map.of(LDAP_ID_KEY, List.of(EXTERNAL_ID));
+
+	static final String CLIENT_KEY = "sh-kiel-dev-goofy";
+	private static final Map<String, List<String>> CLIENT_ROLED = Map.of(CLIENT_KEY, List.of(ROLE_NAME));
+
+	static UserRepresentation createWithAttributes(Map<String, List<String>> attributes) {
+		var user = create();
+		user.setAttributes(attributes);
+
+		return user;
+	}
+
+	public static UserRepresentation create() {
+		var user = new UserRepresentation();
+		user.setEmail(EMAIL);
+		user.setFirstName(FIRST_NAME);
+		user.setLastName(LAST_NAME);
+		user.setUsername(USER_NAME);
+		user.setCreatedTimestamp(CREATED);
+		user.setId(EXTERNAL_ID_FALLBACK);
+		user.setAttributes(ATTRIBUTES);
+		user.setClientRoles(CLIENT_ROLED);
+
+		return user;
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/UserResourceMapperTest.java b/src/test/java/de/itvsh/kop/user/UserResourceMapperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7aadfde8b07262e820ef527fb09ccc24ac4b8887
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/UserResourceMapperTest.java
@@ -0,0 +1,227 @@
+package de.itvsh.kop.user;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.RoleMappingResource;
+import org.keycloak.admin.client.resource.RoleScopeResource;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.representations.idm.ClientMappingsRepresentation;
+import org.keycloak.representations.idm.GroupRepresentation;
+import org.keycloak.representations.idm.MappingsRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.mapstruct.factory.Mappers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import de.itvsh.kop.user.keycloak.KeycloakApiProperties;
+
+class UserResourceMapperTest {
+	static final String ORGANISATIONS_EINHEIT_ID_KEY = "organisationseinheitId";
+	static final String ORGANISATIONS_EINHEIT_ID_1 = "0815";
+	static final String ORGANISATIONS_EINHEIT_ID_2 = "4711";
+	static final String GROUP_1_PATH = "/group1";
+	static final String GROUP_2_PATH = "/group2";
+
+	static final Map<String, List<String>> ATTRIBUTES_1 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_1));
+	static final Map<String, List<String>> ATTRIBUTES_2 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_2));
+
+	@InjectMocks
+	private UserResourceMapper mapper = Mappers.getMapper(UserResourceMapper.class);
+
+	@Mock
+	private KeycloakApiProperties properties;
+
+	@Mock
+	private RealmResource realm;
+
+	@Nested
+	class TestMapping {
+
+		@BeforeEach
+		void init() {
+			when(properties.ldapIdKey()).thenReturn("LDAP_ID");
+			when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId");
+			when(properties.client()).thenReturn("sh-kiel-dev-goofy");
+			when(realm.getGroupByPath(GROUP_1_PATH))
+					.thenReturn(GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_1_PATH, ORGANISATIONS_EINHEIT_ID_1));
+			when(properties.ldapIdKey()).thenReturn("LDAP_ID");
+			when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId");
+			when(properties.client()).thenReturn("sh-kiel-dev-goofy");
+		}
+
+		@Test
+		void shouldMapToUser() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user).isNotNull();
+		}
+
+		@Test
+		void shouldMapEmail() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user.getEmail()).isEqualTo(UserRepresentationTestFactory.EMAIL);
+		}
+
+		@Test
+		void shouldMapExternalId() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID);
+		}
+
+		@Test
+		void shouldMapExternalIdFallback() {
+			User user = mapper.toKopUser(UserResourceTestFactory.createWithAttributes(Map.of()));
+
+			assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID_FALLBACK);
+		}
+
+		@Test
+		void shouldMapFirstName() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user.getFirstName()).isEqualTo(UserRepresentationTestFactory.FIRST_NAME);
+		}
+
+		@Test
+		void shouldMapLastName() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user.getLastName()).isEqualTo(UserRepresentationTestFactory.LAST_NAME);
+		}
+
+		@Test
+		void shouldMapUserName() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user.getUsername()).isEqualTo(UserRepresentationTestFactory.USER_NAME);
+		}
+
+		@Test
+		void shouldMapOrganisationsEinheitIds() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().contains(ORGANISATIONS_EINHEIT_ID_1);
+		}
+
+		@Test
+		void shouldMapMultipleOrganisationsEinheitIds() {
+			GroupRepresentation groupRepresentation = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_2_PATH,
+					ORGANISATIONS_EINHEIT_ID_2);
+
+			when(realm.getGroupByPath(GROUP_2_PATH)).thenReturn(groupRepresentation);
+
+			User user = mapper.toKopUser(
+					UserResourceTestFactory.createWithGroups(List.of(GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_1_PATH),
+							GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_2_PATH))));
+
+			assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().hasSize(2).contains(ORGANISATIONS_EINHEIT_ID_2);
+		}
+
+		@Test
+		void shouldMapRoles() {
+			User user = mapper.toKopUser(UserResourceTestFactory.create());
+
+			assertThat(user.getRoles()).isNotEmpty().contains(UserRepresentationTestFactory.ROLE_NAME);
+		}
+	}
+
+	@DisplayName("Get client roles")
+	@Nested
+	class TestGetClientRoles {
+
+		@Mock
+		private UserResource userResource;
+
+		@Mock
+		private RoleMappingResource roleMappingResource;
+		@Mock
+		private RoleScopeResource roleScopeResource;
+		@Mock
+		private MappingsRepresentation mappingsRepresentation;
+		@Mock
+		private Map<String, ClientMappingsRepresentation> clientMappingsRepresentation;
+		@Mock
+		private ClientMappingsRepresentation clientMappingRepresentation;
+
+		@BeforeEach
+		void init() {
+			when(userResource.roles()).thenReturn(roleMappingResource);
+			when(roleMappingResource.getAll()).thenReturn(mappingsRepresentation);
+		}
+
+		@DisplayName("on existing roles")
+		@Nested
+		class TestOnAssignedRoles {
+
+			@BeforeEach
+			void init() {
+				when(properties.client()).thenReturn(UserRepresentationTestFactory.CLIENT_KEY);
+
+				when(mappingsRepresentation.getClientMappings()).thenReturn(clientMappingsRepresentation);
+				when(clientMappingsRepresentation.containsKey(UserRepresentationTestFactory.CLIENT_KEY)).thenReturn(true);
+				when(clientMappingsRepresentation.get(UserRepresentationTestFactory.CLIENT_KEY)).thenReturn(clientMappingRepresentation);
+				when(clientMappingRepresentation.getMappings()).thenReturn(List.of(createRoleRepresentation()));
+			}
+
+			private RoleRepresentation createRoleRepresentation() {
+				var roleRepresentation = new RoleRepresentation();
+				roleRepresentation.setName(UserRepresentationTestFactory.ROLE_NAME);
+				return roleRepresentation;
+			}
+
+			@Test
+			void shouldReturnRolesIfExists() {
+				var roles = mapper.mapRoles(userResource);
+
+				assertThat(roles).isNotEmpty();
+				assertThat(roles.get(0)).isEqualTo(UserRepresentationTestFactory.ROLE_NAME);
+			}
+		}
+
+		@Nested
+		class TestOnNonExistingClient {
+
+			@BeforeEach
+			void init() {
+				when(properties.client()).thenReturn(UserRepresentationTestFactory.CLIENT_KEY);
+
+				when(mappingsRepresentation.getClientMappings()).thenReturn(Collections.emptyMap());
+			}
+
+			@Test
+			void shouldReturnEmptyListIfNoRolesAttached() {
+				var roles = mapper.mapRoles(userResource);
+
+				assertThat(roles).isEmpty();
+			}
+		}
+
+		@Nested
+		class TestNullClientMappings {
+
+			@BeforeEach
+			void init() {
+				when(mappingsRepresentation.getClientMappings()).thenReturn(null);
+			}
+
+			@Test
+			void shouldReturnEmptyListIfNoRolesAttached() {
+				var roles = mapper.mapRoles(userResource);
+
+				assertThat(roles).isEmpty();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/UserResourceStub.java b/src/test/java/de/itvsh/kop/user/UserResourceStub.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ed3beaf6df8c4bdc0145dfecf0b96afc11c9888
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/UserResourceStub.java
@@ -0,0 +1,241 @@
+package de.itvsh.kop.user;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.Response;
+
+import org.keycloak.admin.client.resource.RoleMappingResource;
+import org.keycloak.admin.client.resource.RoleScopeResource;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.representations.idm.ClientMappingsRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.FederatedIdentityRepresentation;
+import org.keycloak.representations.idm.GroupRepresentation;
+import org.keycloak.representations.idm.MappingsRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.representations.idm.UserSessionRepresentation;
+
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+class UserResourceStub implements UserResource {
+	private UserRepresentation userRepresentation = UserRepresentationTestFactory.create();
+	private List<GroupRepresentation> groups = List.of(GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_1_PATH));
+
+	public UserResourceStub(Map<String, List<String>> attributes) {
+		userRepresentation = UserRepresentationTestFactory.createWithAttributes(attributes);
+	}
+
+	public UserResourceStub(List<GroupRepresentation> groups) {
+		this.groups = groups;
+	}
+
+	@Override
+	public UserRepresentation toRepresentation() {
+		return userRepresentation;
+	}
+
+	@Override
+	public void update(UserRepresentation userRepresentation) {
+		// not implemented
+	}
+
+	@Override
+	public void remove() {
+		// not implemented
+	}
+
+	@Override
+	public List<GroupRepresentation> groups() {
+		return groups;
+	}
+
+	@Override
+	public void leaveGroup(String groupId) {
+		// not implemented
+	}
+
+	@Override
+	public List<GroupRepresentation> groups(Integer firstResult, Integer maxResults) {
+		return groups();
+	}
+
+	@Override
+	public List<GroupRepresentation> groups(String search, Integer firstResult, Integer maxResults) {
+		return groups();
+	}
+
+	@Override
+	public List<GroupRepresentation> groups(Integer firstResult, Integer maxResults, boolean briefRepresentation) {
+		return groups();
+	}
+
+	@Override
+	public List<GroupRepresentation> groups(String search, Integer firstResult, Integer maxResults, boolean briefRepresentation) {
+		return groups();
+	}
+
+	@Override
+	public Map<String, Long> groupsCount(String search) {
+		return Map.of();
+	}
+
+	@Override
+	public void joinGroup(String groupId) {
+		// not implemented
+	}
+
+	@Override
+	public void logout() {
+		// not implemented
+	}
+
+	@Override
+	public List<CredentialRepresentation> credentials() {
+		return null;
+	}
+
+	@Override
+	public List<String> getConfiguredUserStorageCredentialTypes() {
+		return null;
+	}
+
+	@Override
+	public void removeCredential(String credentialId) {
+		// not implemented
+	}
+
+	@Override
+	public void setCredentialUserLabel(String credentialId, String userLabel) {
+		// not implemented
+	}
+
+	@Override
+	public void moveCredentialToFirst(String credentialId) {
+		// not implemented
+
+	}
+
+	@Override
+	public void moveCredentialAfter(String credentialId, String newPreviousCredentialId) {
+		// not implemented
+	}
+
+	@Override
+	public void disableCredentialType(List<String> credentialTypes) {
+		// not implemented
+	}
+
+	@Override
+	public void resetPassword(CredentialRepresentation credentialRepresentation) {
+		// not implemented
+	}
+
+	@Override
+	public void resetPasswordEmail() {
+		// not implemented
+	}
+
+	@Override
+	public void resetPasswordEmail(String clientId) {
+		// not implemented
+	}
+
+	@Override
+	public void executeActionsEmail(List<String> actions) {
+		// not implemented
+	}
+
+	@Override
+	public void executeActionsEmail(List<String> actions, Integer lifespan) {
+		// not implemented
+	}
+
+	@Override
+	public void executeActionsEmail(String clientId, String redirectUri, Integer lifespan, List<String> actions) {
+		// not implemented
+	}
+
+	@Override
+	public void executeActionsEmail(String clientId, String redirectUri, List<String> actions) {
+		// not implemented
+	}
+
+	@Override
+	public void sendVerifyEmail() {
+		// not implemented
+	}
+
+	@Override
+	public void sendVerifyEmail(String clientId) {
+		// not implemented
+	}
+
+	@Override
+	public List<UserSessionRepresentation> getUserSessions() {
+		return null;
+	}
+
+	@Override
+	public List<UserSessionRepresentation> getOfflineSessions(String clientId) {
+		return null;
+	}
+
+	@Override
+	public List<FederatedIdentityRepresentation> getFederatedIdentity() {
+		return null;
+	}
+
+	@Override
+	public Response addFederatedIdentity(String provider, FederatedIdentityRepresentation rep) {
+		return null;
+	}
+
+	@Override
+	public void removeFederatedIdentity(String provider) {
+		// not implemented
+	}
+
+	@Override
+	public RoleMappingResource roles() {
+		return new RoleMappingResource() {
+
+			@Override
+			public RoleScopeResource realmLevel() {
+				return null;
+			}
+
+			@Override
+			public MappingsRepresentation getAll() {
+				var rep = new MappingsRepresentation();
+				var clientMapRep = new ClientMappingsRepresentation();
+				var roleRep = new RoleRepresentation(UserRepresentationTestFactory.ROLE_NAME, "Test role", false);
+				clientMapRep.setMappings(List.of(roleRep));
+				rep.setClientMappings(Map.of("sh-kiel-dev-goofy", clientMapRep));
+				return rep;
+			}
+
+			@Override
+			public RoleScopeResource clientLevel(String clientUUID) {
+				return null;
+			}
+		};
+	}
+
+	@Override
+	public List<Map<String, Object>> getConsents() {
+		return List.of(Map.of());
+	}
+
+	@Override
+	public void revokeConsent(String clientId) {
+		// not implemented
+	}
+
+	@Override
+	public Map<String, Object> impersonate() {
+		return null;
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/UserResourceTestFactory.java b/src/test/java/de/itvsh/kop/user/UserResourceTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..48a49d0eabe39e09004f9727b2fb42fdad9f8572
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/UserResourceTestFactory.java
@@ -0,0 +1,22 @@
+package de.itvsh.kop.user;
+
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.representations.idm.GroupRepresentation;
+
+public class UserResourceTestFactory {
+
+	public static UserResource create() {
+		return new UserResourceStub();
+	}
+
+	public static UserResource createWithAttributes(Map<String, List<String>> attributes) {
+		return new UserResourceStub(attributes);
+	}
+
+	public static UserResource createWithGroups(List<GroupRepresentation> groups) {
+		return new UserResourceStub(groups);
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/UserServiceTest.java b/src/test/java/de/itvsh/kop/user/UserServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b683fdc465604b217e3d5bd3023461cc1af870d
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/UserServiceTest.java
@@ -0,0 +1,76 @@
+package de.itvsh.kop.user;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.time.Instant;
+import java.util.Optional;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import de.itvsh.kop.user.keycloak.KeycloakUserRemoteService;
+
+class UserServiceTest {
+
+	@InjectMocks
+	UserService service;
+	@Mock
+	UserRepository repository;
+	@Mock
+	KeycloakUserRemoteService keycloakRemoteService;
+
+	@DisplayName("Save")
+	@Nested
+	class TestSave {
+
+		private final User user = UserTestFactory.create();
+
+		@Test
+		void shouldCallRepositoryUpdate() {
+			when(repository.findByExternalId(any())).thenReturn(Optional.of(user));
+
+			service.save(user.toBuilder().firstName("Other").build());
+
+			verify(repository).update(any(User.class));
+		}
+
+		@Test
+		void shouldCallRepositoryPersist() {
+			service.save(user);
+
+			verify(repository).persist(any(User.class));
+		}
+
+		@Test
+		void shouldCallUserRepositoryFindByExternalId() {
+			service.save(user);
+
+			verify(repository).findByExternalId(any());
+		}
+
+		@Test
+		void shouldCallUserRepositoryFindByEmail() {
+			service.save(UserTestFactory.createBuilder().externalId(null).build());
+
+			verify(repository).findByEmail(any());
+		}
+	}
+
+	@DisplayName("Mark unsynced users as deleted")
+	@Nested
+	class TestMarkUnsyncedUserAsDeleted {
+
+		@Test
+		void shouldCallRepository() {
+			var lastSyncTimestamp = Instant.now().toEpochMilli();
+
+			service.markUnsyncedUsersAsDeleted(lastSyncTimestamp);
+
+			verify(repository).updateUnsyncedUsers(lastSyncTimestamp);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/UserTestFactory.java b/src/test/java/de/itvsh/kop/user/UserTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..21899053598cf2328fef335e27e622169947a351
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/UserTestFactory.java
@@ -0,0 +1,34 @@
+package de.itvsh.kop.user;
+
+import java.util.List;
+import java.util.UUID;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+public class UserTestFactory {
+
+	public static final String FIRST_NAME = LoremIpsum.getInstance().getFirstName();
+	public static final String LAST_NAME = LoremIpsum.getInstance().getLastName();
+	public static final String USER_NAME = LoremIpsum.getInstance().getName();
+	public static final long LAST_SYNC_TIMESTAMP = 1001L;
+	public static final String EMAIL = LoremIpsum.getInstance().getEmail();
+	public static final String EXTERNAL_ID = UUID.randomUUID().toString();
+	public static final List<String> ORGANISTATIONSEINHEITEN_IDS = List.of("0815", "4711");
+	public static final List<String> ROLES = List.of("ROLE_1", "POSTSTELLE");
+
+	public static User create() {
+		return createBuilder().build();
+	}
+
+	public static User.UserBuilder createBuilder() {
+		return new User.UserBuilder()
+				.firstName(FIRST_NAME)
+				.lastName(LAST_NAME)
+				.username(USER_NAME)
+				.lastSyncTimestamp(LAST_SYNC_TIMESTAMP)
+				.email(EMAIL)
+				.externalId(EXTERNAL_ID)
+				.organisationsEinheitIds(ORGANISTATIONSEINHEITEN_IDS)
+				.roles(ROLES);
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceITCase.java b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..2eb49ab4e065325a8577d224a12d6091301000a0
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceITCase.java
@@ -0,0 +1,25 @@
+package de.itvsh.kop.user.keycloak;
+
+import static org.assertj.core.api.Assertions.*;
+
+import javax.inject.Inject;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.TestProfile;
+
+@QuarkusTest
+@TestProfile(KeycloakTestProfile.class)
+class KeycloakApiServiceITCase {
+
+	@Inject
+	KeycloakApiService service;
+
+	@Test
+	void shouldGetAllUsers() {
+		var usersStream = service.findAllUser().toList();
+
+		assertThat(usersStream).isNotEmpty();
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceTest.java b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..967f3f745e7f1699c1b0658e3ec14f4b7c135e10
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceTest.java
@@ -0,0 +1,78 @@
+package de.itvsh.kop.user.keycloak;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.admin.client.resource.UsersResource;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+import de.itvsh.kop.user.RemoteUserIterator;
+import de.itvsh.kop.user.User;
+import de.itvsh.kop.user.UserRepresentationTestFactory;
+import de.itvsh.kop.user.UserResourceMapper;
+import de.itvsh.kop.user.UserTestFactory;
+
+class KeycloakApiServiceTest {
+
+	@Spy
+	@InjectMocks
+	private KeycloakApiService service;
+	@Mock
+	private RealmResource realmResource;
+	@Mock
+	private UserResourceMapper userResourceMapper;
+	@Mock
+	private KeycloakApiProperties properties;
+
+	@Mock
+	private UserResource userResource;
+
+	@DisplayName("Find all user")
+	@Nested
+	class TestFindAllUser {
+
+		@Mock
+		private UsersResource usersResource;
+
+		@Mock
+		private RemoteUserIterator iterator;
+
+		private User user = UserTestFactory.create();
+		private UserRepresentation userRepresentation = UserRepresentationTestFactory.create();
+		private Stream<UserRepresentation> userStream = Stream.of(userRepresentation);
+
+		@BeforeEach
+		void init() {
+			doReturn(userStream).when(service).getAllUserRepresentation();
+		}
+
+		@Test
+		void shouldCreateIteratorWithRealmResource() {
+			service.findAllUser();
+
+			verify(service).getAllUserRepresentation();
+		}
+
+		@Test
+		void shouldCallMapper() {
+			when(userResourceMapper.toKopUser(any(UserResource.class))).thenReturn(user);
+			when(realmResource.users()).thenReturn(usersResource);
+			when(usersResource.get(anyString())).thenReturn(userResource);
+
+			service.findAllUser().toList();
+
+			verify(userResourceMapper).toKopUser(any(UserResource.class));
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/keycloak/KeycloakProviderITCase.java b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakProviderITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..800275d14a2644cb81e49184066c347d014a9d22
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakProviderITCase.java
@@ -0,0 +1,21 @@
+package de.itvsh.kop.user.keycloak;
+
+import static org.assertj.core.api.Assertions.*;
+
+import javax.inject.Inject;
+
+import org.junit.jupiter.api.Test;
+import org.keycloak.admin.client.resource.RealmResource;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+class KeycloakProviderITCase {
+	@Inject
+	RealmResource realm;
+
+	@Test
+	void shouldHaveRealmResource() {
+		assertThat(realm).isNotNull();
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/keycloak/KeycloakTestProfile.java b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakTestProfile.java
new file mode 100644
index 0000000000000000000000000000000000000000..e47cb32c47d3958ff5c9dc266c9ab517a8db046d
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakTestProfile.java
@@ -0,0 +1,28 @@
+package de.itvsh.kop.user.keycloak;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTestProfile;
+
+public class KeycloakTestProfile implements QuarkusTestProfile {
+
+	private final String userKey = "usermanager.keycloak.api.user";
+	private final String userValue = "goofyApiUser";
+
+	private final String passwordKey = "usermanager.keycloak.api.password";
+	private final String passwordValue = "S9UEMuLG9y9ev99";
+
+	private final String realmKey = "usermanager.keycloak.api.realm";
+	private final String realmValue = "sh-kiel-dev";
+
+	private final String urlKey = "keycloak.url";
+	private final String urlValue = "https://sso.dev.ozg-sh.de/auth";
+
+	@Override
+	public Map<String, String> getConfigOverrides() {
+		return Map.of(userKey, userValue,
+				passwordKey, passwordValue,
+				realmKey, realmValue,
+				urlKey, urlValue);
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteServiceITCase.java b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteServiceITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..441f575b4e6bde1860db67f771781b7d72cab007
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteServiceITCase.java
@@ -0,0 +1,25 @@
+package de.itvsh.kop.user.keycloak;
+
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.mockito.InjectMock;
+import io.quarkus.test.junit.mockito.InjectSpy;
+
+@QuarkusTest
+class KeycloakUserRemoteServiceITCase {
+
+	@InjectSpy
+	KeycloakUserRemoteService service;
+	@InjectMock
+	KeycloakApiService apiService;
+
+	@Test
+	void shouldCallGetAllUsers() {
+		service.getAllUsers();
+
+		verify(apiService).findAllUser();
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteServiceTest.java b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4ed777f9da34bb882756e25b0458e11c36af537
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/keycloak/KeycloakUserRemoteServiceTest.java
@@ -0,0 +1,29 @@
+package de.itvsh.kop.user.keycloak;
+
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+class KeycloakUserRemoteServiceTest {
+
+	@InjectMocks
+	private KeycloakUserRemoteService remoteService;
+	@Mock
+	private KeycloakApiService apiService;
+
+	@DisplayName("Get all userrs")
+	@Nested
+	class TestGetAllUsers {
+
+		@Test
+		void shouldCallApiService() {
+			remoteService.getAllUsers();
+
+			verify(apiService).findAllUser();
+		}
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/sync/LockRepositoryTest.java b/src/test/java/de/itvsh/kop/user/sync/LockRepositoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..182839253272642200ecaa281815df40457337fb
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/sync/LockRepositoryTest.java
@@ -0,0 +1,55 @@
+package de.itvsh.kop.user.sync;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+
+import javax.inject.Inject;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.*;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+class LockRepositoryITCase {
+
+	@Inject
+	private LockRepository repository;
+
+	private final Lock lock = LockTestFactory.create();
+
+	@BeforeEach
+	void init() {
+		repository.deleteAll();
+	}
+
+	@Test
+	void shouldSave() {
+		repository.persist(lock);
+
+		assertThat(repository.count()).isEqualTo(1L);
+	}
+
+	@Test
+	void shouldFindLockBefore() {
+		var lock = Lock.builder().timestamp(Instant.now().minus(1, ChronoUnit.HOURS).toEpochMilli()).build();
+		repository.persist(lock);
+
+		var savedLock = repository.findLockBefore(Instant.now());
+
+		assertThat(savedLock).isPresent();
+		assertThat(savedLock.get()).usingRecursiveComparison().ignoringFields("id").isEqualTo(lock);
+	}
+
+	@Test
+	void shouldFindLock() {
+		repository.persist(lock);
+
+		var savedLock = repository.findLock(Instant.ofEpochMilli(lock.getTimestamp()));
+
+		assertThat(savedLock).isPresent();
+		assertThat(savedLock.get()).usingRecursiveComparison().ignoringFields("id").isEqualTo(lock);
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/sync/LockServiceTest.java b/src/test/java/de/itvsh/kop/user/sync/LockServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..74ad4fc7e398d99f9ad1470c1c60867a92ca60b0
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/sync/LockServiceTest.java
@@ -0,0 +1,139 @@
+package de.itvsh.kop.user.sync;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.Optional;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import static org.assertj.core.api.Assertions.*;
+
+import de.itvsh.kop.user.common.errorhandling.LockCreationException;
+
+class LockServiceTest {
+
+	@InjectMocks
+	private LockService service;
+	@Mock
+	private LockRepository repository;
+
+	@DisplayName("Is not Locked")
+	@Nested
+	class TestIsNotLocked {
+
+		@Test
+		void shouldCallRepository() {
+			service.isNotLocked();
+
+			verify(repository).count();
+		}
+
+		@Test
+		void shouldReturnTrue() {
+			when(repository.count()).thenReturn(0L);
+
+			var isNotLocked = service.isNotLocked();
+
+			assertThat(isNotLocked).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalse() {
+			when(repository.count()).thenReturn(1L);
+
+			var isNotLocked = service.isNotLocked();
+
+			assertThat(isNotLocked).isFalse();
+		}
+	}
+
+	@DisplayName("Is lock older than a day")
+	@Nested
+	class TestIsLockOlderThanADay {
+
+		@Test
+		void shouldCallSyncLockRepository() {
+			service.isLockOlderThanADay();
+
+			verify(repository).findLockBefore(any(Instant.class));
+		}
+
+		@Test
+		void shouldReturnTrue() {
+			var timestamp = Instant.now().minus(1, ChronoUnit.DAYS);
+			var syncLock = LockTestFactory.createBuilder().timestamp(timestamp.toEpochMilli()).build();
+			when(repository.findLockBefore(any(Instant.class))).thenReturn(Optional.of(syncLock));
+
+			var isOlderthantADay = service.isLockOlderThanADay();
+
+			assertThat(isOlderthantADay).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalse() {
+			when(repository.findLockBefore(any(Instant.class))).thenReturn(Optional.empty());
+
+			var isOlderthantADay = service.isLockOlderThanADay();
+
+			assertThat(isOlderthantADay).isFalse();
+		}
+	}
+
+	@DisplayName("Unlock")
+	@Nested
+	class TestUnlock {
+
+		private final Lock lock = LockTestFactory.create();
+
+		@Test
+		void shouldCallRepositoryDelete() {
+			service.unlock(lock);
+
+			verify(repository).delete(lock);
+		}
+	}
+
+	@DisplayName("Lock")
+	@Nested
+	class TestLock {
+
+		private final Instant LOCK = Instant.now();
+
+		@Test
+		void shouldCallRepositoryPersist() {
+			service.lock(LOCK);
+
+			verify(repository).persist(any(Lock.class));
+		}
+	}
+
+	@DisplayName("Get by Timestamp")
+	@Nested
+	class TestGetByTimestamp {
+
+		private final Instant timestamp = Instant.now();
+
+		@Test
+		void shouldCallRepositoryFind() {
+			when(repository.findLock(any(Instant.class))).thenReturn(Optional.of(LockTestFactory.create()));
+
+			service.getByTimestamp(timestamp);
+
+			verify(repository).findLock(timestamp);
+		}
+
+		@Test
+		void shouldThrowExceptionIfNotExists() {
+			when(repository.findLock(any(Instant.class))).thenReturn(Optional.empty());
+
+			assertThatThrownBy(() -> service.getByTimestamp(timestamp)).isInstanceOf(LockCreationException.class);
+		}
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/sync/LockTestFactory.java b/src/test/java/de/itvsh/kop/user/sync/LockTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..36ff4f56fa7bacc27f5c725fe756b047420ebf55
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/sync/LockTestFactory.java
@@ -0,0 +1,17 @@
+package de.itvsh.kop.user.sync;
+
+import java.time.Instant;
+
+public class LockTestFactory {
+
+	private static final long TIMESTAMP = Instant.now().toEpochMilli();
+
+	public static Lock create() {
+		return createBuilder().build();
+	}
+
+	public static Lock.LockBuilder createBuilder() {
+		return Lock.builder()
+				.timestamp(TIMESTAMP);
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/sync/SyncSchedulerTest.java b/src/test/java/de/itvsh/kop/user/sync/SyncSchedulerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..94ac888ded23ad64d01f6f4ec56dde72e1d6a78a
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/sync/SyncSchedulerTest.java
@@ -0,0 +1,60 @@
+package de.itvsh.kop.user.sync;
+
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+class SyncSchedulerTest {
+
+	@Spy
+	@InjectMocks
+	private SyncScheduler scheduler;
+	@Mock
+	private SyncService service;
+	@Mock
+	private LockService syncLockService;
+
+	@DisplayName("Start Scheduler")
+	@Nested
+	class TestStart {
+
+		@Test
+		void shouldDoSyncIfNotLocked() {
+			when(syncLockService.isNotLocked()).thenReturn(true);
+
+			scheduler.start();
+
+			verify(service).sync();
+		}
+
+		@DisplayName("If Locked")
+		@Nested
+		class TestIfLocked {
+
+			@BeforeEach
+			void mockTimeStamp() {
+				when(syncLockService.isNotLocked()).thenReturn(false);
+			}
+
+			@Test
+			void shouldNotDoSync() {
+				scheduler.start();
+
+				verify(service, never()).sync();
+			}
+
+			@Test
+			void shouldCheckIfLockIsOlderThanADay() {
+				scheduler.start();
+
+				verify(syncLockService).isLockOlderThanADay();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/itvsh/kop/user/sync/SyncServiceITCase.java b/src/test/java/de/itvsh/kop/user/sync/SyncServiceITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..c567157d5a0392e5d43e877c33ccda6f93b9a286
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/sync/SyncServiceITCase.java
@@ -0,0 +1,65 @@
+package de.itvsh.kop.user.sync;
+
+import static org.mockito.Mockito.*;
+
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.*;
+
+import de.itvsh.kop.user.User;
+import de.itvsh.kop.user.UserRepository;
+import de.itvsh.kop.user.UserTestFactory;
+import de.itvsh.kop.user.keycloak.KeycloakUserRemoteService;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.mockito.InjectMock;
+import io.quarkus.test.junit.mockito.InjectSpy;
+
+@QuarkusTest
+class SyncServiceITCase {
+
+	@InjectSpy
+	private SyncService service;
+
+	@InjectSpy
+	private UserRepository repository;
+
+	@InjectMock
+	private KeycloakUserRemoteService keycloakUserRemoteService;
+
+	@BeforeEach
+	void init() {
+		when(keycloakUserRemoteService.getAllUsers()).thenReturn(List.of(UserTestFactory.create()).stream());
+	}
+
+	@Test
+	void shouldMarkNotSyncUsersAsDeleted() {
+		repository.deleteAll();
+		User user = UserTestFactory.create();
+		repository.persist(user);
+		when(keycloakUserRemoteService.getAllUsers()).thenReturn(List.of(user.toBuilder().roles(List.of()).build()).stream());
+
+		service.sync();
+
+		User syncedUser = repository.findAll().firstResult();
+		assertThat(syncedUser.isDeleted()).isTrue();
+	}
+
+	@Test
+	void shouldSync() {
+		repository.deleteAll();
+		User user1 = UserTestFactory.createBuilder().externalId("aaaaa").build();
+		User user2 = UserTestFactory.createBuilder().externalId("bbbbb").build();
+		repository.persist(List.of(user1, user2));
+		when(keycloakUserRemoteService.getAllUsers()).thenReturn(List.of(user1, user2).stream());
+
+		service.sync();
+
+		List<User> syncedUsers = repository.findAll().list();
+
+		assertThat(syncedUsers.get(0).getLastSyncTimestamp()).isGreaterThan(UserTestFactory.LAST_SYNC_TIMESTAMP);
+		assertThat(syncedUsers.get(1).getLastSyncTimestamp()).isGreaterThan(UserTestFactory.LAST_SYNC_TIMESTAMP);
+	}
+}
diff --git a/src/test/java/de/itvsh/kop/user/sync/SyncServiceTest.java b/src/test/java/de/itvsh/kop/user/sync/SyncServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc050f3c1cfd1538de71d84aafec5a8a64b67ae2
--- /dev/null
+++ b/src/test/java/de/itvsh/kop/user/sync/SyncServiceTest.java
@@ -0,0 +1,138 @@
+package de.itvsh.kop.user.sync;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.time.Instant;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+import static org.assertj.core.api.Assertions.*;
+
+import de.itvsh.kop.user.User;
+import de.itvsh.kop.user.UserService;
+import de.itvsh.kop.user.UserTestFactory;
+import de.itvsh.kop.user.keycloak.KeycloakUserRemoteService;
+
+class SyncServiceTest {
+
+	@Spy
+	@InjectMocks
+	private SyncService service;
+	@Mock
+	private KeycloakUserRemoteService keycloakService;
+	@Mock
+	private LockService lockService;
+
+	@Mock
+	private UserService userService;
+
+	@DisplayName("Sync")
+	@Nested
+	class TestSync {
+
+		@DisplayName("With successful lock creation")
+		@Nested
+		class TestWithSuccessfulLockCreation {
+
+			private final Lock lock = LockTestFactory.create();
+
+			@BeforeEach
+			void mockLock() {
+				when(lockService.getByTimestamp(any(Instant.class))).thenReturn(lock);
+			}
+
+			@Test
+			void shouldCallLockServiceLock() {
+				service.sync();
+
+				verify(lockService).lock(any(Instant.class));
+			}
+
+			@Test
+			void shouldCallLockServiceFind() {
+				service.sync();
+
+				verify(lockService).getByTimestamp(any(Instant.class));
+			}
+
+			@Test
+			void shouldDoSync() {
+				service.sync();
+
+				verify(service).doSync(lock);
+			}
+		}
+	}
+
+	@DisplayName("Do the sync")
+	@Nested
+	class TestDoSync {
+
+		private final Lock lock = LockTestFactory.create();
+		private final User user = UserTestFactory.create();
+
+		@Captor
+		private ArgumentCaptor<User> userCaptor;
+
+		@DisplayName("should get all users from keycloak")
+		@Test
+		void shouldCallKeycloakService() {
+			service.doSync(lock);
+
+			verify(keycloakService).getAllUsers();
+		}
+
+		@Test
+		void shouldCallUserServiceSave() {
+			when(keycloakService.getAllUsers()).thenReturn(Stream.of(user, user));
+
+			service.doSync(lock);
+
+			verify(userService, times(2)).save(any(User.class));
+		}
+
+		@Test
+		void shouldAddLasSyncToUser() {
+			when(keycloakService.getAllUsers()).thenReturn(Stream.of(user));
+
+			service.doSync(lock);
+
+			verify(userService).save(userCaptor.capture());
+			assertThat(userCaptor.getValue().getLastSyncTimestamp()).isEqualTo(lock.getTimestamp());
+		}
+
+		@DisplayName("should mark all unsynced users as deleted")
+		@Test
+		void shouldMarkUnsyncedUsersAsDeleted() {
+			service.doSync(lock);
+
+			verify(userService).markUnsyncedUsersAsDeleted(lock.getTimestamp());
+		}
+
+		@Test
+		void shouldUnlockLock() {
+			service.doSync(lock);
+
+			verify(lockService).unlock(lock);
+		}
+
+		@Test
+		void shouldUnlockLockOnException() {
+			when(keycloakService.getAllUsers()).thenThrow(new RuntimeException());
+
+			service.doSync(lock);
+
+			verify(lockService).unlock(lock);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/test/resources/META-INF/keycloak/dev-realm.json b/src/test/resources/META-INF/keycloak/dev-realm.json
new file mode 100644
index 0000000000000000000000000000000000000000..f20238e3e85e0199d93fbb4c418570d879759775
--- /dev/null
+++ b/src/test/resources/META-INF/keycloak/dev-realm.json
@@ -0,0 +1,3913 @@
+[ {
+  "id" : "1964b9ab-c6d6-42cf-8bdb-c9a76523a57f",
+  "realm" : "dev",
+  "displayName" : "",
+  "displayNameHtml" : "",
+  "notBefore" : 0,
+  "defaultSignatureAlgorithm" : "RS256",
+  "revokeRefreshToken" : false,
+  "refreshTokenMaxReuse" : 0,
+  "accessTokenLifespan" : 300,
+  "accessTokenLifespanForImplicitFlow" : 900,
+  "ssoSessionIdleTimeout" : 1800,
+  "ssoSessionMaxLifespan" : 36000,
+  "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" : 300,
+  "oauth2DeviceCodeLifespan" : 600,
+  "oauth2DevicePollingInterval" : 5,
+  "enabled" : true,
+  "sslRequired" : "none",
+  "registrationAllowed" : false,
+  "registrationEmailAsUsername" : false,
+  "rememberMe" : false,
+  "verifyEmail" : false,
+  "loginWithEmailAllowed" : true,
+  "duplicateEmailsAllowed" : false,
+  "resetPasswordAllowed" : false,
+  "editUsernameAllowed" : false,
+  "bruteForceProtected" : false,
+  "permanentLockout" : false,
+  "maxFailureWaitSeconds" : 900,
+  "minimumQuickLoginWaitSeconds" : 60,
+  "waitIncrementSeconds" : 60,
+  "quickLoginCheckMilliSeconds" : 1000,
+  "maxDeltaTimeSeconds" : 43200,
+  "failureFactor" : 30,
+  "roles" : {
+    "realm" : [ {
+      "id" : "ccc97175-19ca-45ec-a64d-438b63359092",
+      "name" : "offline_access",
+      "description" : "${role_offline-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "1964b9ab-c6d6-42cf-8bdb-c9a76523a57f",
+      "attributes" : { }
+    }, {
+      "id" : "5e95a9f9-eaaf-46f2-8050-c749de58d2b9",
+      "name" : "default-roles-kop-apitest-verw",
+      "description" : "${role_default-roles}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "offline_access", "uma_authorization" ],
+        "client" : {
+          "account" : [ "view-profile", "manage-account" ]
+        }
+      },
+      "clientRole" : false,
+      "containerId" : "1964b9ab-c6d6-42cf-8bdb-c9a76523a57f",
+      "attributes" : { }
+    }, {
+      "id" : "6ea8c433-be43-475c-818b-1fd269da77e6",
+      "name" : "uma_authorization",
+      "description" : "${role_uma_authorization}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "1964b9ab-c6d6-42cf-8bdb-c9a76523a57f",
+      "attributes" : { }
+    } ],
+    "client" : {
+      "realm-management" : [ {
+        "id" : "9e29328f-4cf1-411b-bbe6-ee19f527aec4",
+        "name" : "view-clients",
+        "description" : "${role_view-clients}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-clients" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "85d15b74-e658-4cc0-9195-5fedff3e122a",
+        "name" : "query-users",
+        "description" : "${role_query-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "ed386119-807b-4074-b1c4-e3ed4e0498d3",
+        "name" : "view-authorization",
+        "description" : "${role_view-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "ea91197e-dfcd-4a09-b251-b7735a48a51d",
+        "name" : "manage-identity-providers",
+        "description" : "${role_manage-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "a906d81e-6648-4b7e-8b6b-fe6ae3a8aa6c",
+        "name" : "view-realm",
+        "description" : "${role_view-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "aff1bccc-3716-425a-bd13-5af791d7b5f1",
+        "name" : "manage-events",
+        "description" : "${role_manage-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "9b9f6be3-5171-4d4c-ae81-6f1293e02112",
+        "name" : "query-groups",
+        "description" : "${role_query-groups}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "cbb6fa87-ebe3-403e-9ea9-1003a97ffa07",
+        "name" : "realm-admin",
+        "description" : "${role_realm-admin}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "view-clients", "query-users", "view-authorization", "manage-identity-providers", "view-realm", "query-groups", "manage-events", "manage-users", "query-clients", "view-users", "impersonation", "create-client", "view-events", "manage-clients", "view-identity-providers", "query-realms", "manage-realm", "manage-authorization" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "599fedc0-c913-44d3-b90d-ae9e28d1e411",
+        "name" : "manage-users",
+        "description" : "${role_manage-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "571ca0ed-b44f-4669-aa08-e097a4b3772e",
+        "name" : "query-clients",
+        "description" : "${role_query-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "c0bc2b45-2a3a-4608-a615-4554889c0f39",
+        "name" : "view-users",
+        "description" : "${role_view-users}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-users", "query-groups" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "3bb7c458-44bb-490a-a961-725a7f62d108",
+        "name" : "impersonation",
+        "description" : "${role_impersonation}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "4338efa1-28e5-46ed-b7d3-faa5af778861",
+        "name" : "create-client",
+        "description" : "${role_create-client}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "57bdcfc7-05db-4ae4-892b-9d3996bae0bc",
+        "name" : "view-events",
+        "description" : "${role_view-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "049ddb7a-a0ac-4b33-8825-b23627d2755b",
+        "name" : "manage-clients",
+        "description" : "${role_manage-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "b4bf7daf-2a6c-4ef8-aa2d-15c948d49066",
+        "name" : "view-identity-providers",
+        "description" : "${role_view-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "0da10f4a-d086-49c5-976a-dba273a13755",
+        "name" : "query-realms",
+        "description" : "${role_query-realms}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "8d41f3df-1f41-453d-8170-b0066e9020f3",
+        "name" : "manage-authorization",
+        "description" : "${role_manage-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      }, {
+        "id" : "4e1bd596-4a2c-4024-aa35-ad13d06ace28",
+        "name" : "manage-realm",
+        "description" : "${role_manage-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+        "attributes" : { }
+      } ],
+      "goofy" : [ {
+        "id" : "598141f9-eb6f-4adb-8f6d-d21e1db7abfe",
+        "name" : "VERWALTUNG_USER",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "73cec8d5-6e03-4589-86eb-8f58e758d730",
+        "attributes" : { }
+      }, {
+        "id" : "7a829180-2acc-47a4-a82a-13d1807559f2",
+        "name" : "VERWALTUNG_POSTSTELLE",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "73cec8d5-6e03-4589-86eb-8f58e758d730",
+        "attributes" : { }
+      } ],
+      "security-admin-console" : [ ],
+      "admin-cli" : [ ],
+      "account-console" : [ ],
+      "broker" : [ {
+        "id" : "72ce150c-45af-485d-9fc3-f43877fc1949",
+        "name" : "read-token",
+        "description" : "${role_read-token}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "8333205e-d5a6-4d2b-9de9-bd07c9c8579c",
+        "attributes" : { }
+      } ],
+      "account" : [ {
+        "id" : "ca5a931e-679b-41ac-949e-5468c68a4015",
+        "name" : "manage-consent",
+        "description" : "${role_manage-consent}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "view-consent" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "bf8f95db-6141-419f-adab-7e951659d989",
+        "attributes" : { }
+      }, {
+        "id" : "8ac3ab69-c53a-49e0-8c70-8ec6bf47008e",
+        "name" : "view-profile",
+        "description" : "${role_view-profile}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "bf8f95db-6141-419f-adab-7e951659d989",
+        "attributes" : { }
+      }, {
+        "id" : "788bd93a-6208-4135-88f2-3be3ef5ed7b4",
+        "name" : "manage-account",
+        "description" : "${role_manage-account}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "manage-account-links" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "bf8f95db-6141-419f-adab-7e951659d989",
+        "attributes" : { }
+      }, {
+        "id" : "dafbb791-d2b4-47bb-b33d-d212a90792bb",
+        "name" : "view-consent",
+        "description" : "${role_view-consent}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "bf8f95db-6141-419f-adab-7e951659d989",
+        "attributes" : { }
+      }, {
+        "id" : "e5bca3d3-b9ae-4e25-b2be-93a11da4ad64",
+        "name" : "delete-account",
+        "description" : "${role_delete-account}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "bf8f95db-6141-419f-adab-7e951659d989",
+        "attributes" : { }
+      }, {
+        "id" : "a3f2f757-383f-4092-a148-9fb1b9ad1867",
+        "name" : "manage-account-links",
+        "description" : "${role_manage-account-links}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "bf8f95db-6141-419f-adab-7e951659d989",
+        "attributes" : { }
+      }, {
+        "id" : "60db677c-b10e-4b77-8fa9-3f5148cee2ae",
+        "name" : "view-applications",
+        "description" : "${role_view-applications}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "bf8f95db-6141-419f-adab-7e951659d989",
+        "attributes" : { }
+      } ]
+    }
+  },
+  "groups" : [ {
+    "id" : "52be1d46-1bae-4f00-922e-02efd6838dcf",
+    "name" : "Ordnungsamt",
+    "path" : "/Ordnungsamt",
+    "attributes" : {
+      "organisationsEinheitId" : [ "9030229" ]
+    },
+    "realmRoles" : [ ],
+    "clientRoles" : { },
+    "subGroups" : [ ]
+  } ],
+  "defaultRole" : {
+    "id" : "5e95a9f9-eaaf-46f2-8050-c749de58d2b9",
+    "name" : "default-roles-kop-apitest-verw",
+    "description" : "${role_default-roles}",
+    "composite" : true,
+    "clientRole" : false,
+    "containerId" : "1964b9ab-c6d6-42cf-8bdb-c9a76523a57f"
+  },
+  "requiredCredentials" : [ "password" ],
+  "otpPolicyType" : "totp",
+  "otpPolicyAlgorithm" : "HmacSHA1",
+  "otpPolicyInitialCounter" : 0,
+  "otpPolicyDigits" : 6,
+  "otpPolicyLookAheadWindow" : 1,
+  "otpPolicyPeriod" : 30,
+  "otpSupportedApplications" : [ "FreeOTP", "Google Authenticator" ],
+  "webAuthnPolicyRpEntityName" : "keycloak",
+  "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
+  "webAuthnPolicyRpId" : "",
+  "webAuthnPolicyAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyRequireResidentKey" : "not specified",
+  "webAuthnPolicyUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyCreateTimeout" : 0,
+  "webAuthnPolicyAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyAcceptableAaguids" : [ ],
+  "webAuthnPolicyPasswordlessRpEntityName" : "keycloak",
+  "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ],
+  "webAuthnPolicyPasswordlessRpId" : "",
+  "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified",
+  "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyPasswordlessCreateTimeout" : 0,
+  "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ],
+  "users" : [ {
+    "id" : "26c16229-0f37-40ce-b44d-27bf1b63141a",
+    "createdTimestamp" : 1660890501831,
+    "username" : "alice",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : true,
+    "firstName" : "Alice",
+    "lastName" : "Wunder",
+    "email" : "alice@dev.local",
+    "credentials" : [ ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-kop-apitest-verw" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  }, {
+    "id" : "9d7633d2-ddf0-4d18-8384-5c9581bc4635",
+    "createdTimestamp" : 1660890535597,
+    "username" : "bob",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : true,
+    "firstName" : "Bob",
+    "lastName" : "Bobster",
+    "email" : "bob@dev.local",
+    "credentials" : [ ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-kop-apitest-verw" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  }, {
+    "id" : "0592dc73-cb01-405a-be10-cc6a204ecf1c",
+    "createdTimestamp" : 1660890234315,
+    "username" : "goofyapiuser",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : true,
+    "firstName" : "goofy",
+    "lastName" : "client",
+    "email" : "goofy@dev.local",
+    "credentials" : [ {
+      "id" : "8cf11911-615a-4fe4-ae0b-37eafac7d8ff",
+      "type" : "password",
+      "createdDate" : 1660890249119,
+      "secretData" : "{\"value\":\"wF2IlMsSnwFvz2I46UOIjeqe0HKzbRIp8s5mymeVxF+H0iU6bVm6qBYT1PXYT3v45AJFPSHtQpG0lA6FxN2F4A==\",\"salt\":\"Cw1vL4Rx1rOwgB6Qn15Pyw==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-kop-apitest-verw" ],
+    "clientRoles" : {
+      "realm-management" : [ "view-users" ]
+    },
+    "notBefore" : 0,
+    "groups" : [ ]
+  }, {
+    "id" : "c970c2c4-ec0b-4f1e-8a58-769fbc8518f9",
+    "createdTimestamp" : 1660655234752,
+    "username" : "sabine",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : false,
+    "firstName" : "Sabine",
+    "lastName" : "Sach",
+    "credentials" : [ {
+      "id" : "98297f4d-3aff-4407-9c82-5c25b4e0406e",
+      "type" : "password",
+      "userLabel" : "My password",
+      "createdDate" : 1660655259975,
+      "secretData" : "{\"value\":\"rbnkjLAt+dxo9k7F8hHKKZ8EN4kMPLHVAhTTcAHLtE7e2wLgc9qnqelAlQeWZZXwXSnHDIxHjqjVW968JPVNTA==\",\"salt\":\"qEBm+fok7trlVRYPHrQfJQ==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-kop-apitest-verw" ],
+    "clientRoles" : {
+      "goofy" : [ "VERWALTUNG_USER" ]
+    },
+    "notBefore" : 0,
+    "groups" : [ "Ordnungsamt" ]
+  } ],
+  "scopeMappings" : [ {
+    "clientScope" : "offline_access",
+    "roles" : [ "offline_access" ]
+  } ],
+  "clientScopeMappings" : {
+    "account" : [ {
+      "client" : "account-console",
+      "roles" : [ "manage-account" ]
+    } ]
+  },
+  "clients" : [ {
+    "id" : "bf8f95db-6141-419f-adab-7e951659d989",
+    "clientId" : "account",
+    "name" : "${client_account}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/kop-apitest-verw/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/kop-apitest-verw/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", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "97f52335-14d4-4db6-a120-a0a3e5b96dc4",
+    "clientId" : "account-console",
+    "name" : "${client_account-console}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/kop-apitest-verw/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/kop-apitest-verw/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" : "92b4e98f-126e-4734-bfaf-f2aa2b1c665d",
+      "name" : "audience resolve",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-audience-resolve-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    } ],
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "3653296a-de2f-4faf-b72c-ddbba60fa529",
+    "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" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "8333205e-d5a6-4d2b-9de9-bd07c9c8579c",
+    "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" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "73cec8d5-6e03-4589-86eb-8f58e758d730",
+    "clientId" : "goofy",
+    "name" : "Goofy",
+    "description" : "",
+    "rootUrl" : "",
+    "adminUrl" : "",
+    "baseUrl" : "",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "http://goofy/**" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : true,
+    "directAccessGrantsEnabled" : true,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : true,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "tls-client-certificate-bound-access-tokens" : "false",
+      "oidc.ciba.grant.enabled" : "false",
+      "backchannel.logout.session.required" : "true",
+      "client_credentials.use_refresh_token" : "false",
+      "acr.loa.map" : "{}",
+      "require.pushed.authorization.requests" : "false",
+      "display.on.consent.screen" : "false",
+      "oauth2.device.authorization.grant.enabled" : "false",
+      "backchannel.logout.revoke.offline.tokens" : "false",
+      "token.response.type.bearer.lower-case" : "false",
+      "use.refresh.tokens" : "true"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : true,
+    "nodeReRegistrationTimeout" : -1,
+    "protocolMappers" : [ {
+      "id" : "472c7034-421c-4634-9ae0-e5a9951158d4",
+      "name" : "orgaIdMapper",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "aggregate.attrs" : "false",
+        "multivalued" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "organisationsEinheitId",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "organisationseinheitId"
+      }
+    } ],
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "87aeb7a3-5be5-486a-93b3-7fab9f0f55e3",
+    "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" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "2b73fff6-0e4b-402e-9242-9a5ccc8b7281",
+    "clientId" : "security-admin-console",
+    "name" : "${client_security-admin-console}",
+    "rootUrl" : "${authAdminUrl}",
+    "baseUrl" : "/admin/kop-apitest-verw/console/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/admin/kop-apitest-verw/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" : "6f7a8a07-e8ed-4721-b2be-e38d7ac34877",
+      "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", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  } ],
+  "clientScopes" : [ {
+    "id" : "1a510ca2-38aa-4667-b0dc-8c9dbda92f21",
+    "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" : "7f215868-55b7-4442-bbd0-7373cf08ed83",
+    "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" : "6b09d606-3bed-4f41-a4d2-1df0a071246c",
+      "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" : "434ba9b5-8a99-4aa6-b609-6604b06105eb",
+    "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" : "80ebd080-acba-4f6d-934d-a4beff935fce",
+      "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" : "24938eb7-e2ff-40d6-8ce4-27e4ff2301db",
+      "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" : "cf37db2b-fbc1-4fd9-b674-851f70064434",
+    "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" : "ba257d57-f147-4c06-ad0a-6ea174fd5a34",
+      "name" : "audience resolve",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-audience-resolve-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    }, {
+      "id" : "9ce3f4c8-fe15-4b31-90aa-1382a1688e31",
+      "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"
+      }
+    }, {
+      "id" : "cd3cc8d0-113b-47d1-aa12-56cee9c5db78",
+      "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" : "4119f432-10e6-4656-aef8-bee2917f355b",
+    "name" : "role_list",
+    "description" : "SAML role list",
+    "protocol" : "saml",
+    "attributes" : {
+      "consent.screen.text" : "${samlRoleListScopeConsentText}",
+      "display.on.consent.screen" : "true"
+    },
+    "protocolMappers" : [ {
+      "id" : "59c7a142-532f-4759-b487-f858722a79c3",
+      "name" : "role list",
+      "protocol" : "saml",
+      "protocolMapper" : "saml-role-list-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "single" : "false",
+        "attribute.nameformat" : "Basic",
+        "attribute.name" : "Role"
+      }
+    } ]
+  }, {
+    "id" : "ba4f7ffe-5b2c-4c20-9806-541b3f0605a3",
+    "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" : "9f32604f-2419-4c9c-8b41-4a83559d3de4",
+      "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" : "16a358c4-29ac-42ad-856a-b4444e93826a",
+    "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" : "78e09dfb-a7be-4eea-bd06-3f7bd871235b",
+      "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" : "f38911b8-b4dc-4851-ad33-9f9b6dfff4d6",
+      "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" : "f755d172-09d2-4a6e-8c6c-86bfb09ba4f8",
+    "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" : "0fd832a5-c891-473e-bea5-443bbabfa2e4",
+      "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" : "40b5cdcd-d7d4-4174-b26a-4a9ec8caafa5",
+      "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" : "03b88607-446d-4ac1-a08d-7ba6e0cca404",
+      "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" : "9ba9e659-dfa7-45de-b966-6fc4f2f7db29",
+      "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" : "b857001f-4a72-4a97-b157-bb58b4c4eef9",
+      "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" : "30c69082-2d00-436e-a86e-2419b573c074",
+      "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" : "e038046e-356b-42b8-bb10-8435c66a24ae",
+      "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" : "44ec36e2-cb7c-46e7-9955-57b9b1e59f1a",
+      "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" : "31b90dab-111c-465d-b703-847c8103db5c",
+      "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" : "2acde2b0-3272-40d7-8c2e-0acb4483fabb",
+      "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" : "13536367-e731-41ed-be86-eb3bcf68c503",
+      "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" : "cb107c43-10a7-4794-a677-3492b24f6c2e",
+      "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" : "73a14943-3e56-4092-9fb9-f9a35146c9c9",
+      "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" : "81d10ca9-5412-4253-8bcf-93364345b64d",
+      "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" : "1809e1d2-479f-4510-bda6-43c1ea1f98b2",
+    "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" : "0483a09e-a5ef-4e8a-bae4-ce801423e065",
+      "name" : "allowed web origins",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-allowed-origins-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    } ]
+  }, {
+    "id" : "7b0c2a1d-7674-4b3e-92f6-9614f65e06a3",
+    "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" : "4e487a9a-54b8-4361-985a-080c196ba714",
+      "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" : "7f02b25b-3f3a-4a90-8152-557a263b5eea",
+      "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"
+      }
+    } ]
+  } ],
+  "defaultDefaultClientScopes" : [ "web-origins", "role_list", "email", "acr", "roles", "profile" ],
+  "defaultOptionalClientScopes" : [ "microprofile-jwt", "offline_access", "phone", "address" ],
+  "browserSecurityHeaders" : {
+    "contentSecurityPolicyReportOnly" : "",
+    "xContentTypeOptions" : "nosniff",
+    "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" : [ ],
+  "adminEventsEnabled" : false,
+  "adminEventsDetailsEnabled" : false,
+  "identityProviders" : [ ],
+  "identityProviderMappers" : [ ],
+  "components" : {
+    "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
+      "id" : "4a3058a3-8aa4-4e42-98d5-d51ddc7f8215",
+      "name" : "Trusted Hosts",
+      "providerId" : "trusted-hosts",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "host-sending-registration-request-must-match" : [ "true" ],
+        "client-uris-must-match" : [ "true" ]
+      }
+    }, {
+      "id" : "f2fdaf71-797e-4901-8889-02a05ec6257b",
+      "name" : "Max Clients Limit",
+      "providerId" : "max-clients",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "max-clients" : [ "200" ]
+      }
+    }, {
+      "id" : "775070ec-69b2-4faf-ac87-7a77115f8649",
+      "name" : "Consent Required",
+      "providerId" : "consent-required",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    }, {
+      "id" : "5543c38f-8399-40e2-a70a-082f96de18a5",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "saml-role-list-mapper" ]
+      }
+    }, {
+      "id" : "5088e788-f3e6-4dc2-8fe5-c464d5d527f5",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    }, {
+      "id" : "e7d9c16b-7dc0-49ec-b121-e2d6a37481cb",
+      "name" : "Full Scope Disabled",
+      "providerId" : "scope",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    }, {
+      "id" : "cda5c120-5627-4d88-9aa9-c6b64b8fcb3c",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper" ]
+      }
+    }, {
+      "id" : "759d5b40-45b6-4acf-acdf-d9ebf49576dd",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    } ],
+    "org.keycloak.userprofile.UserProfileProvider" : [ {
+      "id" : "95cfc09b-6e7d-4adf-8e9e-3b7a02f02b67",
+      "providerId" : "declarative-user-profile",
+      "subComponents" : { },
+      "config" : { }
+    } ],
+    "org.keycloak.keys.KeyProvider" : [ {
+      "id" : "4bd3752e-313c-44e0-a511-0977b9aa002b",
+      "name" : "hmac-generated",
+      "providerId" : "hmac-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "7fcf5141-b805-4db2-8b79-6b14caff09fd" ],
+        "secret" : [ "cBWGKkHpHRRT8EDIn913r4cnjyS_sSo70h5-cMb8fOjvtCzce3ujnZLaXzyIfYZGjEF6d4_oeDtMdBtie9u61g" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "HS256" ]
+      }
+    }, {
+      "id" : "0ffe2318-6296-43c6-aa58-498303905d6d",
+      "name" : "rsa-generated",
+      "providerId" : "rsa-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEowIBAAKCAQEAmcaRhxoBQ+bGtC0ZoEEsQH0tFWV58iJBl9cJzRjVD4UfDEpMP40nkXMpH/vhMm1bQAClViOcqEctv1QQoH7zIDFxH694vz3ymlot3wCIV3rcCrq2cb9wyq4CIccH+bswL8/TLrYd5a0W3BmNpGNrTqFiB6GcuJhfoD+bq4wD51lwInN9h/tKHhtWxySuQkTPQm75Tu9Phxlqac4pgFCBacCMG2tVSBUIJBNT4FS91y05mH1Wuu4CILyo6AQ0socB3K+7lc0hY7zC1cyQyaR2JGM8n7wFUazVdPZBp8bffKxHzfpPscY33Dt2IhP3rILSS+bTjvoJh98HaO2S31L+JwIDAQABAoIBABxXk9Txvw/zxeXJdjKqMGzGZXvPEzXEiJBiyuSpUgOlRn6uZvVDn+pX7ll9xBjWPP5D4DVLJQGC9PSRmurp2wew9Seg4MFmuoMmYdP7NiXheBLmLOA0J6bDgZMWKuslTBFT3Zl7aXE+gLsaXpfQ1yNL7VR4vfjr5JwVfSyWBtYpxYUwfRmVI/c2gSlJYU0s5et2X0eNdwIgQ5+NakI3mo5zlM5eYQSuK1VuhAA+hGWmz9bPzjMk24hofNkODuwPWHv4JtR5c7OLcwo9op5Pc9X0KHH0pjEW14Ir5g6umu4Q9WmrZnREgKphrODZ0DnPl/k292T5AtZEvrFpRFqQxyECgYEA1RAjCuvqoLY0BiN7zk3Me2a30YkDA0y0ctYVWAAHjP1wqN8dFS8r7xkIyLZRj15EPM3IhVQnqcjtQEUAoaV9n9KSmBbbZqyOoOntMO5phIb2TsIzwDAMNB23NJd53vPN87TeBG1JdnzjXiZsMFDkB353HXa7b4lqnbQh/4/KofcCgYEAuMPP7By6Q6AvMktP+bxt6116nDE7kmjTArqXMBNfd6drLgeSURKBi2nStb9gGlA8GWPnFuWjw35Gybw8kKdM+sw8Uan2MpEMokcTjnvgt/r5oFtxVdEBaOFWJb39vtc+2yySBeLTweIv/U9goSdGgNyBpkkRBIeAtMV5wEmYeVECgYEAilQIvE2Arki9LAMbnUyLZs7ApyySJTFGsovlnZWfUV02KJ16b0eJ+ZjCSDV+bFtiaCuedVm2ypel2SUzjL85+WqoPFASr+12SGi30x3mqeFJxsZ0/OD0+10TlfSGbkbRvtj9j9g4atIYeAbwFMpf0bG8ugddF8Qa0TqjHB4KC+8CgYA9OQUoo8xEpEt/St1RT1LM7si2AMpQlVN2UAXQ9Fpp95vYQMIHAy7R11ruxl892OBROX1VZPqCyNED/8/Bzu3/HLXQCZV+4/lfvFWKnRm1XQBiVmqTmRHygthc4Tu3hPNbBMXOFX89e4mTUj4eqDkAchCz3Po6mfvX6qeRQ9G2QQKBgFtKWV6t/zEJ+5PWNc1u7sMllRi5HVhuqjhIY1N0nqSnwyn8p6bs5OUFlaqvXXO9cpsHDrLhO4ioT+Frs6EJIFQoPlU2pVzFXGRsaRq44qG5f7KQ43irSoRMOoJToHoGxh0E9dq6Bo+Jkg3u242l8GwZL6xZw/TSRKgwGsKoD6Gi" ],
+        "keyUse" : [ "SIG" ],
+        "certificate" : [ "MIICrzCCAZcCBgGCpsFoxDANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBBrb3AtYXBpdGVzdC12ZXJ3MB4XDTIyMDgxNjEzMDI0OVoXDTMyMDgxNjEzMDQyOVowGzEZMBcGA1UEAwwQa29wLWFwaXRlc3QtdmVydzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnGkYcaAUPmxrQtGaBBLEB9LRVlefIiQZfXCc0Y1Q+FHwxKTD+NJ5FzKR/74TJtW0AApVYjnKhHLb9UEKB+8yAxcR+veL898ppaLd8AiFd63Aq6tnG/cMquAiHHB/m7MC/P0y62HeWtFtwZjaRja06hYgehnLiYX6A/m6uMA+dZcCJzfYf7Sh4bVsckrkJEz0Ju+U7vT4cZamnOKYBQgWnAjBtrVUgVCCQTU+BUvdctOZh9VrruAiC8qOgENLKHAdyvu5XNIWO8wtXMkMmkdiRjPJ+8BVGs1XT2QafG33ysR836T7HGN9w7diIT96yC0kvm0476CYffB2jtkt9S/icCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAArGwmbI8BvL9BbnxZr+E2lOcCnPVctTreuQGECP69WvmNqpMzfClESvvLdq7al54s3WLfXqI1L2Q4FEMw1AmTQtuGsIwYUn8DA2VMiU2fHV5YxL99yNY2iKenWqvOgC4rWu6+Jk62dosUYo/Rk5a1wvHhIQqORVerfHnZqEcT2SGtdFUioA2KiKvx9aEGa7xbcYqWpZCZ0hBwM6BSmdGGTV2sBOXulDsKl6rf7jZJbg3EVW7MUabDIcII6askYeQP0DvC/qEutCH/x/Ei6YDOF4nMGpvJUqN4v3aDDfqwesO0mfgY143qr8iG9WI8wyOahZ+Z8RJTaAmqIVIM97dQQ==" ],
+        "priority" : [ "100" ]
+      }
+    }, {
+      "id" : "17db465e-c349-4b34-874d-a4671e68206f",
+      "name" : "aes-generated",
+      "providerId" : "aes-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "abc0b43d-3f75-4927-a38e-8f579de7ad20" ],
+        "secret" : [ "gcvgiVD4NA0jTxMiU2LuTw" ],
+        "priority" : [ "100" ]
+      }
+    }, {
+      "id" : "8d29912c-0f8f-4c64-823c-9992720476b1",
+      "name" : "rsa-enc-generated",
+      "providerId" : "rsa-enc-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEowIBAAKCAQEAtORIUr4zt9vlb5wXm6jBAqekzRuYnaJwoka/NrN+x1N6yDBzAn8mFFGMXsKJENHJc0Vt0JkXvjjiqFBekttIzODfgEh7ZBvg4gK9r7XR++jA/gXZetlg5J8L6WToLVOPm0MZ0Df07WAFtF/z03C7gsS0wd3Nhp/VGzThdjvLuq0XVMythrTZGh7V19IvahawAxDA0vWxqOK3MaEmlArFEpz2erEgbGq7KW23In6fUqnpLBSGMVULPmiv/8FYtRr66tOHYopE6kuqk+OUaX+ih+5/ATVdvA3XM0h5fgxkXj7eBLlpJuuy3ejAn7XPSjfULkKSzJseM9dHlTtVARntvwIDAQABAoIBADRS+CyfAfzD6bkAEMAg7zuiXIRL4DhwvV3jUvoyr5BesFxpz0rAlrY35H+gi99Gn5vtUFePgROwBrgjD0gxj/xba6sCzFZnzgPyQQYrdMMGT5TrAj6L1IAtFVf8rUA3NIn3vebB2OI07VGAk9nseQDZf2O4kfPIFe+Zu0HlCAhF/oO8Fg2/nH7DQRdtO3gTnDfJnpQiV7IE7wKB/1v/M1ebRj4gv5yPq39XA1pNHtBmZqneyhmz+9f7ml1LvqJ+LPrhYmqphlVJzShSsi1kbKfuD3nbRql8xg/p+xIeiZ1yCeEZflh3ovw9YYe4Ehs4IivJk6FRq4OjK3K4L4nTAcECgYEA5VKK+7IQAo+L5Q91c8zGuBi6FsmvORN7rkhXGFmzOhiYTi7ihzZcM+1vkH+Owgt5Thc534QPNN2RgZm7rW9iMzCQyMLA17OY85/Hp7GKPdv1L14RrWfEdRUO3Hw5EtZJjzfaAdaSvFX16zwdEvKh5447O2RCMxNFIyN7k0fhkaECgYEAye9scD4kwq9c6XsuXFZ+usov5u4h/5SmuG77MUxqpZUlitMNWzIKzOAoMZx2SLlu0al2VBQGhanyTnxpJGptzFhj+X0RdVUNyAH63AommiFbStueFZLi7sFo58de8UXmb2y3p5FNnQNYbdnDoKeN9w0sZDYGxj40FYmCCfGwA18CgYAGo0oEmRXfjRomijkDHhVOdODGEhZxV4AH/m4O9WG7t8SI1tCVy1wF4MSO8TJHqZ9cRE3Xi3IJPLSehL2q+oNkKe628PQ2CivOOXzE/N2chsZlFZr7YvqLzQ0+EpZwViWQ8LPtw7FBpFdW9Ml+p+lJ05MhV/iWk+M3biqAi98aoQKBgGsOxSXIvIJ+qDqcdNq9fJiZAsZir6GpdK5JIGFlixDYPrwX4nfb0wAFQynyMn+h18/OEQ7IQyDwFadoq/GDf0yb+/zUQsI64oCMFCw+MXL7hkPspSX45tj/rxdaispNbbrbH472KPi6QlKS5fUxf8FfuY4zWmoVplVYvpl5CgDvAoGBAKDg+imoQPMREFXhtSwu7qJNx6vu1By2RfnjffcCBXJjf81uGDfn6zE9H1WdbazxmfSU5zqY5aC7YQ+ilkwKw3O80ScNHqkXYqEdNKtbwD5BpJJxGo1sQkmY+gb6bqV0rTjMI0n2qb15K9OYMFvBcQoVJdmMqeFLGTMciiqyMXjN" ],
+        "keyUse" : [ "ENC" ],
+        "certificate" : [ "MIICrzCCAZcCBgGCpsFqfjANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBBrb3AtYXBpdGVzdC12ZXJ3MB4XDTIyMDgxNjEzMDI0OVoXDTMyMDgxNjEzMDQyOVowGzEZMBcGA1UEAwwQa29wLWFwaXRlc3QtdmVydzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTkSFK+M7fb5W+cF5uowQKnpM0bmJ2icKJGvzazfsdTesgwcwJ/JhRRjF7CiRDRyXNFbdCZF7444qhQXpLbSMzg34BIe2Qb4OICva+10fvowP4F2XrZYOSfC+lk6C1Tj5tDGdA39O1gBbRf89Nwu4LEtMHdzYaf1Rs04XY7y7qtF1TMrYa02Roe1dfSL2oWsAMQwNL1sajitzGhJpQKxRKc9nqxIGxquylttyJ+n1Kp6SwUhjFVCz5or//BWLUa+urTh2KKROpLqpPjlGl/oofufwE1XbwN1zNIeX4MZF4+3gS5aSbrst3owJ+1z0o31C5CksybHjPXR5U7VQEZ7b8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAOcMuNdJDra77bySvC/5/oIqpWUAFsM0ssUTBpuVe2pc/8JcoSFLwsOZn8uBb8by+qPyYAQmJ+CnsSgicQaW8inYraeE3KUA+VI0D5U0FPq6emI7hJXczRj2DtlNE7Mvp7aXMkuZp0xlKzktyUg8EjUYd21mr678EwjOdOvgUMtPLZKvyyCpvE6OVXSsIZq10+4i0UdJyR2bD6sqOcdSapAwj3kqwH6+p5EHQL0Km+JFR4eyPedANm6kZXp6WfxMHHziWvT8WupfCIw/pjtRGXoyn31+kAzs0O6LtCeFW5yFgIPwL+6xbtM+ThFUyhNg1TGny0/fMRfLptrvriinotQ==" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "RSA-OAEP" ]
+      }
+    } ]
+  },
+  "internationalizationEnabled" : false,
+  "supportedLocales" : [ ],
+  "authenticationFlows" : [ {
+    "id" : "8b4babf7-5560-4470-94ec-be1e391a5a1f",
+    "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" : "9ab76242-a2a7-4e7f-b0c7-679eb20a8d8e",
+    "alias" : "Authentication Options",
+    "description" : "Authentication options.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "basic-auth",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "basic-auth-otp",
+      "authenticatorFlow" : false,
+      "requirement" : "DISABLED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "auth-spnego",
+      "authenticatorFlow" : false,
+      "requirement" : "DISABLED",
+      "priority" : 30,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "e7e84029-12ae-43b8-8d7f-53178b711829",
+    "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" : "056e9e36-9ad5-4113-90a6-a3f84df31fc5",
+    "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" : "e3f140c8-ccd6-4002-a3d9-fb4acd9e5812",
+    "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" : "078dcee4-009f-4da5-a11c-d89daf371a6d",
+    "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" : "45dcb4e7-3d3a-4dd7-8a9f-002512e1ec24",
+    "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" : "246f0b4a-7837-48ce-bdea-239c5c0f3d56",
+    "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" : "1d6a6368-4743-4187-92b5-d7c75800737a",
+    "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" : "db3b1215-d705-4419-8268-546d49178ca2",
+    "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" : "df2bb008-c488-42d6-95ef-6e5b4416f933",
+    "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" : "e753ea55-9489-4039-91e4-1504d2726fc2",
+    "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" : "f8b06555-3bdd-4f40-91ac-f5bdd6993a40",
+    "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" : "1ec385b4-b7f7-466d-8a4d-e996a34aa72f",
+    "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" : "cad74125-0f95-4bbe-9448-7a9bb9eb01d6",
+    "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" : "615612e6-0085-4a94-8fb3-7b616b0dffab",
+    "alias" : "http challenge",
+    "description" : "An authentication flow based on challenge-response HTTP Authentication Schemes",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "no-cookie-redirect",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Authentication Options",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "fbeac131-7098-470a-b12c-552166b90c81",
+    "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" : "17ff9178-b88b-4646-a32e-9edc28bb714d",
+    "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-profile-action",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 40,
+      "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" : "86b9197c-c1eb-4354-b036-d573d2407adb",
+    "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" : "cac02a4f-7918-4ad4-aae6-f2948bfbd218",
+    "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" : "e3b68ed0-580e-45f8-a36e-21f169427f58",
+    "alias" : "create unique user config",
+    "config" : {
+      "require.password.update.after.registration" : "false"
+    }
+  }, {
+    "id" : "6b17fb91-bf25-4ddc-8dc9-85d53ca0f71c",
+    "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" : true,
+    "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" : true,
+    "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" : "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",
+  "attributes" : {
+    "cibaBackchannelTokenDeliveryMode" : "poll",
+    "cibaAuthRequestedUserHint" : "login_hint",
+    "clientOfflineSessionMaxLifespan" : "0",
+    "oauth2DevicePollingInterval" : "5",
+    "clientSessionIdleTimeout" : "0",
+    "clientOfflineSessionIdleTimeout" : "0",
+    "cibaInterval" : "5",
+    "cibaExpiresIn" : "120",
+    "oauth2DeviceCodeLifespan" : "600",
+    "parRequestUriLifespan" : "60",
+    "clientSessionMaxLifespan" : "0",
+    "frontendUrl" : "",
+    "acr.loa.map" : "[]"
+  },
+  "keycloakVersion" : "18.0.2",
+  "userManagedAccessAllowed" : false,
+  "clientProfiles" : {
+    "profiles" : [ ]
+  },
+  "clientPolicies" : {
+    "policies" : [ ]
+  }
+}, {
+  "id" : "e81ed749-e62d-4dd0-a200-8a1406152032",
+  "realm" : "master",
+  "displayName" : "Keycloak",
+  "displayNameHtml" : "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
+  "notBefore" : 0,
+  "defaultSignatureAlgorithm" : "RS256",
+  "revokeRefreshToken" : false,
+  "refreshTokenMaxReuse" : 0,
+  "accessTokenLifespan" : 60,
+  "accessTokenLifespanForImplicitFlow" : 900,
+  "ssoSessionIdleTimeout" : 1800,
+  "ssoSessionMaxLifespan" : 36000,
+  "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" : 300,
+  "oauth2DeviceCodeLifespan" : 600,
+  "oauth2DevicePollingInterval" : 600,
+  "enabled" : true,
+  "sslRequired" : "external",
+  "registrationAllowed" : false,
+  "registrationEmailAsUsername" : false,
+  "rememberMe" : false,
+  "verifyEmail" : false,
+  "loginWithEmailAllowed" : true,
+  "duplicateEmailsAllowed" : false,
+  "resetPasswordAllowed" : false,
+  "editUsernameAllowed" : false,
+  "bruteForceProtected" : false,
+  "permanentLockout" : false,
+  "maxFailureWaitSeconds" : 900,
+  "minimumQuickLoginWaitSeconds" : 60,
+  "waitIncrementSeconds" : 60,
+  "quickLoginCheckMilliSeconds" : 1000,
+  "maxDeltaTimeSeconds" : 43200,
+  "failureFactor" : 30,
+  "roles" : {
+    "realm" : [ {
+      "id" : "c03d1d72-4237-4da2-b4a8-afe18ed88907",
+      "name" : "admin",
+      "description" : "${role_admin}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "create-realm" ],
+        "client" : {
+          "master-realm" : [ "manage-realm", "view-events", "view-authorization", "manage-users", "impersonation", "manage-identity-providers", "query-realms", "view-users", "view-identity-providers", "view-clients", "query-groups", "create-client", "view-realm", "manage-clients", "query-users", "manage-events", "manage-authorization", "query-clients" ],
+          "kop-apitest-verw-realm" : [ "manage-identity-providers", "view-users", "query-users", "view-authorization", "manage-realm", "view-realm", "manage-clients", "manage-events", "query-clients", "query-groups", "create-client", "query-realms", "view-events", "manage-users", "manage-authorization", "view-identity-providers", "impersonation", "view-clients" ]
+        }
+      },
+      "clientRole" : false,
+      "containerId" : "e81ed749-e62d-4dd0-a200-8a1406152032",
+      "attributes" : { }
+    }, {
+      "id" : "000d8005-a3ec-4f47-8e97-23d644a117cf",
+      "name" : "default-roles-master",
+      "description" : "${role_default-roles}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "offline_access", "uma_authorization" ],
+        "client" : {
+          "account" : [ "view-profile", "manage-account" ]
+        }
+      },
+      "clientRole" : false,
+      "containerId" : "e81ed749-e62d-4dd0-a200-8a1406152032",
+      "attributes" : { }
+    }, {
+      "id" : "0162b5b8-5461-48c7-b253-f4ceaf603b1a",
+      "name" : "create-realm",
+      "description" : "${role_create-realm}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "e81ed749-e62d-4dd0-a200-8a1406152032",
+      "attributes" : { }
+    }, {
+      "id" : "5ca51565-71f0-47ce-9372-287c9bd54f5a",
+      "name" : "offline_access",
+      "description" : "${role_offline-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "e81ed749-e62d-4dd0-a200-8a1406152032",
+      "attributes" : { }
+    }, {
+      "id" : "c4200c9d-0478-4709-9981-7240d7bb550f",
+      "name" : "uma_authorization",
+      "description" : "${role_uma_authorization}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "e81ed749-e62d-4dd0-a200-8a1406152032",
+      "attributes" : { }
+    } ],
+    "client" : {
+      "security-admin-console" : [ ],
+      "admin-cli" : [ ],
+      "account-console" : [ ],
+      "broker" : [ {
+        "id" : "4e01b517-610b-4f9f-9d78-bf97f0bd854f",
+        "name" : "read-token",
+        "description" : "${role_read-token}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "d0de7847-0f54-4933-8796-7dbf3c6042a7",
+        "attributes" : { }
+      } ],
+      "kop-apitest-verw-realm" : [ {
+        "id" : "ccd6f26c-0400-4dde-85bd-d80a705f6515",
+        "name" : "query-clients",
+        "description" : "${role_query-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "d5662b9c-adb8-4ece-a7f0-30347024de44",
+        "name" : "create-client",
+        "description" : "${role_create-client}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "59d5a221-ebcb-4539-a642-f32c2ab8a1fd",
+        "name" : "manage-identity-providers",
+        "description" : "${role_manage-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "9f48bcad-dab5-4e67-879f-922b654e574a",
+        "name" : "query-groups",
+        "description" : "${role_query-groups}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "be8bcea6-f795-49d3-abb7-627026f85d28",
+        "name" : "query-realms",
+        "description" : "${role_query-realms}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "24aca00d-d3a2-4503-98a3-9073705748b9",
+        "name" : "view-users",
+        "description" : "${role_view-users}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "kop-apitest-verw-realm" : [ "query-users", "query-groups" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "3d68d987-f0fc-4781-838d-7baf5e974659",
+        "name" : "manage-users",
+        "description" : "${role_manage-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "2e3a35e1-0356-4a26-b6ca-f6e5a3b0cfbc",
+        "name" : "view-events",
+        "description" : "${role_view-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "29530ef0-2018-4156-829a-acf9b5ff5da2",
+        "name" : "manage-authorization",
+        "description" : "${role_manage-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "7823b717-dbbc-403c-9713-2db3eb784a08",
+        "name" : "query-users",
+        "description" : "${role_query-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "9e3caf25-82b8-4e84-b19f-cf4519054925",
+        "name" : "view-identity-providers",
+        "description" : "${role_view-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "90dba6b2-d628-4824-8e02-8208dfe3f162",
+        "name" : "impersonation",
+        "description" : "${role_impersonation}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "1d5929ae-1dce-421f-9a5d-7aca1a872e52",
+        "name" : "view-authorization",
+        "description" : "${role_view-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "003b3af2-6856-4c5c-a005-153770863fae",
+        "name" : "manage-realm",
+        "description" : "${role_manage-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "6875fd3c-4c51-4780-85e9-6a8a4fb7fc20",
+        "name" : "view-realm",
+        "description" : "${role_view-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "4b5f482e-8b78-41b3-b9c8-aaf6e76819e1",
+        "name" : "manage-clients",
+        "description" : "${role_manage-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "29d9cfe0-ecc6-4c99-8300-d82465beb7df",
+        "name" : "manage-events",
+        "description" : "${role_manage-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      }, {
+        "id" : "51733859-c072-4f9d-bc7f-fabeca52a34e",
+        "name" : "view-clients",
+        "description" : "${role_view-clients}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "kop-apitest-verw-realm" : [ "query-clients" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+        "attributes" : { }
+      } ],
+      "master-realm" : [ {
+        "id" : "332b2182-e47e-46b3-b0d4-27c809ec9166",
+        "name" : "query-realms",
+        "description" : "${role_query-realms}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "929317c0-4e94-4044-b51f-833f55768bc5",
+        "name" : "view-users",
+        "description" : "${role_view-users}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "master-realm" : [ "query-users", "query-groups" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "5867e198-5144-4b8f-a77e-79defd2b7ebb",
+        "name" : "manage-realm",
+        "description" : "${role_manage-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "773c6077-175e-4da3-8276-f86b360615a8",
+        "name" : "view-clients",
+        "description" : "${role_view-clients}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "master-realm" : [ "query-clients" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "2a669505-d12e-407a-be22-f2a2a2ad3050",
+        "name" : "view-events",
+        "description" : "${role_view-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "20efe9e9-469e-43d5-8d9e-d0132586db6d",
+        "name" : "view-identity-providers",
+        "description" : "${role_view-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "a82d2a8b-3b61-43cd-9ccf-1b1bd99e5964",
+        "name" : "view-authorization",
+        "description" : "${role_view-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "cf8aef6f-6d68-46fe-a2a2-f5b964be8363",
+        "name" : "query-groups",
+        "description" : "${role_query-groups}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "1b98e3b5-3c33-4db2-a7a6-45fc7e1578d9",
+        "name" : "create-client",
+        "description" : "${role_create-client}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "d8782c70-31f8-486c-be81-cba0deebe000",
+        "name" : "manage-clients",
+        "description" : "${role_manage-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "27c1c898-50ee-423e-bfcc-968bb13b2402",
+        "name" : "view-realm",
+        "description" : "${role_view-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "df36f0a1-eaea-4921-905a-cd9ce5221135",
+        "name" : "query-users",
+        "description" : "${role_query-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "5168578d-2aa3-4723-a57e-421d089e24f7",
+        "name" : "manage-users",
+        "description" : "${role_manage-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "9890dd8c-642d-45d2-8826-7bd92f21d346",
+        "name" : "impersonation",
+        "description" : "${role_impersonation}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "b5dde334-ef65-40ed-8515-032a77ea76f3",
+        "name" : "manage-events",
+        "description" : "${role_manage-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "1dedc1c6-9b01-420f-852f-a5c4f42bbaed",
+        "name" : "manage-authorization",
+        "description" : "${role_manage-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "076a68b1-77ab-4b98-a86d-55524917e713",
+        "name" : "manage-identity-providers",
+        "description" : "${role_manage-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      }, {
+        "id" : "a8ad610f-7f11-4c3f-8966-01162b0f04b4",
+        "name" : "query-clients",
+        "description" : "${role_query-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+        "attributes" : { }
+      } ],
+      "account" : [ {
+        "id" : "20c66340-95ee-4372-80df-f2071ad9cb25",
+        "name" : "view-consent",
+        "description" : "${role_view-consent}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+        "attributes" : { }
+      }, {
+        "id" : "c3fffedc-6641-42f4-8fd2-820195c73a4f",
+        "name" : "manage-account-links",
+        "description" : "${role_manage-account-links}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+        "attributes" : { }
+      }, {
+        "id" : "deaea61a-7681-4f26-af62-8ca8f63d3d70",
+        "name" : "delete-account",
+        "description" : "${role_delete-account}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+        "attributes" : { }
+      }, {
+        "id" : "0683711d-34d5-4966-88cc-87c7e57db7ba",
+        "name" : "view-profile",
+        "description" : "${role_view-profile}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+        "attributes" : { }
+      }, {
+        "id" : "ce17b81e-17e1-47d2-8cf0-c1d39088af0c",
+        "name" : "manage-consent",
+        "description" : "${role_manage-consent}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "view-consent" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+        "attributes" : { }
+      }, {
+        "id" : "9526bdba-d1e9-4501-8e3b-12faa10db6b4",
+        "name" : "manage-account",
+        "description" : "${role_manage-account}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "manage-account-links" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+        "attributes" : { }
+      }, {
+        "id" : "10f559dd-a86f-4fcc-964b-189a8c050884",
+        "name" : "view-applications",
+        "description" : "${role_view-applications}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+        "attributes" : { }
+      } ]
+    }
+  },
+  "groups" : [ ],
+  "defaultRole" : {
+    "id" : "000d8005-a3ec-4f47-8e97-23d644a117cf",
+    "name" : "default-roles-master",
+    "description" : "${role_default-roles}",
+    "composite" : true,
+    "clientRole" : false,
+    "containerId" : "e81ed749-e62d-4dd0-a200-8a1406152032"
+  },
+  "requiredCredentials" : [ "password" ],
+  "otpPolicyType" : "totp",
+  "otpPolicyAlgorithm" : "HmacSHA1",
+  "otpPolicyInitialCounter" : 0,
+  "otpPolicyDigits" : 6,
+  "otpPolicyLookAheadWindow" : 1,
+  "otpPolicyPeriod" : 30,
+  "otpSupportedApplications" : [ "FreeOTP", "Google Authenticator" ],
+  "webAuthnPolicyRpEntityName" : "keycloak",
+  "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
+  "webAuthnPolicyRpId" : "",
+  "webAuthnPolicyAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyRequireResidentKey" : "not specified",
+  "webAuthnPolicyUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyCreateTimeout" : 0,
+  "webAuthnPolicyAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyAcceptableAaguids" : [ ],
+  "webAuthnPolicyPasswordlessRpEntityName" : "keycloak",
+  "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ],
+  "webAuthnPolicyPasswordlessRpId" : "",
+  "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified",
+  "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyPasswordlessCreateTimeout" : 0,
+  "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ],
+  "users" : [ {
+    "id" : "6314093b-975f-4e83-a1a5-81e5ebaff3fb",
+    "createdTimestamp" : 1660890109214,
+    "username" : "admin",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : false,
+    "credentials" : [ {
+      "id" : "023812f6-e9d2-4588-84eb-db5676579068",
+      "type" : "password",
+      "createdDate" : 1660890109412,
+      "secretData" : "{\"value\":\"kwvQW91WpNbg6SwNerhqSNb1fmmR1sut54bGXEOiIu1MaZtB4odDivEPTSzLLx/b5QN60Ek5am0avh180Wl0Rg==\",\"salt\":\"ARAVPQWDMYd1E7Eot8wPtQ==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-master", "admin" ],
+    "clientRoles" : {
+      "kop-apitest-verw-realm" : [ "query-clients", "create-client", "manage-identity-providers", "query-groups", "query-realms", "view-users", "view-events", "manage-users", "manage-authorization", "view-identity-providers", "query-users", "view-authorization", "manage-realm", "view-realm", "manage-clients", "manage-events", "view-clients" ]
+    },
+    "notBefore" : 0,
+    "groups" : [ ]
+  } ],
+  "scopeMappings" : [ {
+    "clientScope" : "offline_access",
+    "roles" : [ "offline_access" ]
+  } ],
+  "clientScopeMappings" : {
+    "account" : [ {
+      "client" : "account-console",
+      "roles" : [ "manage-account" ]
+    } ]
+  },
+  "clients" : [ {
+    "id" : "816a0f6b-5f92-4014-af04-c9c6445c969b",
+    "clientId" : "account",
+    "name" : "${client_account}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/master/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/master/account/*" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "e82aa78d-b4d4-4b9c-b305-b36c1c29e274",
+    "clientId" : "account-console",
+    "name" : "${client_account-console}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/master/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/master/account/*" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "pkce.code.challenge.method" : "S256"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "protocolMappers" : [ {
+      "id" : "6bceba1e-e804-4bab-9fdd-9183f8194379",
+      "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" : "851c207a-076b-45af-af0a-df374c43dee5",
+    "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" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "d0de7847-0f54-4933-8796-7dbf3c6042a7",
+    "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" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "80711f4c-5abf-4fb1-8dc8-f500115011dc",
+    "clientId" : "kop-apitest-verw-realm",
+    "name" : "kop-apitest-verw Realm",
+    "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,
+    "attributes" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ ],
+    "optionalClientScopes" : [ ]
+  }, {
+    "id" : "820e5013-a22f-402b-bdc0-d382d9e5bc64",
+    "clientId" : "master-realm",
+    "name" : "master Realm",
+    "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,
+    "attributes" : { },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "5604a389-a474-4e56-a4ba-7af9209643b4",
+    "clientId" : "security-admin-console",
+    "name" : "${client_security-admin-console}",
+    "rootUrl" : "${authAdminUrl}",
+    "baseUrl" : "/admin/master/console/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/admin/master/console/*" ],
+    "webOrigins" : [ "+" ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "pkce.code.challenge.method" : "S256"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "protocolMappers" : [ {
+      "id" : "9dee6645-3070-4af0-bb4a-6bfa356827ad",
+      "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" : "9408ce58-2a52-4b1c-b4ff-515e91e9efc3",
+    "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" : "94c500cb-0358-477a-968f-82a5aea6c6b3",
+      "name" : "acr loa level",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-acr-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "id.token.claim" : "true",
+        "access.token.claim" : "true"
+      }
+    } ]
+  }, {
+    "id" : "388bc69d-1f54-4385-8c1a-e718ce4ca542",
+    "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" : "ee33d532-8b55-44b8-93e2-523ac9e60b38",
+      "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" : "26004e1a-4aae-40d8-b85c-91e120efd172",
+      "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" : "119dd2f4-f91d-418a-a1f5-a31bf9f584cd",
+    "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" : "19d30839-7a1b-4216-b12f-6c65284717d8",
+      "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" : "c1b516e2-e7ac-436e-b876-da22083efea2",
+      "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" : "e472ee44-5b9c-4ab1-82d7-fc9a2b62bb71",
+    "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" : "dd5e2bf8-61d6-4b42-b06f-0330f32356a0",
+      "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" : "755ff7b9-dd91-47a3-b8ea-1fd0ce439dae",
+    "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" : "ae39ed0c-07fd-4bff-8d52-af4ea1daae2e",
+    "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" : "7beceec4-c579-440d-ae1e-934aab4383c0",
+      "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" : "82e09e62-6449-41fa-8192-a5610e8fce69",
+      "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" : "111dfd6a-a2c8-4884-9bb8-8d2120aa5138",
+      "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" : "eec97836-6bd9-4073-8c97-e76d4ce2b749",
+      "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" : "2d39ee08-9ae2-46ee-92dd-0f58b03ef86f",
+      "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" : "fda1318b-802a-4711-990f-b8b4e52ac45b",
+      "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" : "d0a14859-586d-42f2-b0ba-1956348c30dc",
+      "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" : "b2ff65b7-8606-4440-99d3-1dc509cd0479",
+      "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" : "84d8cbfc-f5d0-453f-9b72-84b1a443864a",
+      "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" : "9d670b5b-5c37-4af4-b832-75a14fff3573",
+      "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" : "5935fb83-737a-456d-9bd6-45ec5d1ef8c4",
+      "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" : "a044140c-f4b0-421a-9e2c-1a9c9237ff4a",
+      "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" : "2bae9756-deef-4e5b-acf1-7ba58fb82e71",
+      "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" : "c61b1f2a-1c31-41c4-89dc-326012c0d0ba",
+      "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" : "3ec0a858-4e22-4330-acc7-ec8b34797062",
+    "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" : "16f6505d-36f9-4a88-92a6-1e2602822531",
+      "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" : "5149261b-6018-4afd-8635-09ee0ff905c7",
+      "name" : "audience resolve",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-audience-resolve-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    }, {
+      "id" : "2b7a0ce8-7cfd-47eb-9a34-b08787dc9eff",
+      "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"
+      }
+    } ]
+  }, {
+    "id" : "c722b9d1-c67f-492e-b75d-e614f791d7cb",
+    "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" : "1d8da349-319d-465d-bd9c-dfa731b6efde",
+      "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" : "c3c1ae73-ac3c-4a53-9cc1-c78ed646722f",
+      "name" : "groups",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "multivalued" : "true",
+        "user.attribute" : "foo",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "groups",
+        "jsonType.label" : "String"
+      }
+    } ]
+  }, {
+    "id" : "08f3e0e4-f228-4c5b-b6a3-d960e689be1a",
+    "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" : "16b2017f-dd76-4ae1-84b6-0ea63ac4e89e",
+      "name" : "allowed web origins",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-allowed-origins-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    } ]
+  }, {
+    "id" : "f356a880-f40b-4c9f-9b0d-064ff3925734",
+    "name" : "role_list",
+    "description" : "SAML role list",
+    "protocol" : "saml",
+    "attributes" : {
+      "consent.screen.text" : "${samlRoleListScopeConsentText}",
+      "display.on.consent.screen" : "true"
+    },
+    "protocolMappers" : [ {
+      "id" : "8cbcb253-b64d-4da8-85d7-29ef50e9a657",
+      "name" : "role list",
+      "protocol" : "saml",
+      "protocolMapper" : "saml-role-list-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "single" : "false",
+        "attribute.nameformat" : "Basic",
+        "attribute.name" : "Role"
+      }
+    } ]
+  } ],
+  "defaultDefaultClientScopes" : [ "web-origins", "email", "roles", "acr", "profile", "role_list" ],
+  "defaultOptionalClientScopes" : [ "phone", "offline_access", "microprofile-jwt", "address" ],
+  "browserSecurityHeaders" : {
+    "contentSecurityPolicyReportOnly" : "",
+    "xContentTypeOptions" : "nosniff",
+    "xRobotsTag" : "none",
+    "xFrameOptions" : "SAMEORIGIN",
+    "xXSSProtection" : "1; mode=block",
+    "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+    "strictTransportSecurity" : "max-age=31536000; includeSubDomains"
+  },
+  "smtpServer" : { },
+  "eventsEnabled" : false,
+  "eventsListeners" : [ "jboss-logging" ],
+  "enabledEventTypes" : [ ],
+  "adminEventsEnabled" : false,
+  "adminEventsDetailsEnabled" : false,
+  "identityProviders" : [ ],
+  "identityProviderMappers" : [ ],
+  "components" : {
+    "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
+      "id" : "8b89de8d-1fef-4a65-b4ee-c402c803d187",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper" ]
+      }
+    }, {
+      "id" : "adafd8a4-151c-43c3-bab2-98bd9d3c8b89",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    }, {
+      "id" : "94c0848a-617a-4706-bc42-102ca2b2496a",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper" ]
+      }
+    }, {
+      "id" : "c6cc93f0-7092-4ace-b012-c3813d4edff1",
+      "name" : "Full Scope Disabled",
+      "providerId" : "scope",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    }, {
+      "id" : "d2bc0e39-1428-434c-925d-d558845e1697",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    }, {
+      "id" : "8b4ae70c-67b7-4cb8-801d-8b5ab357b4d2",
+      "name" : "Trusted Hosts",
+      "providerId" : "trusted-hosts",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "host-sending-registration-request-must-match" : [ "true" ],
+        "client-uris-must-match" : [ "true" ]
+      }
+    }, {
+      "id" : "d5961ff8-c1b2-421b-9000-850fd5d000d6",
+      "name" : "Max Clients Limit",
+      "providerId" : "max-clients",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "max-clients" : [ "200" ]
+      }
+    }, {
+      "id" : "7716d0ff-3c75-4158-8d79-410f15586d49",
+      "name" : "Consent Required",
+      "providerId" : "consent-required",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    } ],
+    "org.keycloak.keys.KeyProvider" : [ {
+      "id" : "467045d7-ad14-4a25-92ca-047608aa0cfa",
+      "name" : "hmac-generated",
+      "providerId" : "hmac-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "cd753a25-9bd0-4643-aa08-091dcab19bdc" ],
+        "secret" : [ "ZMruEVEqsgkD6OD8f7oFpokHIW_wwmwUnNX9vbDv0COuuhxA3EUZ6KY9ihiKdkB7SWXXuYRJhXSe_DEJB5yMBA" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "HS256" ]
+      }
+    }, {
+      "id" : "2588c88f-2b4d-4461-aead-64ef172c1101",
+      "name" : "rsa-generated",
+      "providerId" : "rsa-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEowIBAAKCAQEArGeuuZIo0ihMH8aba6PIiV97w9YqZl+gWmuSRUIZaQ+FhzSe2AKQb6FGrdyEE7y3rj85x1RepxMhyKMZiq9vX/KgA/TsShmjAW2zuwnoJzoM5xyzsWolu2F8jrOo9NwDVG+LzSankfov5QsTgGw/Ndb2v1YrlpNKeke7vwBle3lj/XMdgcTel8fXSQtdsHpNz11GlK7g1WjkmbuoRdgkxtoCtqkwFlLRa4AzqQip4cqW2ej7/nLHQcoW4YMdfMsFsWXjk6y7mK7DzrytVoqy2RTCKg/MFho7Q0eKLSHtkivBJnBIBAFf7Rf0RNEo4kLU1HBep1lH8vxPVRp14cS+rQIDAQABAoIBAGNiJXu+AKAdMLzEjYWAVbKzAzKCO9Dl4RcemaQpFWLV2sB1GfglikN/cbH5w31pNW1R7ymzvhiL09bIBopG1Wo2//0n7CpPGwNQzOHONTCfqx5zEjb8nKGm8dmFQaldRuIepzVsyf5BfeiH+Qb333xW3ciwkNHtOGrC/Tx+qwGApz04Jh2fb2jx4xcOlRfXT7kpM5phqwVE8QWSW242TJZn1CFL2VKu/s9UFF/qJf4Ds2/o89HTkzklbF+CkFBpBGvH/7ZQ7ePB5f97qSck0V/Nxyo4DQMnLIYMZSfHWjg1fsrmDRd5DHkeGn+Jx9srsvIs1wSO0vzJBPRMq3shOCECgYEA2gpgnTrfhTbMytDz9n3WrVdwmlTNV99c5iFLxRB1Ik9ANXkp+Zm9GazPHfjSSDPd5g2atRWk4K6a2dpxRr+2rJtYMeRyMApXC60Uk5+jQrHtVn98K6unybboJlJoA7sFTxLHAJx7FpEjqokUpLKX0Wualx4Jpz2uVK2ZM5OpLNUCgYEAymtsMjBf6vGVdzc89n4JKIoGPcJBFY4iH4/rxVyw20g5pl0wiU8l3ZhHJZXgWdTV/LOVV2QHGv928qwZU+jhAWcfKPAGkCjC5OSOuBVkbefiEpeu2h74ziTwwnTa+0dYtH607WfLbooTh3Xs8YxnbtdPS/EOeG0R2TKjMG5DVnkCgYAT0Z+oiwJoNGv2/3k9bYDG7szAanbjxtzF2j7t4aoT/Uoj0iiblHrYy5lj6wsKHxTLZW8riJUdCyHuLWngeWqcU953YoFylm4FFK1rIbaQSGX/V8UsnwS4VBTT7uefdy9rWZSXHKIfkf/A74bd1ZHxKiu6ErPj7Lpc3g6v3nshJQKBgQC9FG8yyqEuc5Asljqp/b1MUvHVirkFC4mwdd3Es/q4OtUvI+mMuZQjVHVRFJlHEFr6/D1KLrO8clmIAV5/VQ+pIcynjt5ylsDG0wDFz6XKTEqPF4VLVpcO6M7Etic/hbvEjn8vLD+I+A2aAXvdfku37AO0am4b67Y6buSk/rqD8QKBgGmaVPqViroiqRnYf5zcuMiYh1UXecrIyZTXSg/DTscHAR6wMg5FH+DZdTb/1i9ECF6OEJowqjt12xzm3/JzU8rEWlmEpyuA5dB5kzMxqdKyhPTGbexqiyWEBP+bv3u1UTrGBrzvBkMNppkp+qP2YIEnjM2g6GpH05LqNOPY9hcp" ],
+        "keyUse" : [ "SIG" ],
+        "certificate" : [ "MIICmzCCAYMCBgGCtMPTnDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjIwODE5MDYyMDA4WhcNMzIwODE5MDYyMTQ4WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsZ665kijSKEwfxptro8iJX3vD1ipmX6Baa5JFQhlpD4WHNJ7YApBvoUat3IQTvLeuPznHVF6nEyHIoxmKr29f8qAD9OxKGaMBbbO7CegnOgznHLOxaiW7YXyOs6j03ANUb4vNJqeR+i/lCxOAbD811va/ViuWk0p6R7u/AGV7eWP9cx2BxN6Xx9dJC12wek3PXUaUruDVaOSZu6hF2CTG2gK2qTAWUtFrgDOpCKnhypbZ6Pv+csdByhbhgx18ywWxZeOTrLuYrsPOvK1WirLZFMIqD8wWGjtDR4otIe2SK8EmcEgEAV/tF/RE0SjiQtTUcF6nWUfy/E9VGnXhxL6tAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJjTBsIwSryLhOj6e/bczs6IKAz8ZKRsB/NoV0GLHN2MTbP1MiThj3urXddNrAOaOp5DcYmh4rhLAbhe1AVy1OuQVL8MYXi0gT+vlkuoPQwtYbcAkadQ8EBo0Vb4rG3kyE5WgVKev2mdFlnRXMRJxjE066Y+tCKvA9tyI/z+QxOCKGoU/pEhXhDpFRU/AOSOAskv3rlL4t0rO8q7JdUAA39U0LBf2ptCvDlHl9oA0xZxS53VuZ990dXR8dTfuM4/IcA2BlAg5zBsmPp8rkz+X088SJ8XWFwRNuWNq6LVxb7atchGdJAOdv8enYWJJHUPd4B78BxgiUtVFWbnXaq98qU=" ],
+        "priority" : [ "100" ]
+      }
+    }, {
+      "id" : "576ffb1e-1a68-4b3c-b593-d48957e6032f",
+      "name" : "rsa-enc-generated",
+      "providerId" : "rsa-enc-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEpAIBAAKCAQEAsfUHnfqhyPvT13cTkd96CnoX9QyxsLCw1cJ71b1SHkrJsVUHwIhgoUhriH0ZphM8MCMlWtia+icvDsuXSTaMqcQzv57rfaU5OXHOEQJnIzUgu/YObD92Scrb8xY0ZenWFpjIAF4+l6EF7EGt5XsmFuRrgjHYwkLxnHvE7sONJv9/lwufB9T1YWj59y+xTifrTFvLCOcgMjloWh/pkoe/HrIagSZ6QgIEKCw6T5oRJ/uMvNSKl2zelHfLsPaUu9fW9mp/Zh9ZqttbPHrKgM+X/YYpxjoIbTDt/wJ+BBsXue/39EDUZFRuhUg1oDlDE6HISsj69xbqMaBCUOthGxNpCwIDAQABAoIBAQCOSb4yacDMQ9apVDOYklgxYlgffmvhPBXYhO2hBARR5jiIitVs815X9uDMPEKy0HRyhNeMYN7hn0z4Bn9Lcctcvl0mHPpr9xzfOoiqfwJaW1N2FpKHqOJ6tDHTlvCEgEjGvphD+xcPBBgJRKa3cxUMfs0bR6HqCb7IAQqAYmlNQO2JzHwjP/yCMvcMgvcVFi/birhn5HkWlybMoxb3Jd4p9tgAjGSZvqHeJj74LnCYXvL771ZTgt8djnEctEVRWryuBMd+uAe/Ar0dba40HbnL6u3WPtXRj/YcR/OMMK1scmi2BqJwrTlcqB9KfOcbR8/JEwGw6FOqib4WoGGqfYO5AoGBAN0QX4tZmllJxzfiVc4GxYYbRBr46xItBUEtztupi7su/X+Q7eiSRJYSt10ESPElBtjb45KHkg/ffh4QPvPEjq2R8ROQMxkfn+TC3jCvK0kEddqzGXKtuP5i3mwwa4MkhWSSFUq6W5b11hWWEJvzwoPiadw2gpIYcfujzifszgMFAoGBAM4UrRLlNCrFBHOrHIRUrl0S1Ft8/QCsUAl4jIp7WNdlnpn+Wj5SQHLaYHPf+QrVkVxzN+xd9Ol3kqWOcGtFtz1Kuxpb/YtPVHm2l6JazgP+VN3wDTvKgrW7OzZuulhHEyaRmwt3s/AorxIgwfpxs/oy8OCUv1840Q89YLf6JJjPAoGARQw2K5pjIXxv4z6oul9XFtoxXZNeKSEywPcD44yDfoXg3BVymfAFyDI0X7NU7S05hEa6QCxkLN0L0WwVnaJJRmGNQSULMM+164gKSn6MMJRaE2NZkX49iAdtnbFKA35Gw/D1AZBPx0kmAzwKGAv9N6BinEvSYLuN7qFtZP8MIdkCgYEAohuvnbqBE9fRTa/fidUXKA3k0Gb8mmfxudGDNHgdBathXJ+xm26WVgKkduJLhJNFemUEK8IpIvI1gFgQ5MF9iBBeKDkOtGRd/jR9CXDGuGt7lO39avg9Y/l5dbMakNCwJtnJDfdGq3dFaEwuavTAb+Ncij1YYO5Pvd45U9/IpA8CgYBNQUhzKpE1TG+q75UAs3O6BvN4fldxWMjgMlkApfmnPWUuNPhioMyUeHUt/GllE0mm7F+QU7MSWXZO6VHw5nkCuOObfib+OPmau7C4SsHCd8czd+T+9kyLJK0ZC6s5+IgFCImVqkySM9UuptmPWsdz9NbzGtYkcuwJrVHxoevtOQ==" ],
+        "keyUse" : [ "ENC" ],
+        "certificate" : [ "MIICmzCCAYMCBgGCtMPUHDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjIwODE5MDYyMDA4WhcNMzIwODE5MDYyMTQ4WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx9Qed+qHI+9PXdxOR33oKehf1DLGwsLDVwnvVvVIeSsmxVQfAiGChSGuIfRmmEzwwIyVa2Jr6Jy8Oy5dJNoypxDO/nut9pTk5cc4RAmcjNSC79g5sP3ZJytvzFjRl6dYWmMgAXj6XoQXsQa3leyYW5GuCMdjCQvGce8Tuw40m/3+XC58H1PVhaPn3L7FOJ+tMW8sI5yAyOWhaH+mSh78eshqBJnpCAgQoLDpPmhEn+4y81IqXbN6Ud8uw9pS719b2an9mH1mq21s8esqAz5f9hinGOghtMO3/An4EGxe57/f0QNRkVG6FSDWgOUMTochKyPr3FuoxoEJQ62EbE2kLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAfhCLcbGQIeOeRono42Bx/dp7IlVZbCFcdwB83awD/W8ACaRmnwQYL+3XyJlCOLjLGUvQnvPONp9yEK09dZxQvILv5WNeJ2IyH7uNMB6o7POBMnxFVkVTa03T13lQur9t/MmyF6XD9uMSEsb22F5/CAham1FZ02P/E7bnnkubFoNR7z6aWC/D0wTxDXzUe6DdTdthJpJpw+JQkq0tb+GW0MP3vxIjlEpbIye6ETlGtn5zjlSF1Nswv84/MSI367nb1982UVJWvsHGjyF2iVcei24DR99RM632llV7y5rzCRBleyZmRXriEDF114JrLcWwvVTUyRTdEzKHrZx0RP5Ak=" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "RSA-OAEP" ]
+      }
+    }, {
+      "id" : "bc87ad24-becc-4c81-b062-164fe7206668",
+      "name" : "aes-generated",
+      "providerId" : "aes-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "e94955c6-2815-4d38-b90d-dc245115d6cb" ],
+        "secret" : [ "2ZU_Dx4DTO6wcqbYKMCWBw" ],
+        "priority" : [ "100" ]
+      }
+    } ]
+  },
+  "internationalizationEnabled" : false,
+  "supportedLocales" : [ ],
+  "authenticationFlows" : [ {
+    "id" : "88de600a-fb85-46a3-8729-7c81827943ee",
+    "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" : "a63f756d-163f-46b1-a7b8-102f7daac662",
+    "alias" : "Authentication Options",
+    "description" : "Authentication options.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "basic-auth",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "basic-auth-otp",
+      "authenticatorFlow" : false,
+      "requirement" : "DISABLED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "auth-spnego",
+      "authenticatorFlow" : false,
+      "requirement" : "DISABLED",
+      "priority" : 30,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "c3b7632e-0417-447a-a20d-c0c7880ed4b5",
+    "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" : "35890077-9430-4bbd-8a67-bcd4f855a33b",
+    "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" : "2fb70949-779b-4881-9f62-f89f3ff1ca36",
+    "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" : "c23477cd-6e3f-444f-b9d9-b355d92163ef",
+    "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" : "1336e226-e4ea-4b02-b922-751bc5fb7965",
+    "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" : "99bf6afa-2b89-453f-bb15-5f837b4c2ab1",
+    "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" : "a3cabd98-262d-43d7-bba4-df6476444b40",
+    "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" : "cabd2c42-5145-452a-ab08-d3c87a40afa3",
+    "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" : "7749f55c-3218-4ce7-9d52-0411de70dab1",
+    "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" : "34462526-355a-406a-9cc7-056f69f4ed13",
+    "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" : "89c54236-bee8-453b-ac0d-d5d5b293b301",
+    "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" : "4f5178b5-8b7c-4ba2-8fe1-46856d50395a",
+    "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" : "2c53dfdb-dffb-4d23-8d71-eb8588528ede",
+    "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" : "5fc8c202-b566-497f-9290-8ec8fceef0a5",
+    "alias" : "http challenge",
+    "description" : "An authentication flow based on challenge-response HTTP Authentication Schemes",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "no-cookie-redirect",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticatorFlow" : true,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : true,
+      "flowAlias" : "Authentication Options",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "bc8a31cd-ca15-4eaf-89b0-27e85cd2bf95",
+    "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" : "aa4c56c3-9b58-4bce-afd2-0903488919bd",
+    "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-profile-action",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 40,
+      "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" : "a8bec154-7966-4de2-a8ff-447182f7d971",
+    "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" : "70bb30f8-b553-4a17-aa33-4195e9c93904",
+    "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" : "2f0a7833-c6dc-4c22-976a-8a8c896a09cf",
+    "alias" : "create unique user config",
+    "config" : {
+      "require.password.update.after.registration" : "false"
+    }
+  }, {
+    "id" : "1243d693-d577-4b7f-b544-ad9e4b369faf",
+    "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" : true,
+    "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" : true,
+    "defaultAction" : false,
+    "priority" : 50,
+    "config" : { }
+  }, {
+    "alias" : "delete_account",
+    "name" : "Delete Account",
+    "providerId" : "delete_account",
+    "enabled" : false,
+    "defaultAction" : false,
+    "priority" : 60,
+    "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",
+  "attributes" : {
+    "cibaBackchannelTokenDeliveryMode" : "poll",
+    "cibaExpiresIn" : "120",
+    "cibaAuthRequestedUserHint" : "login_hint",
+    "parRequestUriLifespan" : "60",
+    "cibaInterval" : "5"
+  },
+  "keycloakVersion" : "18.0.2",
+  "userManagedAccessAllowed" : false,
+  "clientProfiles" : {
+    "profiles" : [ ]
+  },
+  "clientPolicies" : {
+    "policies" : [ ]
+  }
+} ]
diff --git a/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension
new file mode 100644
index 0000000000000000000000000000000000000000..79b126e6cdb86bec1f4f08c205de8961bde1934a
--- /dev/null
+++ b/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension
@@ -0,0 +1 @@
+org.mockito.junit.jupiter.MockitoExtension
\ No newline at end of file