diff --git a/README.md b/README.md
index 152c12bb9db365ccfc39a5e245400ae8f383a3b4..5256c01371cc73c98ea4b40bd591164f8484df87 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,13 @@ The following guides illustrate how to use some features concretely:
 * [Spring Data with MongoDB](https://spring.io/projects/spring-data-mongodb)
 * [gRPC-Spring-Boot-Starter Documentation](https://yidongnan.github.io/grpc-spring-boot-starter/en/)
 
+### Properties
+
+| Name                                      | Description                                                                  | Default value        |
+|-------------------------------------------|------------------------------------------------------------------------------|----------------------|
+| ozgcloud.infomanager.allowed-client-names | List of names of grpc clients allowed to access the getServiceUrlOfNachricht | Antragsraum          |
+| ozgcloud.infomanager.postfach-id-key-name | Name of the key used to read the postfach id from the auth token             | legacyPostkorbHandle |
+
 ### Useful commands
 
 Create an entry using grpcurl:
@@ -31,7 +38,7 @@ Create an entry using grpcurl:
 Add a 'Nachricht' to the database using grpcUrl:
 
 ```
-./grpcurl --plaintext -d '{"nachricht": {"postfachId": "28721c6f-b78f-4d5c-a048-19fd2fc429d2", "vorgangId":"6358fd4146811d04010f44d0", "nachrichtId":"1", "nachrichtenListUrl":"static://localhost:9091"}}' localhost:9091 de.mgm.bup.ozg.applicationroom.NachrichtService.SaveNewNachricht
+./grpcurl --plaintext -d '{"nachricht": {"postfachId": "28721c6f-b78f-4d5c-a048-19fd2fc429d2", "vorgangId":"6358fd4146811d04010f44d0", "nachrichtId":"1", "nachrichtenListUrl":"static://localhost:9091"}}' localhost:9091 de.mgm.bup.ozg.antragsraum.infomanager.NachrichtService.SaveNewNachricht
 ```
 
 Query the InfoManager for available services
diff --git a/ozg-info-manager-server/build.gradle b/ozg-info-manager-server/build.gradle
index c0bd510de6ca63f8581c4a85a45fbb4899cb55cd..d23ea0e2dd81b9784be56047d96db83c09024e91 100644
--- a/ozg-info-manager-server/build.gradle
+++ b/ozg-info-manager-server/build.gradle
@@ -1,7 +1,9 @@
 buildscript {
     ext {
         grpcTestVersion = '1.19.0'
-        netDevhGrpcVersion = '2.14.0.RELEASE'
+        netDevhGrpcVersion = '2.15.0.RELEASE'
+        modulithVersion = '1.0.2'
+        grpcVersion = '1.57.2'
         infoManagerInterfaceVersion = '0.0.2-1.a7b24d5-SNAPSHOT'
     }
 }
@@ -65,23 +67,40 @@ license {
 }
 
 dependencies {
+    implementation 'org.springframework.modulith:spring-modulith-starter-core'
     implementation 'org.springframework.boot:spring-boot-starter'
     implementation 'org.springframework.boot:spring-boot-starter-web'
     implementation 'org.springframework.boot:spring-boot-starter-actuator'
     implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
     implementation 'org.springframework.boot:spring-boot-starter-validation'
+    implementation 'org.springframework.boot:spring-boot-starter-security'
+    implementation 'org.springframework.security:spring-security-config'
+    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
+    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
     implementation "net.devh:grpc-server-spring-boot-starter:${netDevhGrpcVersion}"
     implementation "com.mgmtp.bup.ozg:ozg-info-manager-interface:${infoManagerInterfaceVersion}"
     compileOnly 'org.projectlombok:lombok'
     annotationProcessor 'org.projectlombok:lombok'
     developmentOnly 'org.springframework.boot:spring-boot-devtools'
+    testImplementation 'org.springframework.modulith:spring-modulith-starter-test'
     testImplementation 'org.springframework.boot:spring-boot-starter-test'
     testImplementation 'org.junit.jupiter:junit-jupiter'
     testImplementation 'org.testcontainers:testcontainers'
     testImplementation 'org.testcontainers:junit-jupiter'
     testImplementation 'org.testcontainers:mongodb'
+    testImplementation 'com.github.dasniko:testcontainers-keycloak:3.0.0'
+    testImplementation 'org.springframework.boot:spring-boot-starter-webflux'
     testImplementation "io.grpc:grpc-testing:${grpcTestVersion}"
     testImplementation "net.devh:grpc-client-spring-boot-starter:${netDevhGrpcVersion}"
+    testCompileOnly 'org.projectlombok:lombok'
+    testAnnotationProcessor 'org.projectlombok:lombok'
+}
+
+dependencyManagement {
+    imports {
+        mavenBom "org.springframework.modulith:spring-modulith-bom:${modulithVersion}"
+        mavenBom "io.grpc:grpc-bom:${grpcVersion}"
+    }
 }
 
 tasks.named('test') {
diff --git a/ozg-info-manager-server/lombok.config b/ozg-info-manager-server/lombok.config
new file mode 100644
index 0000000000000000000000000000000000000000..d07dd9b0e2b0281fbf514a968b9451cb6af62f93
--- /dev/null
+++ b/ozg-info-manager-server/lombok.config
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den
+# Ministerpräsidenten des Landes Schleswig-Holstein
+# Staatskanzlei
+# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+#
+# Lizenziert unter der EUPL, Version 1.2 oder - sobald
+# diese von der Europäischen Kommission genehmigt wurden -
+# Folgeversionen der EUPL ("Lizenz");
+# Sie dürfen dieses Werk ausschließlich gemäß
+# dieser Lizenz nutzen.
+# Eine Kopie der Lizenz finden Sie hier:
+#
+# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+#
+# Sofern nicht durch anwendbare Rechtsvorschriften
+# gefordert oder in schriftlicher Form vereinbart, wird
+# die unter der Lizenz verbreitete Software "so wie sie
+# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+# ausdrücklich oder stillschweigend - verbreitet.
+# Die sprachspezifischen Genehmigungen und Beschränkungen
+# unter der Lizenz sind dem Lizenztext zu entnehmen.
+#
+
+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/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-configmap.yaml b/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-configmap.yaml
index ae8e607b5b1c9e36a72d174564ae842404014924..2bf85ab5123a536111ccb92a0989798023c62fef 100644
--- a/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-configmap.yaml
+++ b/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-configmap.yaml
@@ -4,3 +4,4 @@ metadata:
   name: "{{ .Values.name }}-configmap"
 data:
   mongodb.autoIndexCreation: "{{ .Values.mongodb.autoIndexCreation }}"
+  jwt.issuerUri: {{ .Values.jwt.issuerUri }}
diff --git a/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-deployment.yaml b/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-deployment.yaml
index d698f2ca4c57bca0747fa59b56a8fdc00e126c67..7aacfa1229805de55dc114d6bf3552c5e6fbcf2e 100644
--- a/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-deployment.yaml
+++ b/ozg-info-manager-server/src/main/helm/templates/ozg-info-manager-deployment.yaml
@@ -34,6 +34,11 @@ spec:
                 configMapKeyRef:
                   name: "{{ .Values.name }}-configmap"
                   key: mongodb.autoIndexCreation
+            - name: SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUERURI
+              valueFrom:
+                configMapKeyRef:
+                  name: "{{ .Values.name }}-configmap"
+                  key: jwt.issuerUri
           resources:
             requests:
               memory: "1Gi"
diff --git a/ozg-info-manager-server/src/main/helm/values.yaml b/ozg-info-manager-server/src/main/helm/values.yaml
index 89bc586311d774a86396c4260cc10d579ce4d42c..e34db6dd36a61defc7f7cc39d9c3e9895ea25a9a 100644
--- a/ozg-info-manager-server/src/main/helm/values.yaml
+++ b/ozg-info-manager-server/src/main/helm/values.yaml
@@ -12,4 +12,6 @@ mongodb:
   database:
   appuser:
     name: SET_BY_ANSIBLE
-    password: SET_BY_ANSIBLE
\ No newline at end of file
+    password: SET_BY_ANSIBLE
+jwt:
+  issuerUri: jkl
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/GrpcConfig.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/GrpcConfig.java
deleted file mode 100644
index 4bea8b80d90d4aa65426d205a57ccaa0d8691470..0000000000000000000000000000000000000000
--- a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/GrpcConfig.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2023.
- * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-
-
-package de.mgm.bup.ozg.antragsraum;
-
-import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@ImportAutoConfiguration({
-        net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration.class,
-        net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration.class,
-
-        net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcHealthServiceAutoConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcMetadataConsulConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcMetadataEurekaConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcMetadataNacosConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcMetadataZookeeperConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcReflectionServiceAutoConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration.class,
-        net.devh.boot.grpc.server.autoconfigure.GrpcServerTraceAutoConfiguration.class
-})
-class GrpcConfig {
-}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplication.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplication.java
index 830bd2cd346e63165cb97a60c58d4235566fd2d5..f0f6be8269d08d2202d259aff6bba8b14f009dee 100644
--- a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplication.java
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplication.java
@@ -24,8 +24,12 @@
 
 package de.mgm.bup.ozg.antragsraum;
 
+import de.mgm.bup.ozg.antragsraum.common.CallBeanFactoryPostProcessor;
+import de.mgm.bup.ozg.antragsraum.common.CallScope;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
 
 @SpringBootApplication
 public class InfoManagerApplication {
@@ -34,4 +38,14 @@ public class InfoManagerApplication {
         SpringApplication.run(InfoManagerApplication.class, args);
     }
 
+    @Bean
+    public CallScope callScope() {
+        return new CallScope();
+    }
+
+    @Bean
+    public static BeanFactoryPostProcessor beanFactoryPostProcessor(CallScope callScope) {
+        return new CallBeanFactoryPostProcessor(callScope);
+    }
+
 }
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/NachrichtEvent.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/NachrichtEvent.java
index fc6cd88db581adf9bb0c47659a0243be2d5f8540..d6585186eb25aa6347a1c7691aea9b4f7a38bcf5 100644
--- a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/NachrichtEvent.java
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/NachrichtEvent.java
@@ -25,6 +25,7 @@
 package de.mgm.bup.ozg.antragsraum;
 
 import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
 import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
@@ -40,10 +41,13 @@ public class NachrichtEvent {
     @Id
     private ObjectId id;
     @NotBlank(message = "Postfach id is missing")
+    @Size(max = 128, message = "Invalid PostfachId")
     private String postfachId;
     @NotBlank(message = "Vorgang id is missing")
+    @Size(max = 64, message = "Invalid VorgangId")
     private String vorgangId;
     @NotBlank(message = "Nachricht id is missing")
+    @Size(max = 64, message = "Invalid NachrichtId")
     private String nachrichtId;
     @NotBlank(message = "Address of nachricht list endpoint is missing")
     private String nachrichtenListUrl;
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/SecurityConfiguration.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/SecurityConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa555eb7c0a35450f6478b4cfaddaec66914dbf3
--- /dev/null
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/SecurityConfiguration.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum;
+
+import de.mgm.bup.ozg.antragsraum.infomanager.InformationServiceGrpc;
+import lombok.extern.log4j.Log4j2;
+import net.devh.boot.grpc.server.security.authentication.BearerAuthenticationReader;
+import net.devh.boot.grpc.server.security.authentication.CompositeGrpcAuthenticationReader;
+import net.devh.boot.grpc.server.security.authentication.GrpcAuthenticationReader;
+import net.devh.boot.grpc.server.security.check.AccessPredicate;
+import net.devh.boot.grpc.server.security.check.GrpcSecurityMetadataSource;
+import net.devh.boot.grpc.server.security.check.ManualGrpcSecurityMetadataSource;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.oauth2.jwt.JwtDecoder;
+import org.springframework.security.oauth2.jwt.JwtDecoders;
+import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@Log4j2
+public class SecurityConfiguration {
+    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
+    private String issuerUrl;
+
+    @Bean
+    JwtAuthenticationProvider jwtAuthenticationProvider() {
+        var provider = new JwtAuthenticationProvider(jwtDecoder());
+        provider.setJwtAuthenticationConverter(jwtAuthenticationConverter());
+        return provider;
+    }
+
+    @Bean
+    JwtAuthenticationConverter jwtAuthenticationConverter() {
+        return new JwtAuthenticationConverter();
+    }
+
+
+    @Bean
+    AuthenticationManager authenticationManager() {
+        return new ProviderManager(List.of(jwtAuthenticationProvider()));
+    }
+
+    @Bean
+    public JwtDecoder jwtDecoder() {
+        return JwtDecoders.fromIssuerLocation(issuerUrl);
+    }
+
+    @Bean
+    GrpcAuthenticationReader authenticationReader() {
+        final List<GrpcAuthenticationReader> readers = new ArrayList<>();
+        readers.add(new BearerAuthenticationReader(BearerTokenAuthenticationToken::new));
+        return new CompositeGrpcAuthenticationReader(readers);
+    }
+
+    @Bean
+    GrpcSecurityMetadataSource grpcSecurityMetadataSource() {
+        final ManualGrpcSecurityMetadataSource source = new ManualGrpcSecurityMetadataSource();
+        source.setDefault(AccessPredicate.denyAll());
+        source.set(InformationServiceGrpc.getGetInformationMethod(), AccessPredicate.authenticated());
+        source.set(InformationServiceGrpc.getGetServiceUrlOfNachrichtMethod(), AccessPredicate.permitAll());
+        return source;
+    }
+}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallBeanFactoryPostProcessor.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallBeanFactoryPostProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc4a536477712ce8a54e96b5fc0348bf7d275212
--- /dev/null
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallBeanFactoryPostProcessor.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+
+package de.mgm.bup.ozg.antragsraum.common;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+
+@RequiredArgsConstructor
+public class CallBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
+    private final CallScope callScope;
+
+    @Override
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+        beanFactory.registerScope(CallScope.SCOPE_NAME, callScope);
+    }
+}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallContextAttachingInterceptor.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallContextAttachingInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9fc89d74cb56c13c27184121e4cb1df846537a8
--- /dev/null
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallContextAttachingInterceptor.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+
+package de.mgm.bup.ozg.antragsraum.common;
+
+import io.grpc.Metadata;
+import io.grpc.ServerCall;
+import io.grpc.ServerCallHandler;
+import io.grpc.ServerInterceptor;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor;
+
+@Log4j2
+@GrpcGlobalServerInterceptor
+@RequiredArgsConstructor
+public class CallContextAttachingInterceptor implements ServerInterceptor {
+    private final @NonNull ContextService contextService;
+
+    @Override
+    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
+        contextService.readMetadata(headers);
+
+        LOG.debug("Got metadata: {}", headers);
+
+        return next.startCall(call, headers);
+    }
+}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallScope.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallScope.java
new file mode 100644
index 0000000000000000000000000000000000000000..91d9b5d4ab2cdc346c6c206c5d67c1408f9903a5
--- /dev/null
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/CallScope.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+
+package de.mgm.bup.ozg.antragsraum.common;
+
+import lombok.NonNull;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.config.Scope;
+import org.springframework.core.NamedInheritableThreadLocal;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Log4j2
+public class CallScope implements Scope {
+    public static final String SCOPE_NAME = "call";
+
+    static final ThreadLocal<Map<String, Object>> scopedObjectsHolder = new NamedInheritableThreadLocal<>("Call Context");
+    static final ThreadLocal<Map<String, Runnable>> destructionCallbacksHolder = new NamedInheritableThreadLocal<>(
+            "Call Context Destruction Callbacks");
+
+    public void startScope() {
+        LOG.debug("START Call-Scope");
+        scopedObjectsHolder.set(new ConcurrentHashMap<>());
+        destructionCallbacksHolder.set(new ConcurrentHashMap<>());
+    }
+
+    public void endScope() {
+        scopedObjectsHolder.remove();
+        callAllDestructionCallbacks();
+        destructionCallbacksHolder.remove();
+        LOG.debug("END Call-Scope");
+    }
+
+    void callAllDestructionCallbacks() {
+        destructionCallbacksHolder.get().values().forEach(Runnable::run);
+    }
+
+    @Override
+    public @NonNull Object get(@NonNull String name, @NonNull ObjectFactory<?> objectFactory) {
+        if (!scopedObjectsHolder.get().containsKey(name)) {
+            scopedObjectsHolder.get().put(name, objectFactory.getObject());
+        }
+
+        return scopedObjectsHolder.get().get(name);
+    }
+
+    @Override
+    public Object remove(@NonNull String name) {
+        destructionCallbacksHolder.get().remove(name);
+        return scopedObjectsHolder.get().remove(name);
+    }
+
+    @Override
+    public void registerDestructionCallback(@NonNull String name, @NonNull Runnable callback) {
+        destructionCallbacksHolder.get().put(name, callback);
+
+    }
+
+    @Override
+    public Object resolveContextualObject(@NonNull String key) {
+        return scopedObjectsHolder.get().get(key);
+    }
+
+    @Override
+    public String getConversationId() {
+        return Thread.currentThread().getName();
+    }
+}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/ContextService.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/ContextService.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8859a7b9bb11e5d00617a69ce4a415b65a8e9a7
--- /dev/null
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/ContextService.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+
+package de.mgm.bup.ozg.antragsraum.common;
+
+import io.grpc.Metadata;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+import java.util.Optional;
+
+@Log4j2
+@Service
+@RequiredArgsConstructor
+public class ContextService {
+    public static final String KEY_CLIENT_NAME = "CLIENT_NAME-bin";
+    public static final String KEY_REQUEST_ID = "REQUEST_ID-bin";
+    public static final String KEY_AUTHENTICATION_ID = "AUTHENTICATION-bin";
+    RequestAttributes requestAttributes;
+
+    void readMetadata(Metadata headers) {
+        setToken(headers);
+        var requestAttributesBuilder = RequestAttributes.builder();
+
+        getRequestId(headers).ifPresent(id -> requestAttributesBuilder.requestId(new String(id)));
+        getClientName(headers).ifPresent(name -> requestAttributesBuilder.clientName(new String(name)));
+
+        requestAttributes = requestAttributesBuilder.build();
+    }
+
+    void setToken(Metadata headers) {
+        var token = headers.get(ContextService.createKeyOf(ContextService.KEY_AUTHENTICATION_ID));
+        if (Objects.nonNull(token)) {
+            SecurityContextHolder.getContext().setAuthentication(new BearerTokenAuthenticationToken(new String(token)));
+        }
+    }
+
+    Optional<byte[]> getRequestId(Metadata headers) {
+        return Optional.ofNullable(headers.get(ContextService.createKeyOf(ContextService.KEY_REQUEST_ID)));
+    }
+
+    Optional<byte[]> getClientName(Metadata headers) {
+        return Optional.ofNullable(headers.get(ContextService.createKeyOf(ContextService.KEY_CLIENT_NAME)));
+    }
+
+    static Metadata.Key<byte[]> createKeyOf(String key) {
+        return Metadata.Key.of(key, Metadata.BINARY_BYTE_MARSHALLER);
+    }
+}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/RequestAttributes.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/RequestAttributes.java
new file mode 100644
index 0000000000000000000000000000000000000000..4bd14b59cd31fdfd8cdce0fca3c4bfd3027f9d23
--- /dev/null
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/common/RequestAttributes.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+
+package de.mgm.bup.ozg.antragsraum.common;
+
+import lombok.*;
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+
+@Component
+@Scope(scopeName = "call", proxyMode = ScopedProxyMode.TARGET_CLASS)
+@Getter
+@Builder
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@NoArgsConstructor
+public class RequestAttributes {
+    @Builder.Default
+    private String requestId = UUID.randomUUID().toString();
+    private String clientName;
+}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/infomanager/InfoManagerProperties.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/infomanager/InfoManagerProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..25c8828c5e781cc313a5b080d076abe98c4d871a
--- /dev/null
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/infomanager/InfoManagerProperties.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+
+package de.mgm.bup.ozg.antragsraum.infomanager;
+
+import lombok.Getter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+@Getter
+@Configuration
+@ConfigurationProperties(prefix = InfoManagerProperties.PREFIX)
+public class InfoManagerProperties {
+    static final String PREFIX = "ozgcloud.infomanager";
+    private List<String> allowedClientNames = List.of("Antragsraum");
+    private String postfachIdKeyName = "legacyPostkorbHandle";
+}
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcService.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcService.java
index cf28c4b5583f565e44c450700ef74c2980f6e684..660949aa73e708197c2b5eff63e4d6a41c9f8db0 100644
--- a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcService.java
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcService.java
@@ -24,43 +24,94 @@
 
 package de.mgm.bup.ozg.antragsraum.infomanager;
 
+import de.mgm.bup.ozg.antragsraum.common.RequestAttributes;
 import io.grpc.stub.StreamObserver;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
 import net.devh.boot.grpc.server.service.GrpcService;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
+import org.springframework.util.ObjectUtils;
 
 import java.util.ArrayList;
 
+@Log4j2
 @GrpcService
 @RequiredArgsConstructor
 public class InformationGrpcService extends InformationServiceGrpc.InformationServiceImplBase {
     private final InformationService service;
+    private final RequestAttributes requestAttributes;
+    private final InfoManagerProperties infoManagerProperties;
 
     @Override
     public void getInformation(GrpcInformationRequest request, StreamObserver<GrpcInformationResponse> responseStreamObserver) {
-        var nachrichten = new ArrayList<GrpcNachricht>();
-        var information = service.getInformationOfPostfach(request.getPostfachId());
-
-        information.forEach(info -> nachrichten.add(GrpcNachricht.newBuilder()
-                .setNachrichtenListUrl(info.getNachrichtenListUrl())
-                .setPostfachId(info.getPostfachId())
-                .setNachrichtId(info.getNachrichtId())
-                .setVorgangId(info.getVorgangId())
-                .build()
-        ));
-
-        responseStreamObserver.onNext(GrpcInformationResponse.newBuilder().addAllNachrichten(nachrichten).build());
-        responseStreamObserver.onCompleted();
+        if (checkForAccessToPostfach(request.getPostfachId(), responseStreamObserver)) {
+            var nachrichten = new ArrayList<GrpcNachricht>();
+            var information = service.getInformationOfPostfach(request.getPostfachId());
+
+            information.forEach(info -> nachrichten.add(GrpcNachricht.newBuilder()
+                    .setNachrichtenListUrl(info.getNachrichtenListUrl())
+                    .setPostfachId(info.getPostfachId())
+                    .setNachrichtId(info.getNachrichtId())
+                    .setVorgangId(info.getVorgangId())
+                    .build()
+            ));
+
+            responseStreamObserver.onNext(GrpcInformationResponse.newBuilder().addAllNachrichten(nachrichten).build());
+            responseStreamObserver.onCompleted();
+        }
+    }
+
+    boolean checkForAccessToPostfach(String requestedPostfachId, StreamObserver<GrpcInformationResponse> responseStreamObserver) {
+        var auth = SecurityContextHolder.getContext().getAuthentication();
+        boolean success = false;
+        try {
+            if (auth instanceof JwtAuthenticationToken jwtAuthenticationToken) {
+                var userPostfachId = jwtAuthenticationToken.getToken().getClaims().get(infoManagerProperties.getPostfachIdKeyName());
+
+                if (ObjectUtils.isEmpty(userPostfachId)) {
+                    var msg = "Invalid postfach_id_key_name [%s] configured. Unable get Postfach id from token".formatted(infoManagerProperties.getPostfachIdKeyName());
+                    LOG.error(msg);
+                    throw new IllegalStateException(msg);
+                }
+
+                if (!userPostfachId.equals(requestedPostfachId)) {
+                    LOG.error("User " + jwtAuthenticationToken.getToken().getClaims().get("sid") + " is not allowed to access events of postfach id " + requestedPostfachId);
+                    throw new SecurityException("User not allowed");
+                }
+
+                success = true;
+            } else {
+                var msg = "Invalid auth configuration. Expected JwtAuthenticationToken class but got %s".formatted(auth.getClass().getName());
+                LOG.error(msg);
+                throw new IllegalStateException(msg);
+            }
+        } catch (SecurityException | IllegalStateException e) {
+            responseStreamObserver.onError(e);
+        }
+
+        return success;
     }
 
     @Override
     public void getServiceUrlOfNachricht(GrpcServiceUrlRequest request, StreamObserver<GrpcServiceUrlResponse> responseStreamObserver) {
-        var urlOptional = service.getUrlOfNachricht(request.getNachrichtId());
+        if (canAccessByName()) {
+
+            var urlOptional = service.getUrlOfNachricht(request.getNachrichtId());
 
-        var responseBuilder = GrpcServiceUrlResponse.newBuilder();
+            var responseBuilder = GrpcServiceUrlResponse.newBuilder();
 
-        urlOptional.ifPresent(responseBuilder::setUrl);
+            urlOptional.ifPresent(responseBuilder::setUrl);
+
+            responseStreamObserver.onNext(responseBuilder.build());
+            responseStreamObserver.onCompleted();
+        } else {
+            LOG.error("Client " + requestAttributes.getClientName() + " not allowed");
+            responseStreamObserver.onError(new SecurityException("Client not allowed"));
+        }
+    }
 
-        responseStreamObserver.onNext(responseBuilder.build());
-        responseStreamObserver.onCompleted();
+    boolean canAccessByName() {
+        return infoManagerProperties.getAllowedClientNames().contains(requestAttributes.getClientName());
     }
 }
diff --git a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtenService.java b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtenService.java
index 188b15c37ab41a40ea63aa2fc0b43641c5fbba90..e9e0f5bc2084165c1b50e0f95e9cc31cecfa37dd 100644
--- a/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtenService.java
+++ b/ozg-info-manager-server/src/main/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtenService.java
@@ -25,14 +25,13 @@
 package de.mgm.bup.ozg.antragsraum.nachrichteventmanager;
 
 import de.mgm.bup.ozg.antragsraum.NachrichtEvent;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
 @Service
+@RequiredArgsConstructor
 class NachrichtenService {
-
-    @Autowired
-    NachrichtenRepository repository;
+    private final NachrichtenRepository repository;
 
     void save(NachrichtEvent nachrichtEvent) {
         repository.save(nachrichtEvent);
diff --git a/ozg-info-manager-server/src/main/resources/application.properties b/ozg-info-manager-server/src/main/resources/application.properties
index a95f855ce39e1b36086175b94cb10cb1f8453f7a..a187ef199f78e41073268c12bc220f0fa6a08126 100644
--- a/ozg-info-manager-server/src/main/resources/application.properties
+++ b/ozg-info-manager-server/src/main/resources/application.properties
@@ -25,4 +25,6 @@ management.endpoint.info.enabled=true
 management.endpoint.health.enabled=true
 management.endpoints.web.exposure.include=health,info
 management.endpoint.health.show-components=always
+spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8081/realms/antragsraum
+ozgcloud.infomanager.allowed-client-names=Antragsraum
 
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/GrpcTestConfig.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/GrpcTestConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..c47e412f6c3254f3707c0e6ead51710be0693915
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/GrpcTestConfig.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+
+package de.mgm.bup.ozg.antragsraum;
+
+import net.devh.boot.grpc.client.autoconfigure.*;
+import net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration;
+import net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ImportAutoConfiguration({
+        GrpcCommonCodecAutoConfiguration.class,
+        GrpcCommonTraceAutoConfiguration.class,
+
+        GrpcClientAutoConfiguration.class,
+        GrpcClientHealthAutoConfiguration.class,
+        GrpcClientMetricAutoConfiguration.class,
+        GrpcClientSecurityAutoConfiguration.class,
+        GrpcClientTraceAutoConfiguration.class,
+        GrpcDiscoveryClientAutoConfiguration.class,
+})
+class GrpcTestConfig {
+}
+
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplicationITCase.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplicationITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..aead5cc7a38dbf35ea701d0681d74fd8916caec4
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplicationITCase.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+@SpringBootTest
+@SpringJUnitConfig(classes = {GrpcTestConfig.class})
+class InfoManagerApplicationITCase {
+    @Test
+    void shouldLoadContext() {
+    }
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplicationTest.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplicationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9d45c0e398f3ea330246072333708a90f67a3a7
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/InfoManagerApplicationTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum;
+
+import de.mgm.bup.ozg.antragsraum.common.CallScope;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Spy;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.assertj.core.api.Assertions.*;
+
+@ExtendWith(MockitoExtension.class)
+class InfoManagerApplicationTest {
+    @Spy
+    @InjectMocks
+    private InfoManagerApplication application;
+    @Test
+    void shouldCreateCallScope() {
+        var callScope = application.callScope();
+
+        assertThat(callScope).isNotNull();
+    }
+
+    @Test
+    void shouldCreateBeanFactoryPostProcessor() {
+        var beanProcessor = InfoManagerApplication.beanFactoryPostProcessor(new CallScope());
+
+        assertThat(beanProcessor).isNotNull();
+    }
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/KeycloakExtension.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/KeycloakExtension.java
new file mode 100644
index 0000000000000000000000000000000000000000..caf8f11275607d98d387b5d47b802e87070ae360
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/KeycloakExtension.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum;
+
+import dasniko.testcontainers.keycloak.KeycloakContainer;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+public class KeycloakExtension implements BeforeAllCallback, AfterAllCallback {
+    public static final String REALMS_ANTRAGSRAUM = "/realms/antragsraum";
+
+    @Override
+    public void afterAll(ExtensionContext context) {
+        // do nothing, Testcontainers handles container shutdown
+    }
+
+    @Override
+    public void beforeAll(ExtensionContext context) {
+        KeycloakContainer keycloak = new KeycloakContainer().withRealmImportFile("realm-export.json");
+        keycloak.start();
+
+        String url = keycloak.getAuthServerUrl() + REALMS_ANTRAGSRAUM;
+        System.setProperty("spring.security.oauth2.resourceserver.jwt.issuer-uri", url);
+    }
+}
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/ModularityTests.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/ModularityTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfcf9f01f642bf6422b1de0a42f76280c4095bc3
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/ModularityTests.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.modulith.core.ApplicationModules;
+import org.springframework.modulith.docs.Documenter;
+
+class ModularityTests {
+    @Test
+    void verifyModularity() {
+        ApplicationModules.of(InfoManagerApplication.class);
+    }
+
+    @Test
+    void writeDocumentationSnippets() {
+
+        var modules = ApplicationModules.of(InfoManagerApplication.class).verify();
+
+        new Documenter(modules)
+                .writeModulesAsPlantUml()
+                .writeIndividualModulesAsPlantUml();
+    }
+}
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/NachrichtEventTestFactory.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/NachrichtEventTestFactory.java
index 4f8a927ba99cc6367a8285eadd0842c3310b905c..3c2df4f8e3ed7334201a467c4fbf7dc52e18dcd7 100644
--- a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/NachrichtEventTestFactory.java
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/NachrichtEventTestFactory.java
@@ -27,7 +27,8 @@ import java.util.UUID;
 public class NachrichtEventTestFactory {
     public final static String VORGANG_ID = UUID.randomUUID().toString();
     public final static String NACHRICHT_ID = UUID.randomUUID().toString();
-    public final static String POSTFACH_ID = UUID.randomUUID().toString();
+    public final static String POSTFACH_ID = "abc123-jsdkfjks-sdfhks-2636hdh";
+    public final static String EMPTY_POSTFACH_ID = "73228744-a28a-4485-845b-d8cc02422760";
     public final static String URL = "http://localhost";
 
     public static NachrichtEvent create() {
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/TokenSupplier.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/TokenSupplier.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ea7c658015382e0e0bac4f05e17c6714a874b46
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/TokenSupplier.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum;
+
+import lombok.extern.log4j.Log4j2;
+import org.apache.http.client.utils.URIBuilder;
+import org.springframework.boot.json.JacksonJsonParser;
+import org.springframework.http.MediaType;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+
+@Log4j2
+public class TokenSupplier {
+    public String get(String issuerUrl, String userName) {
+        var token = getToken(issuerUrl, userName);
+        LOG.info("TokenSupplier token: " + token);
+        return token;
+    }
+
+    String getToken(String issuerUrl, String userName) {
+        try {
+            URI authorizationURI = new URIBuilder(issuerUrl + "/protocol/openid-connect/token").build();
+            WebClient webclient = WebClient.builder().build();
+            MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+            formData.put("grant_type", Collections.singletonList("password"));
+            formData.put("client_id", Collections.singletonList("antragsraum-api"));
+            formData.put("username", Collections.singletonList(userName));
+            formData.put("password", Collections.singletonList("s3cr3t"));
+
+            String result = webclient.post()
+                    .uri(authorizationURI)
+                    .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+                    .body(BodyInserters.fromFormData(formData))
+                    .retrieve()
+                    .bodyToMono(String.class)
+                    .block();
+
+            JacksonJsonParser jsonParser = new JacksonJsonParser();
+
+            return jsonParser.parseMap(result).get("access_token").toString();
+        } catch (URISyntaxException e) {
+            LOG.error("Error loading token from keycloak.", e);
+        }
+
+        return null;
+    }
+}
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallBeanFactoryPostProcessorTest.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallBeanFactoryPostProcessorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef9bbadeb57bd6b2dcb88a6bd498738d38a42548
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallBeanFactoryPostProcessorTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.common;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Spy;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class CallBeanFactoryPostProcessorTest {
+    @Spy
+    private ConfigurableListableBeanFactory configurableListableBeanFactory;
+
+    @Test
+    void shouldRegisterPostProcessBeanFactory() {
+        var processor = new CallBeanFactoryPostProcessor(new CallScope());
+
+        processor.postProcessBeanFactory(configurableListableBeanFactory);
+
+        verify(configurableListableBeanFactory).registerScope(eq(CallScope.SCOPE_NAME), any(CallScope.class));
+    }
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallContextAttachingInterceptorTest.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallContextAttachingInterceptorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b175524ee0ce188b97996f3db99728e927576d5
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallContextAttachingInterceptorTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.common;
+
+import io.grpc.Metadata;
+import io.grpc.ServerCallHandler;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class CallContextAttachingInterceptorTest {
+    @InjectMocks
+    private CallContextAttachingInterceptor interceptor;
+    @Mock
+    private ContextService contextService;
+
+    @Mock
+    ServerCallHandler<?, ?> handler;
+
+    @Test
+    void shouldInterceptCall() {
+        interceptor.interceptCall(null, MetadataTestFactory.create(), handler);
+
+        verify(handler).startCall(any(), any());
+    }
+
+    @Test
+    void shouldFillContextService() {
+        interceptor.interceptCall(null, MetadataTestFactory.create(), handler);
+
+        verify(contextService).readMetadata(any(Metadata.class));
+    }
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallScopeTest.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallScopeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..48a6a60ab928aa7dfd379305999b199f88c5755d
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/CallScopeTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.common;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.beans.factory.ObjectFactory;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class CallScopeTest {
+    public static final String TEST = "Test";
+    public static final String TEST_NEW = "TestNew";
+    @Spy
+    @InjectMocks
+    private CallScope callScope;
+
+    @Nested
+    class TestFreshCallScope {
+
+        @Test
+        void shouldStartScope() {
+            callScope.startScope();
+
+            assertThat(CallScope.scopedObjectsHolder).isNotNull();
+            assertThat(CallScope.destructionCallbacksHolder).isNotNull();
+        }
+
+        @Test
+        void shouldEndScope() {
+            callScope.endScope();
+
+            verify(callScope).callAllDestructionCallbacks();
+        }
+
+        @Test
+        void getConversationId() {
+            var id = callScope.getConversationId();
+
+            assertThat(id).isEqualTo(Thread.currentThread().getName());
+        }
+    }
+
+    @Nested
+    class TestCallScope {
+        @Mock
+        private ObjectFactory<Object> objectFactory;
+
+        @BeforeEach
+        void setupEmptyCallScope() {
+            callScope.startScope();
+            CallScope.scopedObjectsHolder.get().put(TEST, objectFactory);
+        }
+
+        @Test
+        void shouldGetAdded() {
+            var newObjectFactory = mock(ObjectFactory.class);
+            var object = new Object();
+            when(newObjectFactory.getObject()).thenReturn(object);
+
+            var recievedObject = callScope.get(TEST_NEW, newObjectFactory);
+
+            assertThat(recievedObject).isNotNull().isEqualTo(object);
+        }
+
+        @Test
+        void shouldGetNullName() {
+            var newObjectFactory = mock(ObjectFactory.class);
+
+            assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> callScope.get(null, newObjectFactory));
+        }
+
+        @Test
+        void shouldGetNullFactory() {
+            assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> callScope.get(TEST, null));
+        }
+
+        @Test
+        void shouldGetExisting() {
+            var recievedObject = callScope.get(TEST, mock(ObjectFactory.class));
+
+            assertThat(recievedObject).isNotNull().isEqualTo(objectFactory);
+        }
+
+        @Test
+        void remove() {
+            var res = callScope.remove(TEST);
+
+            assertThat(res).isNotNull().isEqualTo(objectFactory);
+        }
+
+        @Test
+        void removeNull() {
+            assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> callScope.remove(null));
+        }
+
+        @Test
+        void registerDestructionCallback() {
+            var callBack = mock(Runnable.class);
+
+            callScope.registerDestructionCallback(TEST, callBack);
+
+            assertThat(CallScope.destructionCallbacksHolder.get()).containsEntry(TEST, callBack);
+        }
+
+        @Test
+        void registerDestructionCallbackNullName() {
+            var callBack = mock(Runnable.class);
+            assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> callScope.registerDestructionCallback(null, callBack));
+        }
+
+        @Test
+        void registerDestructionCallbackNullCallback() {
+            assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> callScope.registerDestructionCallback(TEST, null));
+        }
+
+        @Test
+        void resolveContextualObject() {
+            var contextualObject = callScope.resolveContextualObject(TEST);
+
+            assertThat(contextualObject).isEqualTo(objectFactory);
+        }
+
+        @Test
+        void resolveContextualObjectNullName() {
+            assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> callScope.resolveContextualObject(null));
+        }
+    }
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/ContextServiceTest.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/ContextServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..280ca8aa408bd96bfb4b529599f72dfe9472de42
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/ContextServiceTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.common;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Spy;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import static de.mgm.bup.ozg.antragsraum.common.MetadataTestFactory.*;
+import static org.assertj.core.api.Assertions.*;
+
+@ExtendWith(MockitoExtension.class)
+class ContextServiceTest {
+    @Spy
+    @InjectMocks
+    private ContextService contextService;
+
+    @Nested
+    class TestCallContext {
+
+        @BeforeEach
+        void init() {
+            contextService.readMetadata(MetadataTestFactory.create());
+        }
+
+        @Test
+        void shouldGetRequestId() {
+            var requestId = contextService.getRequestId(MetadataTestFactory.create());
+
+            assertThat(requestId).isPresent().hasValue(REQUEST_ID_BYTES);
+        }
+
+        @Test
+        void shouldGetClientName() {
+            var clientName = contextService.getClientName(MetadataTestFactory.create());
+
+            assertThat(clientName).isPresent().hasValue(CLIENT_NAME_BYTES);
+        }
+
+        @Test
+        void shouldSetAuthToken() {
+            contextService.setToken(MetadataTestFactory.create());
+
+            var auth = SecurityContextHolder.getContext().getAuthentication();
+
+            assertThat(auth).isNotNull();
+        }
+
+        @Test
+        void shouldReadRequestAttributesRequestId() {
+            assertThat(contextService.requestAttributes.getRequestId()).isEqualTo(new String(REQUEST_ID_BYTES));
+        }
+
+        @Test
+        void shouldReadRequestAttributesClientName() {
+            assertThat(contextService.requestAttributes.getClientName()).isEqualTo(new String(CLIENT_NAME_BYTES));
+        }
+
+        @Test
+        void shouldReadRequestAttributesAuth() {
+            var auth = SecurityContextHolder.getContext().getAuthentication();
+            assertThat(auth).isNotNull();
+        }
+    }
+
+    @Nested
+    class TestEmptyCallContext {
+        @BeforeEach
+        void init() {
+            contextService.readMetadata(MetadataTestFactory.createEmpty());
+        }
+
+        @Test
+        void shouldReadRequestAttributesRequestId() {
+            assertThat(contextService.requestAttributes.getRequestId()).isNotEmpty();
+        }
+
+        @Test
+        void shouldReadRequestAttributesClientName() {
+            assertThat(contextService.requestAttributes.getClientName()).isNull();
+        }
+
+        @Test
+        void shouldReadRequestAttributesAuth() {
+            var auth = SecurityContextHolder.getContext().getAuthentication();
+            assertThat(auth).isNull();
+        }
+    }
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/MetadataTestFactory.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/MetadataTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..46cf3f951e596af3c60cb79d825d66ba77bd4b33
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/common/MetadataTestFactory.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.common;
+
+import io.grpc.Metadata;
+import org.springframework.security.oauth2.jwt.Jwt;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.UUID;
+
+import static de.mgm.bup.ozg.antragsraum.common.ContextService.*;
+
+public class MetadataTestFactory {
+    public static byte[] CLIENT_NAME_BYTES = "ANTRAGSRAUM".getBytes();
+    public static byte[] REQUEST_ID_BYTES = UUID.randomUUID().toString().getBytes();
+
+    public static Metadata create() {
+        var metadata = new Metadata();
+
+        metadata.put(createKeyOf(KEY_CLIENT_NAME), CLIENT_NAME_BYTES);
+        metadata.put(createKeyOf(KEY_REQUEST_ID), REQUEST_ID_BYTES);
+        metadata.put(createKeyOf(KEY_AUTHENTICATION_ID), createToken().getTokenValue().getBytes());
+
+        return metadata;
+    }
+
+    public static Metadata createEmpty() {
+        return new Metadata();
+    }
+
+    public static Metadata.Key<byte[]> createKeyOf(String key) {
+        return Metadata.Key.of(key, Metadata.BINARY_BYTE_MARSHALLER);
+    }
+
+    public static Jwt createToken() {
+        String jwtTokenPayload = """
+                  {
+                      "exp": 1699951718,
+                          "iat": 1699951418,
+                          "jti": "3ebe34c0-875b-4253-8428-a1736546b3d0",
+                          "iss": "http://localhost:32804/realms/antragsraum",
+                          "aud": "account",
+                          "sub": "80b69dc1-7d37-43df-9efe-64584f5d25c8",
+                          "typ": "Bearer",
+                          "azp": "antragsraum-api",
+                          "session_state": "35aeb2f0-9f88-46e6-befa-b49773afbf0b",
+                          "allowed-origins": [
+                      "http://localhost:8080",
+                              "/*",
+                              "https://localhost:8080"
+                ],
+                      "resource_access": {
+                      "account": {
+                          "roles": [
+                          "manage-account",
+                                  "manage-account-links",
+                                  "view-profile"
+                    ]
+                      }
+                  },
+                      "scope": "email profile",
+                          "sid": "35aeb2f0-9f88-46e6-befa-b49773afbf0b",
+                          "email_verified": false,
+                          "name": "Jane Doe",
+                          "preferred_username": "janedoe",
+                          "given_name": "Jane",
+                          "family_name": "Doe",
+                          "email": "jane.doe@ozg-cloud.com"
+                  }
+                  """;
+        return Jwt.withTokenValue(jwtTokenPayload)
+                .header("alg", "RS256")
+                .header("typ", "jwt")
+                .header("kid", "NZ4PVRP0uUtxqh7CNBsLUdHSd5rbpGbIG247kepoadc")
+                .claim("iss", "https://localhost/realms/antragsraum")
+                .claim("sub", "281c4558-550c-413b-9972-2d2e5bde6b9b")
+                .claim("iat", Instant.now())
+                .claim("exp", Instant.now().plus(1, ChronoUnit.DAYS))
+                .claim("preferred_username", "janedoe")
+                .build();
+    }
+}
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceNoEventsITCase.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceNoEventsITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..645de2f456ce248d636568b0620446713758da3e
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceNoEventsITCase.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.infomanager;
+
+
+import de.mgm.bup.ozg.antragsraum.KeycloakExtension;
+import de.mgm.bup.ozg.antragsraum.SecurityConfiguration;
+import net.devh.boot.grpc.client.inject.GrpcClient;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+import static de.mgm.bup.ozg.antragsraum.NachrichtEventTestFactory.*;
+import static org.assertj.core.api.Assertions.*;
+
+@SpringBootTest(properties = {
+        "grpc.server.inProcessName=test",
+        "grpc.server.port=-1",
+        "grpc.client.inProcess.address=in-process:test"
+})
+@SpringJUnitConfig(classes = {InformationGrpcTestConfiguration.class, UserWithOutEventsConfiguration.class, SecurityConfiguration.class})
+@ExtendWith(KeycloakExtension.class)
+@DirtiesContext
+class InformationGrpcServiceNoEventsITCase {
+    @GrpcClient("inProcess")
+    private InformationServiceGrpc.InformationServiceBlockingStub service;
+
+    @Nested
+    class TestNoInformationAvailable {
+
+        @Test
+        void responseShouldHaveEmptyList() {
+            var request = GrpcInformationRequest.newBuilder().setPostfachId(EMPTY_POSTFACH_ID).build();
+
+            var response = service.getInformation(request);
+
+            var values = response.getNachrichtenList();
+            assertThat(values).isEmpty();
+        }
+
+        @Test
+        void responseShouldHaveEmptyUrl() {
+            var request = GrpcServiceUrlRequest.newBuilder().setNachrichtId("nothing").build();
+
+            var response = service.getServiceUrlOfNachricht(request);
+
+            var values = response.getUrl();
+            assertThat(values).isEmpty();
+        }
+    }
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceTest.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceTest.java
index da326ea1d57eef5e5ee4e8576638c180a25e23cc..a9356cb794ca5b88f057b6b0b04f7af7377cc0fd 100644
--- a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceTest.java
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceTest.java
@@ -25,6 +25,7 @@ package de.mgm.bup.ozg.antragsraum.infomanager;
 
 import de.mgm.bup.ozg.antragsraum.NachrichtEvent;
 import de.mgm.bup.ozg.antragsraum.NachrichtEventTestFactory;
+import de.mgm.bup.ozg.antragsraum.common.RequestAttributes;
 import io.grpc.stub.StreamObserver;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
@@ -32,16 +33,24 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.*;
 import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
+import static de.mgm.bup.ozg.antragsraum.NachrichtEventTestFactory.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
 @ExtendWith(MockitoExtension.class)
 class InformationGrpcServiceTest {
 
+    public static final String CLIENT_NAME = "Antragsraum";
+    public static final String POSTFACH_ID = "legacyPostkorbHandle";
     @Spy
     @InjectMocks
     InformationGrpcService informationGrpcService;
@@ -58,6 +67,12 @@ class InformationGrpcServiceTest {
     @Captor
     ArgumentCaptor<GrpcInformationResponse> informationResponseArgumentCaptor;
 
+    @Mock
+    private RequestAttributes requestAttributes;
+
+    @Mock
+    private InfoManagerProperties infoManagerProperties;
+
     @Nested
     class TestInformationAvailable {
         final NachrichtEvent firstNachrichtEvent = NachrichtEventTestFactory.create();
@@ -66,6 +81,7 @@ class InformationGrpcServiceTest {
         void init() {
             var information = List.of(firstNachrichtEvent, NachrichtEventTestFactory.create());
             when(service.getInformationOfPostfach(anyString())).thenReturn(information);
+            when(infoManagerProperties.getPostfachIdKeyName()).thenReturn(POSTFACH_ID);
         }
 
         @Test
@@ -108,6 +124,8 @@ class InformationGrpcServiceTest {
     class TestServiceUrlAvailable {
         @BeforeEach
         void init() {
+            when(infoManagerProperties.getAllowedClientNames()).thenReturn(List.of(CLIENT_NAME));
+            when(requestAttributes.getClientName()).thenReturn(CLIENT_NAME);
             when(service.getUrlOfNachricht(anyString())).thenReturn(Optional.of(NachrichtEventTestFactory.URL));
         }
 
@@ -130,12 +148,37 @@ class InformationGrpcServiceTest {
         }
     }
 
+    @Nested
+    class TestServiceUrlAvailableSecurityError {
+        @BeforeEach
+        void init() {
+            when(infoManagerProperties.getAllowedClientNames()).thenReturn(List.of(CLIENT_NAME));
+            when(requestAttributes.getClientName()).thenReturn("OTHER");
+        }
+
+        @Test
+        void shouldCallOnError() {
+            informationGrpcService.getServiceUrlOfNachricht(
+                    GrpcServiceUrlRequest.newBuilder().setNachrichtId(NachrichtEventTestFactory.NACHRICHT_ID).build(), urlResponseObserver
+            );
+
+            verify(urlResponseObserver).onError(any(SecurityException.class));
+        }
+    }
+
     @Nested
     class TestNoInformationAvailable {
         @BeforeEach
         void init() {
             List<NachrichtEvent> information = List.of();
             when(service.getInformationOfPostfach(anyString())).thenReturn(information);
+            var jwtAuth = mock(JwtAuthenticationToken.class);
+            var jwt = mock(Jwt.class);
+            when(jwt.getClaims()).thenReturn(Map.of(POSTFACH_ID, NachrichtEventTestFactory.POSTFACH_ID));
+            when(jwtAuth.getToken()).thenReturn(jwt);
+            SecurityContextHolder.getContext().setAuthentication(jwtAuth);
+
+            when(infoManagerProperties.getPostfachIdKeyName()).thenReturn(POSTFACH_ID);
         }
 
         @Test
@@ -160,8 +203,86 @@ class InformationGrpcServiceTest {
         }
     }
 
+    @Nested
+    class TestAccessCheck {
+        @Mock
+        private JwtAuthenticationToken token;
+
+        @Mock
+        private Jwt jwt;
+
+        @Mock
+        StreamObserver<GrpcInformationResponse> responseStreamObserver;
+
+        @BeforeEach
+        void init() {
+            SecurityContextHolder.getContext().setAuthentication(token);
+            when(infoManagerProperties.getPostfachIdKeyName()).thenReturn(POSTFACH_ID);
+        }
+
+        @Test
+        void shouldAccessPostfach() {
+            Map<String, Object> claims = Map.of(POSTFACH_ID, NachrichtEventTestFactory.POSTFACH_ID);
+            when(jwt.getClaims()).thenReturn(claims);
+            when(token.getToken()).thenReturn(jwt);
+
+            var res = informationGrpcService.checkForAccessToPostfach(NachrichtEventTestFactory.POSTFACH_ID, responseStreamObserver);
+
+            assertThat(res).isTrue();
+        }
+
+        @Test
+        void shouldNotAccessPostfach() {
+            Map<String, Object> claims = Map.of(POSTFACH_ID, NachrichtEventTestFactory.POSTFACH_ID);
+            when(jwt.getClaims()).thenReturn(claims);
+            when(token.getToken()).thenReturn(jwt);
+
+            var res = informationGrpcService.checkForAccessToPostfach(EMPTY_POSTFACH_ID, responseStreamObserver);
+
+            assertThat(res).isFalse();
+        }
+
+        @Test
+        void shouldThrowSecurityException() {
+            Map<String, Object> claims = Map.of(POSTFACH_ID, NachrichtEventTestFactory.POSTFACH_ID);
+            when(jwt.getClaims()).thenReturn(claims);
+            when(token.getToken()).thenReturn(jwt);
+
+            informationGrpcService.checkForAccessToPostfach(EMPTY_POSTFACH_ID, responseStreamObserver);
+
+            verify(responseStreamObserver).onError(any(SecurityException.class));
+        }
+
+        @Test
+        void shouldThrowIllegalStateException() {
+            when(jwt.getClaims()).thenReturn(Map.of());
+            when(token.getToken()).thenReturn(jwt);
+
+            informationGrpcService.checkForAccessToPostfach(POSTFACH_ID, responseStreamObserver);
+
+            verify(responseStreamObserver).onError(any(IllegalStateException.class));
+        }
+    }
+
+    @Nested
+    class TestExceptionOnOtherPostfachId {
+        @Mock
+        StreamObserver<GrpcInformationResponse> responseStreamObserver;
+
+        @Test
+        void shouldThrowIllegalStateException() {
+            SecurityContextHolder.getContext().setAuthentication(mock(Authentication.class));
+
+            informationGrpcService.checkForAccessToPostfach(EMPTY_POSTFACH_ID, responseStreamObserver);
+
+            verify(responseStreamObserver).onError(any(IllegalStateException.class));
+        }
+    }
+
     @Test
     void shouldCallOnCompleteForGrpcInformationRequest() {
+        SecurityContextHolder.getContext().setAuthentication(mock(Authentication.class));
+
         informationGrpcService.getInformation(
                 GrpcInformationRequest.newBuilder().setPostfachId(NachrichtEventTestFactory.POSTFACH_ID).build(), informationResponseStreamObserver
         );
@@ -171,6 +292,8 @@ class InformationGrpcServiceTest {
 
     @Test
     void shouldCallOnCompleteForGrpcServiceUrlRequest() {
+        when(requestAttributes.getClientName()).thenReturn(CLIENT_NAME);
+
         informationGrpcService.getServiceUrlOfNachricht(
                 GrpcServiceUrlRequest.newBuilder().setNachrichtId(NachrichtEventTestFactory.NACHRICHT_ID).build(), urlResponseObserver
         );
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceITCase.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceWithEventsITCase.java
similarity index 76%
rename from ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceITCase.java
rename to ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceWithEventsITCase.java
index c82d9786ebe40101046536fee5500de4e9a3662f..84f457fdcbfed09c05ee414601e2cc465eb5eaff 100644
--- a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceITCase.java
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcServiceWithEventsITCase.java
@@ -23,14 +23,19 @@
 package de.mgm.bup.ozg.antragsraum.infomanager;
 
 
+import de.mgm.bup.ozg.antragsraum.KeycloakExtension;
 import de.mgm.bup.ozg.antragsraum.NachrichtEventTestFactory;
+import de.mgm.bup.ozg.antragsraum.SecurityConfiguration;
+import io.grpc.StatusRuntimeException;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
 
+import static de.mgm.bup.ozg.antragsraum.NachrichtEventTestFactory.*;
 import static org.assertj.core.api.Assertions.*;
 
 @SpringBootTest(properties = {
@@ -38,29 +43,29 @@ import static org.assertj.core.api.Assertions.*;
         "grpc.server.port=-1",
         "grpc.client.inProcess.address=in-process:test"
 })
-@SpringJUnitConfig(classes = {InformationGrpcTestConfiguration.class})
+@SpringJUnitConfig(classes = {InformationGrpcTestConfiguration.class, UserWithEventsConfiguration.class, SecurityConfiguration.class})
+@ExtendWith(KeycloakExtension.class)
 @DirtiesContext
-class InformationGrpcServiceITCase {
+class InformationGrpcServiceWithEventsITCase {
     @GrpcClient("inProcess")
     private InformationServiceGrpc.InformationServiceBlockingStub service;
 
     @Nested
     class TestInformationAvailable {
-
         @Test
         void shouldLoadInformation() {
-            var request = GrpcInformationRequest.newBuilder().setPostfachId(NachrichtEventTestFactory.POSTFACH_ID).build();
+            var request = GrpcInformationRequest.newBuilder().setPostfachId(POSTFACH_ID).build();
 
             var response = service.getInformation(request);
 
             var values = response.getNachrichtenList();
             assertThat(values).hasSize(1);
-            assertThat(values.get(0).getPostfachId()).isEqualTo(NachrichtEventTestFactory.POSTFACH_ID);
+            assertThat(values.get(0).getPostfachId()).isEqualTo(POSTFACH_ID);
         }
 
         @Test
         void shouldLoadUrl() {
-            var request = GrpcServiceUrlRequest.newBuilder().setNachrichtId(NachrichtEventTestFactory.NACHRICHT_ID).build();
+            var request = GrpcServiceUrlRequest.newBuilder().setNachrichtId(NACHRICHT_ID).build();
 
             var response = service.getServiceUrlOfNachricht(request);
 
@@ -69,26 +74,13 @@ class InformationGrpcServiceITCase {
     }
 
     @Nested
-    class TestNoInformationAvailable {
-
-        @Test
-        void responseShouldHaveEmptyList() {
-            var request = GrpcInformationRequest.newBuilder().setPostfachId("nothing").build();
-
-            var response = service.getInformation(request);
-
-            var values = response.getNachrichtenList();
-            assertThat(values).isEmpty();
-        }
+    class TestNoAccess {
 
         @Test
-        void responseShouldHaveEmptyUrl() {
-            var request = GrpcServiceUrlRequest.newBuilder().setNachrichtId("nothing").build();
-
-            var response = service.getServiceUrlOfNachricht(request);
+        void responseShouldThrowStatusRuntimeException() {
+            var request = GrpcInformationRequest.newBuilder().setPostfachId("not_the_postfach_id_of_the_user").build();
 
-            var values = response.getUrl();
-            assertThat(values).isEmpty();
+            assertThatExceptionOfType(StatusRuntimeException.class).isThrownBy(() -> service.getInformation(request));
         }
     }
 }
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcTestConfiguration.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcTestConfiguration.java
index 2ff3086f7deafc8378f0028a53887fad5ca64b8f..ed1252a7d63b3b72afae914e4acddf5da1e42965 100644
--- a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcTestConfiguration.java
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/InformationGrpcTestConfiguration.java
@@ -23,30 +23,47 @@
 package de.mgm.bup.ozg.antragsraum.infomanager;
 
 import de.mgm.bup.ozg.antragsraum.NachrichtEventTestFactory;
+import de.mgm.bup.ozg.antragsraum.common.RequestAttributes;
+import lombok.extern.log4j.Log4j2;
 import net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration;
+import net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration;
+import net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration;
+import net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration;
 import net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration;
 import net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration;
+import net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration;
 import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 import java.util.List;
 import java.util.Optional;
+import java.util.UUID;
 
 import static org.mockito.Mockito.*;
 
+@Log4j2
 @Configuration
 @ImportAutoConfiguration({
+        GrpcCommonCodecAutoConfiguration.class,
+        GrpcCommonTraceAutoConfiguration.class,
         GrpcServerAutoConfiguration.class,
         GrpcServerFactoryAutoConfiguration.class,
-        GrpcClientAutoConfiguration.class})
+        GrpcServerSecurityAutoConfiguration.class,
+        GrpcClientAutoConfiguration.class,
+        GrpcClientSecurityAutoConfiguration.class})
 public class InformationGrpcTestConfiguration {
+
+
     @Bean
     InformationService informationService() {
         var service = mock(InformationService.class);
         when(
                 service.getInformationOfPostfach(NachrichtEventTestFactory.POSTFACH_ID))
                 .thenReturn(List.of(NachrichtEventTestFactory.create()));
+        when(
+                service.getInformationOfPostfach(NachrichtEventTestFactory.EMPTY_POSTFACH_ID))
+                .thenReturn(List.of());
         when(
                 service.getUrlOfNachricht(NachrichtEventTestFactory.NACHRICHT_ID))
                 .thenReturn(Optional.of(NachrichtEventTestFactory.URL));
@@ -58,8 +75,19 @@ public class InformationGrpcTestConfiguration {
         return mock(InformationRepository.class);
     }
 
+    @Bean
+    RequestAttributes requestAttributes() {
+        return RequestAttributes.builder().clientName("Antragsraum").requestId(UUID.randomUUID().toString()).build();
+    }
+
+    @Bean
+    InfoManagerProperties infoManagerProperties() {
+        return new InfoManagerProperties();
+    }
+
     @Bean
     InformationGrpcService informationGrpcService() {
-        return new InformationGrpcService(informationService());
+        return new InformationGrpcService(informationService(), requestAttributes(), infoManagerProperties());
     }
+
 }
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/UserWithEventsConfiguration.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/UserWithEventsConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..de71ff15198dceb24039b914d37a4c694ca5e21d
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/UserWithEventsConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.infomanager;
+
+import de.mgm.bup.ozg.antragsraum.TokenSupplier;
+import io.grpc.CallCredentials;
+import net.devh.boot.grpc.client.security.CallCredentialsHelper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class UserWithEventsConfiguration {
+    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
+    private String issuerUrl;
+
+    @Bean
+    CallCredentials grpcCredentials() {
+        return CallCredentialsHelper.bearerAuth(new TokenSupplier().get(issuerUrl, "jane.doe@ozg-cloud.com"));
+    }
+}
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/UserWithOutEventsConfiguration.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/UserWithOutEventsConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..1afadcbc731fb98b04f94fb9aadfc27da549e585
--- /dev/null
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/infomanager/UserWithOutEventsConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023.
+ * Das Land Schleswig-Holstein vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.mgm.bup.ozg.antragsraum.infomanager;
+
+import de.mgm.bup.ozg.antragsraum.TokenSupplier;
+import io.grpc.CallCredentials;
+import net.devh.boot.grpc.client.security.CallCredentialsHelper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class UserWithOutEventsConfiguration {
+    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
+    private String issuerUrl;
+
+    @Bean
+    CallCredentials grpcCredentials() {
+        return CallCredentialsHelper.bearerAuth(new TokenSupplier().get(issuerUrl, "maxmustermann@ozg-cloud.com"));
+    }
+}
diff --git a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtEventGrpcServiceITCase.java b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtEventGrpcServiceITCase.java
index 1c734e1f73fab8748f8850d05f6f3265192b7cc6..57a9262ebfad7b8454875494ab6562a95d31673e 100644
--- a/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtEventGrpcServiceITCase.java
+++ b/ozg-info-manager-server/src/test/java/de/mgm/bup/ozg/antragsraum/nachrichteventmanager/NachrichtEventGrpcServiceITCase.java
@@ -22,8 +22,10 @@
  */
 package de.mgm.bup.ozg.antragsraum.nachrichteventmanager;
 
+import de.mgm.bup.ozg.antragsraum.KeycloakExtension;
 import de.mgm.bup.ozg.antragsraum.NachrichtEvent;
 import de.mgm.bup.ozg.antragsraum.NachrichtEventTestFactory;
+import de.mgm.bup.ozg.antragsraum.SecurityConfiguration;
 import de.mgm.bup.ozg.antragsraum.infomanager.GrpcFinishedNachrichtRequest;
 import de.mgm.bup.ozg.antragsraum.infomanager.GrpcNachricht;
 import de.mgm.bup.ozg.antragsraum.infomanager.GrpcNewNachrichtRequest;
@@ -31,6 +33,7 @@ import de.mgm.bup.ozg.antragsraum.infomanager.NachrichtServiceGrpc;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@@ -42,7 +45,8 @@ import static org.assertj.core.api.Assertions.*;
         "grpc.server.port=-1",
         "grpc.client.inProcess.address=in-process:test"
 })
-@SpringJUnitConfig(classes = {NachrichtEventGrpcTestConfiguration.class})
+@SpringJUnitConfig(classes = {NachrichtEventGrpcTestConfiguration.class, SecurityConfiguration.class})
+@ExtendWith(KeycloakExtension.class)
 @DirtiesContext
 class NachrichtEventGrpcServiceITCase {
 
diff --git a/ozg-info-manager-server/src/test/resources/application.properties b/ozg-info-manager-server/src/test/resources/application.properties
index 4e6ecb06ecdc90ac715ee82bf7910a1bdaaedda5..02912f8fc43e14e7cbadfde1212a8aea22d84d67 100644
--- a/ozg-info-manager-server/src/test/resources/application.properties
+++ b/ozg-info-manager-server/src/test/resources/application.properties
@@ -22,4 +22,5 @@
 spring.data.mongodb.database=InformationManager
 spring.data.mongodb.port=${mongodb.container.port}
 spring.data.mongodb.host=localhost
-spring.data.mongodb.auto-index-creation=true
\ No newline at end of file
+spring.data.mongodb.auto-index-creation=true
+logging.level.org.springframework.security=DEBUG
diff --git a/ozg-info-manager-server/src/test/resources/realm-export.json b/ozg-info-manager-server/src/test/resources/realm-export.json
new file mode 100644
index 0000000000000000000000000000000000000000..2b74987ddf6d4add48e52b736f63af40ef039472
--- /dev/null
+++ b/ozg-info-manager-server/src/test/resources/realm-export.json
@@ -0,0 +1,1845 @@
+{
+  "id": "antragsraum",
+  "realm": "antragsraum",
+  "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": "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,
+  "defaultRole": {
+    "id": "ae0de638-8b16-4d7f-9c1d-e1a55129f895",
+    "name": "default-roles-antragsraum",
+    "description": "${role_default-roles}",
+    "composite": true,
+    "clientRole": false,
+    "containerId": "antragsraum"
+  },
+  "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": [],
+  "scopeMappings": [
+    {
+      "clientScope": "offline_access",
+      "roles": [
+        "offline_access"
+      ]
+    }
+  ],
+  "clientScopeMappings": {
+    "account": [
+      {
+        "client": "account-console",
+        "roles": [
+          "manage-account"
+        ]
+      }
+    ]
+  },
+  "clients": [
+    {
+      "id": "f4acf69c-1490-444e-9b1a-dfa4016b54a1",
+      "clientId": "account",
+      "name": "${client_account}",
+      "rootUrl": "${authBaseUrl}",
+      "baseUrl": "/realms/antragsraum/account/",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "/realms/antragsraum/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",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "cbfe941f-fe9a-4b79-aeb6-043b7993ffcc",
+      "clientId": "account-console",
+      "name": "${client_account-console}",
+      "rootUrl": "${authBaseUrl}",
+      "baseUrl": "/realms/antragsraum/account/",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "/realms/antragsraum/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": "bfff2bda-a626-489f-8b07-9989582dd452",
+          "name": "audience resolve",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-audience-resolve-mapper",
+          "consentRequired": false,
+          "config": {}
+        }
+      ],
+      "defaultClientScopes": [
+        "web-origins",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "6c504e4d-4ad5-48ee-a47b-6c31d8d9f67e",
+      "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",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "c683c33f-a584-46b1-af9f-d401ba93af85",
+      "clientId": "antragsraum-api",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [],
+      "webOrigins": [],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": true,
+      "serviceAccountsEnabled": false,
+      "publicClient": true,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {
+        "backchannel.logout.session.required": "true",
+        "backchannel.logout.revoke.offline.tokens": "false"
+      },
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": true,
+      "nodeReRegistrationTimeout": -1,
+      "defaultClientScopes": [
+        "web-origins",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ],
+      "protocolMappers": [
+        {
+          "id": "c5237a00-d3ea-4e87-9caf-5146b02d1a15",
+          "name": "PostkorbHandle",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "postkorbhandle",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "legacyPostkorbHandle",
+            "jsonType.label": "String"
+          }
+        }
+      ]
+    },
+    {
+      "id": "d71dc523-1f66-4cce-a23f-83a13ba3744b",
+      "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",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "36b87703-dfab-4c8e-b2a6-2bd96c89c141",
+      "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",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "440114dd-9b2c-4c4b-b192-8dec233715db",
+      "clientId": "security-admin-console",
+      "name": "${client_security-admin-console}",
+      "rootUrl": "${authAdminUrl}",
+      "baseUrl": "/admin/antragsraum/console/",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "/admin/antragsraum/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": "20f83504-601b-43d8-8725-38af0d7471d8",
+          "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",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    }
+  ],
+  "clientScopes": [
+    {
+      "id": "b7ffedbd-ba94-4fd4-ba1e-0145252e10ef",
+      "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": "7f93ba40-1f5e-48ff-b332-3cfe659072cb",
+          "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": "014cf82a-ac04-4fff-880b-019a225d3bbd",
+          "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": "0c36e47f-4e3d-4cad-aa18-5521d3bbc7f2",
+      "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": "abf78f87-6282-4a04-9ea6-4270978c7507",
+          "name": "audience resolve",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-audience-resolve-mapper",
+          "consentRequired": false,
+          "config": {}
+        },
+        {
+          "id": "171f5552-b4dc-45c1-b166-5738b7bbb08d",
+          "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": "92c00b3e-ec76-4497-aa56-3df225e82e24",
+          "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": "b1856e10-88e1-4f14-b9f0-6673523f6e39",
+      "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": "d94d0d20-6329-47ce-a4d4-b0f80d702ab7",
+      "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": "9dc9f261-26ed-4dab-bdbb-735f7a50f90e",
+          "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": "b9e049bb-7cbf-483a-a55a-c777b7403229",
+      "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": "35bdeedc-92e7-484b-9282-70574247d263",
+          "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": "ab2aac65-a55e-406e-b42e-40d42e6c4388",
+          "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": "c8df543e-eb97-42e6-8aa2-63a8252afc9e",
+      "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": "b8714689-b19f-40da-b184-cc882028e8a4",
+          "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": "e00ad84f-2f3c-4f13-be8a-3931103042c6",
+          "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": "54a0ac8d-4b46-413a-8d63-1822b424e2f1",
+      "name": "role_list",
+      "description": "SAML role list",
+      "protocol": "saml",
+      "attributes": {
+        "consent.screen.text": "${samlRoleListScopeConsentText}",
+        "display.on.consent.screen": "true"
+      },
+      "protocolMappers": [
+        {
+          "id": "d52bd17c-98c1-4dcc-9e16-5736ddf6347e",
+          "name": "role list",
+          "protocol": "saml",
+          "protocolMapper": "saml-role-list-mapper",
+          "consentRequired": false,
+          "config": {
+            "single": "false",
+            "attribute.nameformat": "Basic",
+            "attribute.name": "Role"
+          }
+        }
+      ]
+    },
+    {
+      "id": "18f13b5b-b7b3-4daa-afc5-ec25d6395075",
+      "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": "9371941e-b465-4413-a742-1036fafb2485",
+          "name": "allowed web origins",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-allowed-origins-mapper",
+          "consentRequired": false,
+          "config": {}
+        }
+      ]
+    },
+    {
+      "id": "09b1bbe9-5be6-477f-bcf5-bb661d7fe2a2",
+      "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": "58083ae1-5f33-4830-b975-e9f8da33920f",
+          "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": "String"
+          }
+        },
+        {
+          "id": "6a87985d-12e6-4ea6-9e40-14fe46ad4668",
+          "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": "d2393d95-5f3e-4f08-a876-d4971845e5ad",
+          "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": "7ce8e5e6-2f50-4b32-bd0a-7db014146baf",
+          "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": "e935814c-cf70-447d-85da-854bee14f403",
+          "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": "b2a73b0c-fd84-4894-85cf-05b9a8b9a329",
+          "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": "1f4d67e2-7083-4bb8-a666-361a6762161d",
+          "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": "5425cfb0-f259-43ba-bd31-8ab2b935e76c",
+          "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": "2fb74508-49c3-46dd-b620-61a4a461c7bc",
+          "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": "457d4a3f-f47e-4ed4-a7da-5950c822e434",
+          "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": "d2748ba4-aac9-486f-bbfc-ec398e273eec",
+          "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": "6e78fd09-6cac-4c66-84e4-299b58a1eefc",
+          "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": "e44bd071-8a85-49a3-8649-09985f7e8a61",
+          "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": "da7000a8-8a8b-4df7-a4b9-7f78f3d13406",
+          "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"
+          }
+        }
+      ]
+    }
+  ],
+  "defaultDefaultClientScopes": [
+    "profile",
+    "roles",
+    "web-origins",
+    "role_list",
+    "email"
+  ],
+  "defaultOptionalClientScopes": [
+    "offline_access",
+    "phone",
+    "microprofile-jwt",
+    "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": "80d5424d-79ab-44f4-818e-bc3b593641de",
+        "name": "Allowed Client Scopes",
+        "providerId": "allowed-client-templates",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "allow-default-scopes": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "b578a18a-e340-49a1-ace1-8092ed29f28c",
+        "name": "Allowed Protocol Mapper Types",
+        "providerId": "allowed-protocol-mappers",
+        "subType": "authenticated",
+        "subComponents": {},
+        "config": {
+          "allowed-protocol-mapper-types": [
+            "oidc-usermodel-attribute-mapper",
+            "oidc-full-name-mapper",
+            "oidc-sha256-pairwise-sub-mapper",
+            "saml-user-property-mapper",
+            "oidc-usermodel-property-mapper",
+            "saml-role-list-mapper",
+            "oidc-address-mapper",
+            "saml-user-attribute-mapper"
+          ]
+        }
+      },
+      {
+        "id": "9311fd52-8330-4065-b987-7a0ce8589d6a",
+        "name": "Full Scope Disabled",
+        "providerId": "scope",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "dcd5d2fe-da81-492e-ae6b-c026792e3154",
+        "name": "Consent Required",
+        "providerId": "consent-required",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "1ed1d774-d6d9-45ee-8a22-61125a01a479",
+        "name": "Allowed Client Scopes",
+        "providerId": "allowed-client-templates",
+        "subType": "authenticated",
+        "subComponents": {},
+        "config": {
+          "allow-default-scopes": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "717825ce-f267-4468-99cb-b09126b00570",
+        "name": "Trusted Hosts",
+        "providerId": "trusted-hosts",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "host-sending-registration-request-must-match": [
+            "true"
+          ],
+          "client-uris-must-match": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "6fb4db12-299d-4b7e-a100-8c318248d5e3",
+        "name": "Max Clients Limit",
+        "providerId": "max-clients",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "max-clients": [
+            "200"
+          ]
+        }
+      },
+      {
+        "id": "bf2d5422-07a0-4317-9e01-0d2a1be9b582",
+        "name": "Allowed Protocol Mapper Types",
+        "providerId": "allowed-protocol-mappers",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "allowed-protocol-mapper-types": [
+            "oidc-usermodel-property-mapper",
+            "saml-role-list-mapper",
+            "oidc-usermodel-attribute-mapper",
+            "saml-user-attribute-mapper",
+            "oidc-address-mapper",
+            "oidc-full-name-mapper",
+            "saml-user-property-mapper",
+            "oidc-sha256-pairwise-sub-mapper"
+          ]
+        }
+      }
+    ],
+    "org.keycloak.keys.KeyProvider": [
+      {
+        "id": "be18f5ef-4151-43e2-a607-1852f53acc76",
+        "name": "rsa-enc-generated",
+        "providerId": "rsa-enc-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ],
+          "algorithm": [
+            "RSA-OAEP"
+          ]
+        }
+      },
+      {
+        "id": "52fb51ee-b5aa-41c3-88d2-a0b11b6d4072",
+        "name": "rsa-generated",
+        "providerId": "rsa-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ]
+        }
+      },
+      {
+        "id": "9e839a58-a36e-420f-bebc-7466c4b578c9",
+        "name": "hmac-generated",
+        "providerId": "hmac-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ],
+          "algorithm": [
+            "HS256"
+          ]
+        }
+      },
+      {
+        "id": "93d3b307-cf5a-484c-a612-43cb4923501a",
+        "name": "aes-generated",
+        "providerId": "aes-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ]
+        }
+      }
+    ]
+  },
+  "internationalizationEnabled": false,
+  "supportedLocales": [],
+  "authenticationFlows": [
+    {
+      "id": "e285f1b9-bc15-4457-851d-abc9cb54953d",
+      "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": "65944e23-1f0d-47cf-b5d8-358463b0d382",
+      "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": "235ca7f6-27ad-4817-a686-cec020f7a091",
+      "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": "3d8dc16b-07e8-4535-ad1a-4ce79df1dd07",
+      "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": "3fa38b47-45a2-4eea-85a6-620b877db701",
+      "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": "126eee75-5f90-4a46-92c5-6fbb209d764a",
+      "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": "d9d8e610-41f8-45e3-a097-9961aa5e6d5f",
+      "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": "b01b7a9e-597b-4a12-8ccb-bfb707686dbf",
+      "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": "33a40ef5-e611-4182-b1a5-55aa930a839b",
+      "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": "5e148805-8a3f-4cbd-9a75-862da8e3fcdf",
+      "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": "38fd27d7-9914-47b3-aa11-1079cc059236",
+      "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": "58a3dcd5-56d1-4003-a1a1-dfafaf71ffa1",
+      "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": "4ed42c08-7dc6-47bf-8ac6-27e262973fdb",
+      "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": "b4ff61a6-56c7-4160-9047-b9abab13cfd9",
+      "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": "68b55fff-3f1e-4cce-a181-0b4fdc8ab1e5",
+      "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": "d3456a10-f6a1-4767-9385-baed652e82c4",
+      "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": "7b50c4ff-25c2-4ff9-8f4b-95c1144bb30a",
+      "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": "edc22a19-8b8d-4bca-bdfb-446df319e4b5",
+      "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": "b5f2931c-badf-4c09-96fb-7a0af5860b9f",
+      "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": "cc118d9d-31b8-4fa9-ba7c-2fc65936612a",
+      "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": "5219b9c4-0664-4b61-8fd4-c9ecc9954c4b",
+      "alias": "create unique user config",
+      "config": {
+        "require.password.update.after.registration": "false"
+      }
+    },
+    {
+      "id": "f48e0b44-86c9-4db0-87da-97433d873b80",
+      "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",
+    "oauth2DeviceCodeLifespan": "600",
+    "oauth2DevicePollingInterval": "5",
+    "parRequestUriLifespan": "60",
+    "cibaInterval": "5"
+  },
+  "keycloakVersion": "17.0.1",
+  "userManagedAccessAllowed": false,
+  "clientProfiles": {
+    "profiles": []
+  },
+  "clientPolicies": {
+    "policies": []
+  },
+  "users": [
+    {
+      "username": "janedoe",
+      "email": "jane.doe@ozg-cloud.com",
+      "firstName": "Jane",
+      "lastName": "Doe",
+      "enabled": true,
+      "credentials": [
+        {
+          "type": "password",
+          "value": "s3cr3t"
+        }
+      ],
+      "clientRoles": {
+        "account": [
+          "view-profile",
+          "manage-account"
+        ]
+      },
+      "attributes": {
+        "postkorbhandle": "abc123-jsdkfjks-sdfhks-2636hdh"
+      }
+    },
+    {
+      "username": "maxmustermann",
+      "email": "maxmustermann@ozg-cloud.com",
+      "firstName": "Max",
+      "lastName": "Mustermann",
+      "enabled": true,
+      "credentials": [
+        {
+          "type": "password",
+          "value": "s3cr3t"
+        }
+      ],
+      "clientRoles": {
+        "account": [
+          "view-profile",
+          "manage-account"
+        ]
+      },
+      "attributes": {
+        "postkorbhandle": "73228744-a28a-4485-845b-d8cc02422760"
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/ozg-info-manager-server/src/test/resources/user.json b/ozg-info-manager-server/src/test/resources/user.json
new file mode 100644
index 0000000000000000000000000000000000000000..01f2c01cb71623d8bd06009868590522888e964c
--- /dev/null
+++ b/ozg-info-manager-server/src/test/resources/user.json
@@ -0,0 +1,15 @@
+{
+  "iss": "https://localhost/realms/antragsraum",
+  "sub": "281c4558-550c-413b-9972-2d2e5bde6b9b",
+  "iat": 1695992542,
+  "exp": 1695992642,
+  "preferred_username": "janedoe",
+  "realm_access": {
+    "roles": [
+      "admin",
+      "ROLE_AUTHORIZED_PERSONNEL"
+    ]
+  },
+  "email": "jane.doe@ozg-cloud.com",
+  "scope": "openid email"
+}
\ No newline at end of file