diff --git a/.gitignore b/.gitignore
index 549e00a2a96fa9d7c5dbc9859664a78d980158c2..9ddbf280ee467a8bf60fb940d990634d1f0cbabf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,5 @@ build/
 
 ### VS Code ###
 .vscode/
+
+bin/**
diff --git a/Jenkinsfile b/Jenkinsfile
index a1c302e7602ab760c04249a980423e57391bc519..b11447de08cd0645e6f427af44fff71823e7e53d 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -106,32 +106,16 @@ pipeline {
             }
         }
 
-        stage ('Deploy SBOM to DependencyTrack') {
-            steps {
-                script {
-                    IMAGE_TAG = buildVersionName()
-
-                    configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
-                        withCredentials([string(credentialsId: 'dependency-track-api-key', variable: 'API_KEY')]) {
-
-                            catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
-                                sh "mvn  --no-transfer-progress -s $MAVEN_SETTINGS io.github.pmckeown:dependency-track-maven-plugin:upload-bom -Ddependency-track.apiKey=$API_KEY -Ddependency-track.projectVersion=${IMAGE_TAG} -Ddependency-track.dependencyTrackBaseUrl=https://dependency-track.ozg-sh.de"
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
         stage('Build and publish Docker image') {
             steps {
                 script {
+					IMAGE_TAG = buildVersionName()
                     FAILED_STAGE=env.STAGE_NAME
                 }
 
                 configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
                     withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
-                        sh 'mvn -s $MAVEN_SETTINGS spring-boot:build-image -DskipTests -Dmaven.wagon.http.retryHandler.count=3 $BUILD_PROFILE -Ddocker.publishRegistry.username=${USER} -Ddocker.publishRegistry.password=${PASSWORD} -Dbuild.number=$BUILD_NUMBER -DimageTag=$IMAGE_TAG -DpublishImage=true'
+                        sh 'mvn --no-transfer-progress -s $MAVEN_SETTINGS -Dspring-boot.build-image.publish=true -DskipTests -Dmaven.wagon.http.retryHandler.count=3 $BUILD_PROFILE -Ddocker.publishRegistry.username=${USER} -Ddocker.publishRegistry.password=${PASSWORD} -Dbuild.number=$BUILD_NUMBER spring-boot:build-image -Dspring-boot.build-image.imageName=docker.ozg-sh.de/administration:${IMAGE_TAG}'
                     }
                 }
             }
@@ -189,6 +173,23 @@ pipeline {
                 }
             }
         }
+        
+         stage ('Deploy SBOM to DependencyTrack') {
+            steps {
+                script {
+                    IMAGE_TAG_WO_COMMIT = buildVersionNameWithoutCommidId()
+
+                    configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
+                        withCredentials([string(credentialsId: 'dependency-track-api-key', variable: 'API_KEY')]) {
+
+                            catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
+                                sh "mvn  --no-transfer-progress -s $MAVEN_SETTINGS io.github.pmckeown:dependency-track-maven-plugin:upload-bom -Ddependency-track.apiKey=$API_KEY -Ddependency-track.projectVersion=${IMAGE_TAG_WO_COMMIT} -Ddependency-track.dependencyTrackBaseUrl=https://dependency-track.ozg-sh.de"
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     post {
@@ -241,6 +242,12 @@ String buildVersionName() {
     }
     return "${getPomVersion()}-${validateBranchName(env.BRANCH_NAME)}-${env.GIT_COMMIT.take(7)}".replaceAll("_", "-")
 }
+String buildVersionNameWithoutCommidId() {
+	if (isReleaseBranch()) {
+        return getPomVersion()
+    }
+    return "${getPomVersion()}-${validateBranchName(env.BRANCH_NAME)}".replaceAll("_", "-")
+}
 
 String getPomVersion() {
     def pom = readMavenPom file: 'pom.xml'
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..e3822b358f647ddbe6db35957b929ea29326cc0d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
+# Administration
+Die Anwendung Administration der OZG-Cloud stellt ein Web-UI zur Verwaltung der globalen Einstellungen der OZG-Cloud zur Verfügung. Über dieses erfolgt die fachliche Administration der OZG-Cloud durch den Mandanten oder eine durch den Mandanten beauftragte Institution.
+
+## Architektur
+ 
+### Client
+
+Der Client ist mit Angular entwickelt und bindet sich per REST-API an das Backend. Der Client wird im mono-repo der OZG-Cloud Clients mit entwickelt und ist ebenfalls auf [code.schleswig-holstein.de](https://code.schleswig-holstein.de/ozg-cloud/app/frontend-clients/-/tree/main/alfa-client/apps/admin?ref_type=heads) zu finden.
+
+### Backend
+
+Das Backend (in diesem Repo zu finden) ist eine spring-boot basierte Java Anwendung. 
+
+* spring data rest - das Rest Api für den Client wird per spring data rest aufgebaut.
+* spring cloud server - zur Übertragung der Konfigurationen an die einzelnen Dienste der OZG-Cloud (im Kontext der OZG-Cloud 'Manager' genannt) wird eine Schnittstelle nach dem spring cloud server Standard bereit gestellt.
+
+Die Konfiguration wird in einer MongoDB gespeichert.
+
+## Entwicklung
+
+Um ein neue Konfiguration einzubauen, müssen folgende Klassen angelegt werden:
+
+* Datenklassen - Die Klassen mit den eigentlichen Konfigurationsparameter. Die Klasse wird nach der Fachlichkeit benannt. Diese wird mit @TypeAlias annotiert.
+* Repository - MongoRepository mit @RepositoryRestResource annotation. Die findAll Methode muss überschrieben werden.
+* Klasse als Datentransferobjekt (DTO) - Format für die Spring Config Server Schnittstelle für einen Manager. Bennenung daher: FachlichkeitManagerSettingDto.java
+* Mapper - Mapped die Konfigurationsparamter in das Dto.
+* DtoService - Stellt die Settings für einen MAnager bereit. Wird mit @DtoService annotiert. Dadurch ist es eine Spring-Bean und wird automatisch aufgerufen, wenn eine Konfiguration für den jeweiligen Manager geladen wird. Benennung: FachlichkeitManagerSettingDtoService
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 0b91b4cf1a7876b05b238bace29be0cbb60b9f61..cbbc05e062d7cf73ca49e70fd4ec0be52c259574 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,9 +31,10 @@
 	<parent>
 		<groupId>de.ozgcloud.common</groupId>
 		<artifactId>ozgcloud-common-parent</artifactId>
-		<version>4.6.0</version>
-		<relativePath/>
+		<version>4.9.0-SNAPSHOT</version>
+		<relativePath />
 	</parent>
+
 	<groupId>de.ozgcloud</groupId>
 	<artifactId>administration</artifactId>
 	<version>1.3.0-SNAPSHOT</version>
@@ -46,12 +47,12 @@
 		<imageTag>build-latest</imageTag>
 		<publishImage>false</publishImage>
 		<build.number>SET_BY_JENKINS</build.number>
-		<spring-cloud-config-server.version>4.1.2</spring-cloud-config-server.version>
+
+		<spring-cloud-config-server.version>4.2.0</spring-cloud-config-server.version>
 		<testcontainers-keycloak.version>3.3.1</testcontainers-keycloak.version>
-		<keycloak-admin-client.version>24.0.5</keycloak-admin-client.version>
+
 		<mongock.version>5.4.0</mongock.version>
-		<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
-		<mapstruct-processor.version>${mapstruct.version}</mapstruct-processor.version>
+
 		<zufi-manager.version>1.6.0</zufi-manager.version>
 		<shedlock.version>5.16.0</shedlock.version>
 	</properties>
@@ -66,42 +67,46 @@
 
 		<!-- Spring -->
 		<dependency>
-			<groupId>net.devh</groupId>
-			<artifactId>grpc-client-spring-boot-starter</artifactId>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
 		<dependency>
-			<groupId>io.grpc</groupId>
-			<artifactId>grpc-inprocess</artifactId>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-rest</artifactId>
 		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-actuator</artifactId>
+			<artifactId>spring-boot-starter-hateoas</artifactId>
 		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-mongodb</artifactId>
+			<artifactId>spring-boot-starter-security</artifactId>
 		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-web</artifactId>
+			<artifactId>spring-boot-starter-data-mongodb</artifactId>
 		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-rest</artifactId>
+			<artifactId>spring-boot-starter-actuator</artifactId>
 		</dependency>
+
 		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-hateoas</artifactId>
+			<groupId>net.devh</groupId>
+			<artifactId>grpc-client-spring-boot-starter</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>io.grpc</groupId>
+			<artifactId>grpc-inprocess</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
 			<artifactId>spring-cloud-config-server</artifactId>
 			<version>${spring-cloud-config-server.version}</version>
 		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-security</artifactId>
-		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-validation</artifactId>
@@ -132,7 +137,6 @@
 		<dependency>
 			<groupId>org.keycloak</groupId>
 			<artifactId>keycloak-admin-client</artifactId>
-			<version>${keycloak-admin-client.version}</version>
 		</dependency>
 
 		<!-- tools -->
@@ -143,7 +147,7 @@
 		<dependency>
 			<groupId>org.mapstruct</groupId>
 			<artifactId>mapstruct-processor</artifactId>
-			<version>${mapstruct-processor.version}</version>
+			<version>${mapstruct.version}</version>
 		</dependency>
 
 		<!-- commons -->
@@ -266,6 +270,7 @@
 				</plugin>
 			</plugins>
 		</pluginManagement>
+
 		<plugins>
 			<plugin>
 				<groupId>org.sonarsource.scanner.maven</groupId>
@@ -282,60 +287,10 @@
 			<plugin>
 				<groupId>org.springframework.boot</groupId>
 				<artifactId>spring-boot-maven-plugin</artifactId>
-				<configuration>
-					<image>
-						<name>${imageName}:${imageTag}</name>
-						<publish>${publishImage}</publish>
-					</image>
-					<docker>
-						<publishRegistry>
-							<username>${docker.publishRegistry.username}</username>
-							<password>${docker.publishRegistry.password}</password>
-						</publishRegistry>
-					</docker>
-					<excludes>
-						<exclude>
-							<groupId>org.projectlombok</groupId>
-							<artifactId>lombok</artifactId>
-						</exclude>
-					</excludes>
-				</configuration>
-				<executions>
-					<execution>
-						<id>build-info</id>
-						<goals>
-							<goal>build-info</goal>
-						</goals>
-						<configuration>
-							<additionalProperties>
-								<number>${build.number}</number>
-							</additionalProperties>
-						</configuration>
-					</execution>
-				</executions>
 			</plugin>
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-compiler-plugin</artifactId>
-				<configuration>
-					<annotationProcessorPaths>
-						<path>
-							<groupId>org.mapstruct</groupId>
-							<artifactId>mapstruct-processor</artifactId>
-							<version>${mapstruct-processor.version}</version>
-						</path>
-						<path>
-							<groupId>org.projectlombok</groupId>
-							<artifactId>lombok</artifactId>
-							<version>${lombok.version}</version>
-						</path>
-						<path>
-							<groupId>org.projectlombok</groupId>
-							<artifactId>lombok-mapstruct-binding</artifactId>
-							<version>${lombok-mapstruct-binding.version}</version>
-						</path>
-					</annotationProcessorPaths>
-				</configuration>
 			</plugin>
 		</plugins>
 	</build>
diff --git a/src/main/java/de/ozgcloud/admin/AdministrationRepositoryRestConfigurer.java b/src/main/java/de/ozgcloud/admin/AdministrationRepositoryRestConfigurer.java
index 2ab9b687e22cad4e59a978b6558a6a366f60895a..31bcf3b864fd772838ebe1ef3555084c984af6b6 100644
--- a/src/main/java/de/ozgcloud/admin/AdministrationRepositoryRestConfigurer.java
+++ b/src/main/java/de/ozgcloud/admin/AdministrationRepositoryRestConfigurer.java
@@ -23,17 +23,20 @@
  */
 package de.ozgcloud.admin;
 
+import jakarta.validation.Validation;
+
 import org.springframework.context.annotation.Configuration;
-import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
+import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
 import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
-import org.springframework.hateoas.server.core.DefaultLinkRelationProvider;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
+
+import de.ozgcloud.admin.common.DelegatingValidatorAdapter;
 
 @Configuration
 public class AdministrationRepositoryRestConfigurer implements RepositoryRestConfigurer {
 
 	@Override
-	public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
-		config.setLinkRelationProvider(new DefaultLinkRelationProvider());
+	public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener listener) {
+		var validator = Validation.buildDefaultValidatorFactory().getValidator();
+		listener.addValidator("beforeCreate", new DelegatingValidatorAdapter(validator));
 	}
 }
diff --git a/src/main/java/de/ozgcloud/admin/OzgCloudRestLinksConfiguration.java b/src/main/java/de/ozgcloud/admin/OzgCloudRestLinksConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..5bf4c55db0af6b7785b80fac20e6c047a4f264c4
--- /dev/null
+++ b/src/main/java/de/ozgcloud/admin/OzgCloudRestLinksConfiguration.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin;
+
+import java.util.Optional;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.mapping.PersistentProperty;
+import org.springframework.data.mapping.context.PersistentEntities;
+import org.springframework.data.repository.support.Repositories;
+import org.springframework.data.rest.core.Path;
+import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
+import org.springframework.data.rest.core.mapping.PropertyAwareResourceMapping;
+import org.springframework.data.rest.core.mapping.RepositoryResourceMappings;
+import org.springframework.data.rest.core.mapping.ResourceDescription;
+import org.springframework.data.rest.core.mapping.ResourceMapping;
+import org.springframework.data.rest.core.mapping.ResourceMetadata;
+import org.springframework.data.rest.core.mapping.SearchResourceMappings;
+import org.springframework.data.rest.core.mapping.SupportedHttpMethods;
+import org.springframework.hateoas.LinkRelation;
+import org.springframework.security.authorization.AuthorizationDecision;
+import org.springframework.security.authorization.method.SecuredAuthorizationManager;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.util.SimpleMethodInvocation;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+
+@Configuration
+class OzgCloudRestLinksConfiguration {
+	@Primary
+	@Bean
+	RepositoryResourceMappings ozgCloudResourceMappings(Repositories repositories, PersistentEntities persistentEntities,
+			RepositoryRestConfiguration repositoryRestConfiguration) {
+		return new OzgCloudDelegatingRepositoryResourceMappings(repositories, persistentEntities, repositoryRestConfiguration);
+	}
+}
+
+@Log4j2
+class OzgCloudDelegatingRepositoryResourceMappings extends RepositoryResourceMappings {
+
+	private final Repositories repositories;
+
+	public OzgCloudDelegatingRepositoryResourceMappings(Repositories repositories, PersistentEntities entities,
+			RepositoryRestConfiguration configuration) {
+		super(repositories, entities, configuration);
+
+		this.repositories = repositories;
+	}
+
+	@Override
+	public ResourceMetadata getMetadataFor(Class<?> type) {
+		return new OzgCloudDelegatingResourceMetadata(super.getMetadataFor(type), repositories);
+	}
+
+	@RequiredArgsConstructor
+	static class OzgCloudDelegatingResourceMetadata implements ResourceMetadata {
+
+		private final ResourceMetadata metadata;
+		private final Repositories repositories;
+		private final SecuredAuthorizationManager authManager = new SecuredAuthorizationManager();
+
+		@Override
+		public LinkRelation getItemResourceRel() {
+			return metadata.getItemResourceRel();
+		}
+
+		@Override
+		public ResourceDescription getItemResourceDescription() {
+			return metadata.getItemResourceDescription();
+		}
+
+		@Override
+		public Optional<Class<?>> getExcerptProjection() {
+			return metadata.getExcerptProjection();
+		}
+
+		@Override
+		public boolean isExported() {
+			return isAccessPermitted(metadata.getDomainType()) && metadata.isExported();
+		}
+
+		boolean isAccessPermitted(Class<?> type) {
+			var repository = repositories.getRepositoryFor(type);
+			return repository.map(repo -> authManager.check(() -> SecurityContextHolder.getContext().getAuthentication(), getFindAllInvocation(repo)))
+					.map(AuthorizationDecision::isGranted)
+					.orElse(true);
+		}
+
+		MethodInvocation getFindAllInvocation(Object repository) {
+			try {
+				var method = repository.getClass().getMethod("findAll");
+				return new SimpleMethodInvocation(repository, method);
+			} catch (NoSuchMethodException | SecurityException e) {
+				LOG.error(e.getMessage(), e);
+				throw new TechnicalException("Error on extracting findAll Repository Method", e);
+			}
+		}
+
+		@Override
+		public LinkRelation getRel() {
+			return metadata.getRel();
+		}
+
+		@Override
+		public Path getPath() {
+			return metadata.getPath();
+		}
+
+		@Override
+		public boolean isPagingResource() {
+			return metadata.isPagingResource();
+		}
+
+		@Override
+		public ResourceDescription getDescription() {
+			return metadata.getDescription();
+		}
+
+		@Override
+		public Class<?> getDomainType() {
+			return metadata.getDomainType();
+		}
+
+		@Override
+		public boolean isExported(PersistentProperty<?> property) {
+			return metadata.isExported(property);
+		}
+
+		@Override
+		public PropertyAwareResourceMapping getProperty(String mappedPath) {
+			return metadata.getProperty(mappedPath);
+		}
+
+		@Override
+		public ResourceMapping getMappingFor(PersistentProperty<?> property) {
+			return metadata.getMappingFor(property);
+		}
+
+		@Override
+		public SearchResourceMappings getSearchResourceMappings() {
+			return metadata.getSearchResourceMappings();
+		}
+
+		@Override
+		public SupportedHttpMethods getSupportedHttpMethods() {
+			return metadata.getSupportedHttpMethods();
+		}
+	}
+}
diff --git a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java
index 4d54c2e3ad0bbaee5d719022999b34a735022257..4feced27c6e16b2ecfc4837c17adf9a8e3468bbe 100644
--- a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java
+++ b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java
@@ -23,8 +23,9 @@
  */
 package de.ozgcloud.admin;
 
-import de.ozgcloud.admin.common.user.CurrentUserService;
-import de.ozgcloud.admin.common.user.UserRole;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties;
 import org.springframework.hateoas.EntityModel;
 import org.springframework.hateoas.Link;
@@ -34,9 +35,6 @@ import org.springframework.stereotype.Component;
 
 import lombok.RequiredArgsConstructor;
 
-import java.util.ArrayList;
-import java.util.List;
-
 @Component
 @RequiredArgsConstructor
 public class RootModelAssembler implements RepresentationModelAssembler<Root, EntityModel<Root>> {
@@ -44,23 +42,17 @@ public class RootModelAssembler implements RepresentationModelAssembler<Root, En
 
 	private final RepositoryRestProperties restProperties;
 
-	private final CurrentUserService currentUserService;
-
 	@Override
 	public EntityModel<Root> toModel(Root root) {
 		List<Link> links = buildRootModelLinks();
-		return EntityModel.of(
-				root,
-				links);
+		return EntityModel.of(root, links);
 	}
 
 	List<Link> buildRootModelLinks() {
 		List<Link> links = new ArrayList<>();
 		var rootLinkBuilder = WebMvcLinkBuilder.linkTo(RootController.class);
 		links.add(rootLinkBuilder.withSelfRel());
-		if (currentUserService.hasRole(UserRole.ADMIN_ADMIN)) {
-			links.add(buildConfigLink());
-		}
+		links.add(buildConfigLink());
 		return links;
 	}
 
@@ -68,7 +60,6 @@ public class RootModelAssembler implements RepresentationModelAssembler<Root, En
 		var rootLinkBuilder = WebMvcLinkBuilder.linkTo(RootController.class);
 		return Link.of(
 				rootLinkBuilder.toUriComponentsBuilder().replacePath(restProperties.getBasePath()).toUriString(),
-				REL_CONFIGURATION
-		);
+				REL_CONFIGURATION);
 	}
 }
diff --git a/src/main/java/de/ozgcloud/admin/common/AbstractLinkedResourceDeserializer.java b/src/main/java/de/ozgcloud/admin/common/AbstractLinkedResourceDeserializer.java
deleted file mode 100644
index 106c3616b4a08d51e8ee413587fed710fc0dba98..0000000000000000000000000000000000000000
--- a/src/main/java/de/ozgcloud/admin/common/AbstractLinkedResourceDeserializer.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-import org.apache.commons.lang3.StringUtils;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.BeanProperty;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
-import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-
-import de.ozgcloud.common.datatype.StringBasedValue;
-import lombok.Getter;
-
-abstract class AbstractLinkedResourceDeserializer extends StdDeserializer<Object> implements ContextualDeserializer {
-
-	private static final long serialVersionUID = 1L;
-
-	@Getter
-	private BeanProperty beanProperty;
-
-	@Getter
-	private final JavaType targetType;
-
-	protected AbstractLinkedResourceDeserializer() {
-		super(Object.class);
-		targetType = null;
-	}
-
-	protected AbstractLinkedResourceDeserializer(BeanProperty beanProperty) {
-		super(Object.class);
-		this.beanProperty = beanProperty;
-		this.targetType = beanProperty.getType();
-	}
-
-	@Override
-	public Object deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
-		if (jsonParser.isExpectedStartArrayToken()) {
-			Collection<Object> idList = targetType.getRawClass().isAssignableFrom(Set.class) ? new HashSet<>() : new ArrayList<>();
-
-			while (!jsonParser.nextToken().isStructEnd()) {
-				idList.add(extractId(jsonParser.getText()));
-			}
-			return idList;
-		} else {
-			return extractId(jsonParser.getText());
-		}
-	}
-
-	Object extractId(String url) {
-		Class<?> type;
-		if (targetType.isCollectionLikeType()) {
-			type = targetType.getContentType().getRawClass();
-		} else {
-			type = targetType.getRawClass();
-		}
-
-		if (String.class.isAssignableFrom(type)) {
-			return extractStringId(url);
-		}
-		if (Long.class.isAssignableFrom(type) || Long.TYPE.isAssignableFrom(type)) {
-			return extractLongId(url);
-		}
-		if (StringBasedValue.class.isAssignableFrom(type)) {
-			return extractStringBasedValue(type, url);
-		}
-		return buildByBuilder(url);
-	}
-
-	abstract Object buildByBuilder(String url);
-
-	public static Long extractLongId(String uri) {
-		var trimedUri = StringUtils.trimToNull(uri);
-		if (Objects.isNull(trimedUri)) {
-			return null;
-		}
-		return Long.parseLong(URLDecoder.decode(trimedUri.substring(trimedUri.lastIndexOf('/') + 1), StandardCharsets.UTF_8));
-	}
-
-	private StringBasedValue extractStringBasedValue(Class<?> type, String url) {
-		String value = extractStringId(url);
-		Method fromMethod;
-		try {
-			fromMethod = type.getMethod("from", String.class);
-		} catch (NoSuchMethodException e) {
-			throw new IllegalStateException(
-					String.format("Cannot generate Id from type '%s'. Missing 'from' Method.", targetType.getRawClass().getSimpleName()));
-		}
-		try {
-			return (StringBasedValue) fromMethod.invoke(null, value);
-		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-			throw new IllegalStateException(
-					String.format("Cannot generate Id from type '%s'. Error calling 'from' Method.", targetType.getRawClass().getSimpleName()),
-					e);
-		}
-	}
-
-	public static String extractStringId(String url) {
-		return URLDecoder.decode(url.substring(url.lastIndexOf('/') + 1), StandardCharsets.UTF_8);
-	}
-}
diff --git a/src/main/java/de/ozgcloud/admin/common/AbstractLinkedResourceSerializer.java b/src/main/java/de/ozgcloud/admin/common/AbstractLinkedResourceSerializer.java
deleted file mode 100644
index aff16f22a29698cf591680353e4bf07800810d04..0000000000000000000000000000000000000000
--- a/src/main/java/de/ozgcloud/admin/common/AbstractLinkedResourceSerializer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.ser.ContextualSerializer;
-
-import de.ozgcloud.common.errorhandling.TechnicalException;
-
-abstract class AbstractLinkedResourceSerializer extends JsonSerializer<Object> implements ContextualSerializer {
-	@Override
-	public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
-
-		if (value instanceof Collection) {
-			gen.writeStartArray();
-			((Collection<?>) value).forEach(val -> writeObject(gen, buildLink(val)));
-			gen.writeEndArray();
-		} else {
-			writeObject(gen, buildLink(value));
-		}
-	}
-
-	abstract String buildLink(Object id);
-
-	abstract IdExtractor<Object> getExtractor();
-
-	void writeObject(JsonGenerator gen, Object value) {
-		try {
-			gen.writeObject(value);
-		} catch (IOException e) {
-			throw new TechnicalException("Error writing String to json", e);
-		}
-	}
-}
diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingValidator.java b/src/main/java/de/ozgcloud/admin/common/DelegatingValidatorAdapter.java
similarity index 75%
rename from src/main/java/de/ozgcloud/admin/setting/SettingValidator.java
rename to src/main/java/de/ozgcloud/admin/common/DelegatingValidatorAdapter.java
index 54ecb425791b213835169e3303fc74b2296abe4c..870b17f79246c3db1491c81b56ad9fd8efab4c18 100644
--- a/src/main/java/de/ozgcloud/admin/setting/SettingValidator.java
+++ b/src/main/java/de/ozgcloud/admin/common/DelegatingValidatorAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -21,27 +21,30 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.setting;
+package de.ozgcloud.admin.common;
+
+import java.util.Objects;
 
 import jakarta.validation.ConstraintViolationException;
-import jakarta.validation.Validation;
 
-import org.springframework.stereotype.Component;
 import org.springframework.validation.Errors;
 import org.springframework.validation.Validator;
 
-@Component
-class SettingValidator implements Validator {
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public class DelegatingValidatorAdapter implements Validator {
+
+	private final jakarta.validation.Validator delegate;
 
 	@Override
 	public boolean supports(Class<?> clazz) {
-		return Setting.class.equals(clazz);
+		return !Objects.isNull(delegate);
 	}
 
 	@Override
 	public void validate(Object target, Errors errors) {
-		var validator = Validation.buildDefaultValidatorFactory().getValidator();
-		var constraintViolations = validator.validate(target);
+		var constraintViolations = delegate.validate(target);
 		if (!constraintViolations.isEmpty()) {
 			throw new ConstraintViolationException(constraintViolations);
 		}
diff --git a/src/main/java/de/ozgcloud/admin/common/ObjectBuilder.java b/src/main/java/de/ozgcloud/admin/common/DtoService.java
similarity index 70%
rename from src/main/java/de/ozgcloud/admin/common/ObjectBuilder.java
rename to src/main/java/de/ozgcloud/admin/common/DtoService.java
index a08385af64361f8e178d9a03451f81853eeda9d8..6e260a3fb3ff15674ca5b88717426c40df1ec3ac 100644
--- a/src/main/java/de/ozgcloud/admin/common/ObjectBuilder.java
+++ b/src/main/java/de/ozgcloud/admin/common/DtoService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -23,11 +23,17 @@
  */
 package de.ozgcloud.admin.common;
 
-import com.fasterxml.jackson.databind.BeanProperty;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
-public interface ObjectBuilder<T> {
+import org.springframework.stereotype.Service;
 
-	T build(Object id);
+@Service
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DtoService {
 
-	ObjectBuilder<T> constructContextAware(BeanProperty property);
+	String[] value();
 }
diff --git a/src/main/java/de/ozgcloud/admin/common/LinkedResource.java b/src/main/java/de/ozgcloud/admin/common/LinkedResource.java
deleted file mode 100644
index 4798f516bf52910ab2641ecba167540622dfb101..0000000000000000000000000000000000000000
--- a/src/main/java/de/ozgcloud/admin/common/LinkedResource.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.core.annotation.AliasFor;
-
-import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-@Inherited
-
-@JacksonAnnotationsInside
-@JsonSerialize(using = LinkedResourceSerializer.class)
-@JsonDeserialize(using = LinkedResourceDeserializer.class)
-public @interface LinkedResource {
-
-	Class<?> controllerClass();
-
-	Class<? extends IdExtractor<Object>> extractor() default ToStringExtractor.class;
-
-	@AliasFor(annotation = JsonDeserialize.class, attribute = "builder")
-	Class<? extends ObjectBuilder<Object>> builder() default IdBuilder.class;
-}
\ No newline at end of file
diff --git a/src/main/java/de/ozgcloud/admin/common/LinkedResourceDeserializer.java b/src/main/java/de/ozgcloud/admin/common/LinkedResourceDeserializer.java
deleted file mode 100644
index 7130e16af20c1f774e599b3096bced026c1b7bbe..0000000000000000000000000000000000000000
--- a/src/main/java/de/ozgcloud/admin/common/LinkedResourceDeserializer.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.commons.lang3.reflect.ConstructorUtils;
-
-import com.fasterxml.jackson.databind.BeanProperty;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-
-import de.ozgcloud.common.errorhandling.TechnicalException;
-
-public class LinkedResourceDeserializer extends AbstractLinkedResourceDeserializer {
-
-	private static final long serialVersionUID = 1L;
-
-	private LinkedResource annotation;
-
-	protected LinkedResourceDeserializer() {
-		super();
-	}
-
-	protected LinkedResourceDeserializer(BeanProperty beanProperty) {
-		super(beanProperty);
-		this.annotation = beanProperty.getAnnotation(LinkedResource.class);
-	}
-
-	@Override
-	Object buildByBuilder(String url) {
-		ObjectBuilder<?> builder;
-		try {
-			builder = ConstructorUtils.invokeConstructor(annotation.builder()).constructContextAware(getBeanProperty());
-		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
-			throw new TechnicalException("Error instanciating Builder.", e);
-		}
-		return builder.build(extractStringId(url));
-	}
-
-	@Override
-	public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
-		return new LinkedResourceDeserializer(property);
-	}
-
-}
diff --git a/src/main/java/de/ozgcloud/admin/common/LinkedResourceSerializer.java b/src/main/java/de/ozgcloud/admin/common/LinkedResourceSerializer.java
deleted file mode 100644
index 28a098c82185730476c0f85f4eb299a7bdd3ed13..0000000000000000000000000000000000000000
--- a/src/main/java/de/ozgcloud/admin/common/LinkedResourceSerializer.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.commons.lang3.reflect.ConstructorUtils;
-
-import com.fasterxml.jackson.databind.BeanProperty;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-
-import de.ozgcloud.common.errorhandling.TechnicalException;
-import lombok.NoArgsConstructor;
-
-@NoArgsConstructor
-public class LinkedResourceSerializer extends AbstractLinkedResourceSerializer {
-
-	private LinkedResource annotation;
-
-	private LinkedResourceSerializer(LinkedResource annotation) {
-		this.annotation = annotation;
-	}
-
-	@Override
-	public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
-		return new LinkedResourceSerializer(property.getAnnotation(LinkedResource.class));
-	}
-
-	@Override
-	String buildLink(Object id) {
-		return linkTo(annotation.controllerClass()).slash(getExtractor().extractId(id)).toString();
-	}
-
-	@Override
-	IdExtractor<Object> getExtractor() {
-		try {
-			return ConstructorUtils.invokeConstructor(annotation.extractor());
-		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
-			throw new TechnicalException("Error instanciating IdExtractor", e);
-		}
-	}
-}
diff --git a/src/main/java/de/ozgcloud/admin/common/ModelBuilder.java b/src/main/java/de/ozgcloud/admin/common/ModelBuilder.java
deleted file mode 100644
index cd90619981aa59db2f29a1f158c76000773aacb2..0000000000000000000000000000000000000000
--- a/src/main/java/de/ozgcloud/admin/common/ModelBuilder.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BooleanSupplier;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.function.UnaryOperator;
-import java.util.stream.Collectors;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.reflect.FieldUtils;
-import org.springframework.hateoas.EntityModel;
-import org.springframework.hateoas.Link;
-import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-public class ModelBuilder<T> {
-
-	private static final Map<Class<?>, Map<Object, List<Field>>> ANNOTATED_FIELDS_BY_ANNOTATION = new ConcurrentHashMap<>();
-
-	private final T entity;
-	private final EntityModel<T> model;
-
-	private final List<Link> links = new LinkedList<>();
-	private final List<Function<EntityModel<T>, EntityModel<T>>> mapper = new LinkedList<>();
-
-	private ModelBuilder(T entity) {
-		this.entity = entity;
-		this.model = null;
-	}
-
-	private ModelBuilder(EntityModel<T> model) {
-		this.entity = null;
-		this.model = model;
-	}
-
-	public static <T> ModelBuilder<T> fromEntity(T entity) {
-		return new ModelBuilder<>(entity);
-	}
-
-	public static <T> ModelBuilder<T> fromModel(EntityModel<T> model) {
-		return new ModelBuilder<>(model);
-	}
-
-	public ModelBuilder<T> addLink(Link link) {
-		links.add(link);
-		return this;
-	}
-
-	public ModelBuilder<T> addLink(Optional<Link> link) {
-		link.ifPresent(links::add);
-		return this;
-	}
-
-	public ModelBuilder<T> addLinks(Link... links) {
-		this.links.addAll(Arrays.asList(links));
-		return this;
-	}
-
-	public ModelBuilder<T> addLinks(Collection<Link> links) {
-		this.links.addAll(links);
-		return this;
-	}
-
-	public ConditionalLinkAdder ifMatch(Predicate<T> predicate) {
-		return new ConditionalLinkAdder(predicate.test(Objects.isNull(entity) ? model.getContent() : entity));
-	}
-
-	public ConditionalLinkAdder ifMatch(BooleanSupplier guard) {
-		return new ConditionalLinkAdder(guard.getAsBoolean());
-	}
-
-	public ModelBuilder<T> map(UnaryOperator<EntityModel<T>> mapper) {
-		this.mapper.add(mapper);
-		return this;
-	}
-
-	public EntityModel<T> buildModel() {
-		var filteredLinks = links.stream().filter(Objects::nonNull).collect(Collectors.toSet());
-
-		EntityModel<T> buildedModel = Objects.isNull(model) ? EntityModel.of(entity) : model;
-		buildedModel = buildedModel.add(filteredLinks);
-
-		addLinkByLinkedResourceAnnotationIfMissing(buildedModel);
-
-		return applyMapper(buildedModel);
-	}
-
-	private EntityModel<T> applyMapper(EntityModel<T> resource) {
-		Iterator<Function<EntityModel<T>, EntityModel<T>>> i = mapper.iterator();
-		EntityModel<T> result = resource;
-		while (i.hasNext()) {
-			result = i.next().apply(result);
-		}
-		return result;
-	}
-
-	private void addLinkByLinkedResourceAnnotationIfMissing(EntityModel<T> resource) {
-		getFields(LinkedResource.class).stream()
-				.filter(field -> shouldAddLink(resource, field))
-				.forEach(field -> handleLinkedResourceField(resource, field));
-	}
-
-	private void handleLinkedResourceField(EntityModel<T> resource, Field field) {
-		getEntityFieldValue(field).map(Object::toString).filter(StringUtils::isNotBlank).ifPresent(val -> resource
-				.add(WebMvcLinkBuilder.linkTo(field.getAnnotation(LinkedResource.class).controllerClass()).slash(val)
-						.withRel(sanitizeName(field.getName()))));
-	}
-
-	private boolean shouldAddLink(EntityModel<T> resource, Field field) {
-		return !(field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) || resource.hasLink(sanitizeName(field.getName())));
-	}
-
-	private List<Field> getFields(Class<? extends Annotation> annotationClass) {
-		var fields = Optional.ofNullable(ANNOTATED_FIELDS_BY_ANNOTATION.get(getEntity().getClass()))
-				.map(fieldsByAnnotation -> fieldsByAnnotation.get(annotationClass))
-				.orElseGet(Collections::emptyList);
-
-		if (CollectionUtils.isEmpty(fields)) {
-			fields = FieldUtils.getFieldsListWithAnnotation(getEntity().getClass(), annotationClass);
-
-			updateFields(annotationClass, fields);
-		}
-		return fields;
-	}
-
-	private void updateFields(Class<? extends Annotation> annotationClass, List<Field> fields) {
-		var annotationMap = Optional.ofNullable(ANNOTATED_FIELDS_BY_ANNOTATION.get(getEntity().getClass())).orElseGet(HashMap::new);
-		annotationMap.put(annotationClass, fields);
-
-		ANNOTATED_FIELDS_BY_ANNOTATION.put(annotationClass, annotationMap);
-	}
-
-	private String sanitizeName(String fieldName) {
-		if (fieldName.endsWith("Id")) {
-			return fieldName.substring(0, fieldName.indexOf("Id"));
-		}
-		return fieldName;
-	}
-
-	private Optional<Object> getEntityFieldValue(Field field) {
-		try {
-			field.setAccessible(true);
-			Optional<Object> value = Optional.ofNullable(field.get(getEntity()));
-			field.setAccessible(false);
-			return value;
-		} catch (IllegalArgumentException | IllegalAccessException e) {
-			LOG.warn("Cannot access field value of LinkedResource field.", e);
-		}
-		return Optional.empty();
-	}
-
-	private T getEntity() {
-		return Optional.ofNullable(entity == null ? model.getContent() : entity)
-				.orElseThrow(() -> new IllegalStateException("Entity must not null for ModelBuilding"));
-	}
-
-	@RequiredArgsConstructor
-	public class ConditionalLinkAdder {
-
-		public final boolean conditionFulfilled;
-
-		public ModelBuilder<T> addLink(Supplier<Link> linkSupplier) {
-			if (conditionFulfilled) {
-				addLink(linkSupplier.get());
-			}
-			return ModelBuilder.this;
-		}
-
-		public ModelBuilder<T> addLinkIfPresent(Supplier<Optional<Link>> linkSupplier) {
-			if (conditionFulfilled) {
-				addLink(linkSupplier.get());
-			}
-			return ModelBuilder.this;
-		}
-
-		public ModelBuilder<T> addLink(Function<T, Link> linkBuilder) {
-			if (conditionFulfilled) {
-				addLink(linkBuilder.apply(getEntity()));
-			}
-			return ModelBuilder.this;
-		}
-
-		public ModelBuilder<T> addLink(Link link) {
-			if (conditionFulfilled) {
-				links.add(link);
-			}
-			return ModelBuilder.this;
-		}
-
-		public ModelBuilder<T> addLink(Optional<Link> link) {
-			if (conditionFulfilled) {
-				link.ifPresent(links::add);
-			}
-			return ModelBuilder.this;
-		}
-
-		public ModelBuilder<T> addLinks(Link... links) {
-			if (conditionFulfilled) {
-				ModelBuilder.this.links.addAll(Arrays.asList(links));
-			}
-			return ModelBuilder.this;
-		}
-
-		@SafeVarargs
-		public final ModelBuilder<T> addLinks(Supplier<Link>... linkSuppliers) {
-			if (conditionFulfilled) {
-				for (int i = 0; i < linkSuppliers.length; i++) {
-					ModelBuilder.this.links.add(linkSuppliers[i].get());
-				}
-			}
-			return ModelBuilder.this;
-		}
-
-		public final ModelBuilder<T> addLinks(Supplier<Collection<Link>> linksSupplier) {
-			if (conditionFulfilled) {
-				linksSupplier.get().forEach(ModelBuilder.this.links::add);
-			}
-
-			return ModelBuilder.this;
-		}
-
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/de/ozgcloud/admin/common/IdExtractor.java b/src/main/java/de/ozgcloud/admin/common/SettingDtoService.java
similarity index 84%
rename from src/main/java/de/ozgcloud/admin/common/IdExtractor.java
rename to src/main/java/de/ozgcloud/admin/common/SettingDtoService.java
index 658b06586cd447274ef701dc8942af43300a814a..e99addc6f1bc9cbf172a6c0be1baebbf29cd9812 100644
--- a/src/main/java/de/ozgcloud/admin/common/IdExtractor.java
+++ b/src/main/java/de/ozgcloud/admin/common/SettingDtoService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -23,7 +23,9 @@
  */
 package de.ozgcloud.admin.common;
 
-@FunctionalInterface
-public interface IdExtractor<T> {
-	String extractId(T object);
-}
\ No newline at end of file
+public interface SettingDtoService {
+
+	String getSettingKeyName();
+
+	Object getDataTransferObject();
+}
diff --git a/src/main/java/de/ozgcloud/admin/common/user/UserRole.java b/src/main/java/de/ozgcloud/admin/common/user/UserRole.java
index d4745c0a2a8bb515dcc694024383e187aee03f36..8c28ea3ebe1bc531ad2447297ec9f3f23e370554 100644
--- a/src/main/java/de/ozgcloud/admin/common/user/UserRole.java
+++ b/src/main/java/de/ozgcloud/admin/common/user/UserRole.java
@@ -28,5 +28,6 @@ import lombok.NoArgsConstructor;
 
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public class UserRole {
+	public static final String DATENBEAUFTRAGUNG = "DATENBEAUFTRAGUNG";
 	public static final String ADMIN_ADMIN = "ADMIN_ADMIN";
 }
diff --git a/src/main/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessor.java b/src/main/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1a750f6c95152b2eb1d94ea15d312f8e303f074
--- /dev/null
+++ b/src/main/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessor.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.keycloak;
+
+import java.util.Map;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.Link;
+import org.springframework.hateoas.server.RepresentationModelProcessor;
+import org.springframework.stereotype.Component;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import de.ozgcloud.admin.Root;
+import de.ozgcloud.admin.common.FeatureToggleProperties;
+import de.ozgcloud.admin.common.user.CurrentUserService;
+import de.ozgcloud.admin.common.user.UserRole;
+import lombok.RequiredArgsConstructor;
+
+@Component
+@RequiredArgsConstructor
+@ConditionalOnProperty(prefix = FeatureToggleProperties.FEATURE_TOGGLE_PREFIX, name = "benutzer-rollen", havingValue = "true")
+class KeyCloakRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> {
+
+	private static final String KEYCLOAK_API_TEMPLATE = "{baseUrl}/admin/realms/{realm}/users";
+	private static final String BASE_URL_KEY = "baseUrl";
+	private static final String REALM_KEY = "realm";
+
+	public static final String REL_USERS = "users";
+
+	private final KeycloakApiProperties keycloakApiProperties;
+	private final CurrentUserService currentUserService;
+
+	@Override
+	public EntityModel<Root> process(EntityModel<Root> model) {
+		return model.addIf(currentUserService.hasRole(UserRole.ADMIN_ADMIN), () -> Link.of(buildUsersHref(), REL_USERS));
+	}
+
+	String buildUsersHref() {
+		Map<String, Object> pathVariableMap = Map.of(BASE_URL_KEY, keycloakApiProperties.getUrl(), REALM_KEY, keycloakApiProperties.getRealm());
+		return UriComponentsBuilder.fromUriString(KEYCLOAK_API_TEMPLATE).uriVariables(pathVariableMap)
+				.build().toUriString();
+	}
+}
diff --git a/src/main/java/de/ozgcloud/admin/reporting/AggregationMapping.java b/src/main/java/de/ozgcloud/admin/reporting/AggregationMapping.java
new file mode 100644
index 0000000000000000000000000000000000000000..d923d2c01a69af97787af47de8444cab6d086dd4
--- /dev/null
+++ b/src/main/java/de/ozgcloud/admin/reporting/AggregationMapping.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.reporting;
+
+import java.util.List;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.TypeAlias;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Singular;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+
+@Document("settings")
+@TypeAlias(AggregationMapping.TYPE_ALIAS)
+@Jacksonized
+@Builder
+@Getter
+@ToString
+public class AggregationMapping {
+
+	public static final String TYPE_ALIAS = "AggregationMapping";
+
+	@Id
+	@JsonIgnore
+	private String id;
+	@Builder.Default
+	private String name = "aggregationMapping";
+
+	@Valid
+	private FormIdentifier formIdentifier;
+
+	@NotEmpty
+	@Singular
+	private List<FieldMapping> mappings;
+
+	@Builder
+	@Getter
+	@ToString
+	static class FieldMapping {
+		@NotBlank
+		private String sourcePath;
+		@NotBlank
+		private String targetPath;
+	}
+
+	@Builder
+	@Getter
+	@ToString
+	static class FormIdentifier {
+		@NotBlank
+		private String formEngineName;
+		@NotBlank
+		private String formId;
+	}
+}
diff --git a/src/test/java/de/ozgcloud/admin/common/EntityModelTestFactory.java b/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingMapper.java
similarity index 61%
rename from src/test/java/de/ozgcloud/admin/common/EntityModelTestFactory.java
rename to src/main/java/de/ozgcloud/admin/reporting/AggregationMappingMapper.java
index 1f01a94247938090c4e85f0d9c96d3ec399aeb6c..81a25c3042c172767fa810162764de2d72b9b3d9 100644
--- a/src/test/java/de/ozgcloud/admin/common/EntityModelTestFactory.java
+++ b/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingMapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -21,23 +21,18 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.common;
+package de.ozgcloud.admin.reporting;
 
-import org.springframework.hateoas.EntityModel;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.NullValueCheckStrategy;
 
-import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheit;
-import lombok.NoArgsConstructor;
+import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.AggregationMappingDto;
 
-public class EntityModelTestFactory {
+@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
+public interface AggregationMappingMapper {
 
-	public static final NullableEntityModel NULLABLE = createNullable();
-
-	private static NullableEntityModel createNullable() {
-		return new NullableEntityModel();
-	}
-
-	@NoArgsConstructor
-	private static class NullableEntityModel extends EntityModel<OrganisationsEinheit> {
-
-	}
+	@Mapping(target = "fieldMapping", ignore = true)
+	@Mapping(target = "fieldMappings", source = "mappings")
+	AggregationMappingDto toMapping(AggregationMapping setting);
 }
diff --git a/src/main/java/de/ozgcloud/admin/common/ToStringExtractor.java b/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingRepository.java
similarity index 59%
rename from src/main/java/de/ozgcloud/admin/common/ToStringExtractor.java
rename to src/main/java/de/ozgcloud/admin/reporting/AggregationMappingRepository.java
index dade3573176baac48e7f6df83e0c45a4c1cb9389..249aa175f5c7a313ba1e69dd178926fd29c8f2a0 100644
--- a/src/main/java/de/ozgcloud/admin/common/ToStringExtractor.java
+++ b/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -21,15 +21,19 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.common;
+package de.ozgcloud.admin.reporting;
 
-import lombok.NoArgsConstructor;
+import java.util.List;
 
-@NoArgsConstructor
-class ToStringExtractor implements IdExtractor<Object> {
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.mongodb.repository.Query;
+import org.springframework.data.rest.core.annotation.RepositoryRestResource;
+import org.springframework.security.access.annotation.Secured;
 
+@Secured("ROLE_DATENBEAUFTRAGUNG")
+@RepositoryRestResource
+interface AggregationMappingRepository extends MongoRepository<AggregationMapping, String> {
 	@Override
-	public String extractId(Object object) {
-		return object.toString();
-	}
+	@Query("{'_class': 'AggregationMapping'}")
+	List<AggregationMapping> findAll();
 }
diff --git a/src/main/java/de/ozgcloud/admin/setting/DataRestConfiguration.java b/src/main/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDto.java
similarity index 54%
rename from src/main/java/de/ozgcloud/admin/setting/DataRestConfiguration.java
rename to src/main/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDto.java
index b93f96d8665b904d133d44f9e3682b649e5ed5a6..00e74b76d4eaad2b3bbe9937c781f505852ff942 100644
--- a/src/main/java/de/ozgcloud/admin/setting/DataRestConfiguration.java
+++ b/src/main/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDto.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -21,23 +21,42 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.setting;
+package de.ozgcloud.admin.reporting;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
-import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
+import java.util.List;
 
-import lombok.RequiredArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Singular;
+import lombok.ToString;
 
-@Configuration
-@RequiredArgsConstructor
-public class DataRestConfiguration implements RepositoryRestConfigurer {
+@Builder
+@Getter
+@ToString
+public class ReportingAggregationManagerSettingDto {
 
-	private final SettingValidator settingValidator;
+	@Singular
+	private List<AggregationMappingDto> aggregationMappings;
 
-	@Override
-	public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
-		v.addValidator("beforeSave", settingValidator);
-		v.addValidator("beforeCreate", settingValidator);
+	@Builder
+	@Getter
+	static class AggregationMappingDto {
+		private FormIdentifierDto formIdentifier;
+		@Singular
+		private List<FieldMappingDto> fieldMappings;
 	}
-}
\ No newline at end of file
+
+	@Builder
+	@Getter
+	static class FormIdentifierDto {
+		private String formEngineName;
+		private String formId;
+	}
+
+	@Builder
+	@Getter
+	static class FieldMappingDto {
+		private String sourcePath;
+		private String targetPath;
+	}
+}
diff --git a/src/main/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoService.java b/src/main/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoService.java
new file mode 100644
index 0000000000000000000000000000000000000000..acb46bf40ebaf81a11b896ed6c2d55c7048f29e7
--- /dev/null
+++ b/src/main/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoService.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.reporting;
+
+import java.util.stream.Stream;
+
+import de.ozgcloud.admin.common.DtoService;
+import de.ozgcloud.admin.common.SettingDtoService;
+import de.ozgcloud.admin.setting.SettingConstants;
+import de.ozgcloud.admin.setting.SettingRepository;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+@DtoService(SettingConstants.AGGREGATION_MANAGER)
+class ReportingAggregationManagerSettingDtoService implements SettingDtoService {
+
+	private final AggregationMappingMapper mapper;
+
+	private final SettingRepository repository;
+
+	@Override
+	public ReportingAggregationManagerSettingDto getDataTransferObject() {
+		return mapToDto(repository.findByType("AggregationMapping", AggregationMapping.class));
+	}
+
+	ReportingAggregationManagerSettingDto mapToDto(Stream<AggregationMapping> settings) {
+		return ReportingAggregationManagerSettingDto.builder()
+				.aggregationMappings(settings.map(mapper::toMapping).toList())
+				.build();
+	}
+
+	@Override
+	public String getSettingKeyName() {
+		return "aggregation";
+	}
+}
diff --git a/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java b/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java
index b3d46b9d610865098fc760e8a94e94ee79f594f2..9d8cd455bdd726f2d31207ac96c8740cb4139dbd 100644
--- a/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java
+++ b/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java
@@ -56,16 +56,13 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class SecurityConfiguration {
 
-	private final AdminAuthenticationEntryPoint authenticationEntryPoint;
-
-	private final OAuth2Properties oAuth2Properties;
-
 	static final String RESOURCE_ACCESS_KEY = "resource_access";
-
 	static final String SIMPLE_GRANT_AUTHORITY_PREFIX = "ROLE_";
-
 	static final String ROLES_KEY = "roles";
 
+	private final AdminAuthenticationEntryPoint authenticationEntryPoint;
+	private final OAuth2Properties oAuth2Properties;
+
 	@Bean
 	SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
@@ -77,8 +74,8 @@ public class SecurityConfiguration {
 
 		http.authorizeHttpRequests(requests -> requests
 				.requestMatchers(HttpMethod.GET, "/api/environment").permitAll()
-				.requestMatchers("/api/configuration").hasRole(UserRole.ADMIN_ADMIN)
-				.requestMatchers("/api/configuration/**").hasRole(UserRole.ADMIN_ADMIN)
+				.requestMatchers("/api/configuration").hasAnyRole(UserRole.ADMIN_ADMIN, UserRole.DATENBEAUFTRAGUNG)
+				.requestMatchers("/api/configuration/**").hasAnyRole(UserRole.ADMIN_ADMIN, UserRole.DATENBEAUFTRAGUNG)
 				.requestMatchers("/api").authenticated()
 				.requestMatchers("/api/**").authenticated()
 				.requestMatchers("/actuator").permitAll()
@@ -89,11 +86,11 @@ public class SecurityConfiguration {
 		return http.build();
 	}
 
+	// TODO OZG-4954 replace with spring defaults
 	@Bean
 	JwtAuthenticationConverter jwtAuthenticationConverter() {
 		var jwtConverter = new JwtAuthenticationConverter();
-		jwtConverter.setJwtGrantedAuthoritiesConverter(
-				this::convertJwtToGrantedAuthorities);
+		jwtConverter.setJwtGrantedAuthoritiesConverter(this::convertJwtToGrantedAuthorities);
 		jwtConverter.setPrincipalClaimName(StandardClaimNames.PREFERRED_USERNAME);
 		return jwtConverter;
 	}
diff --git a/src/test/java/de/ozgcloud/admin/common/LinkedResourceTestObject.java b/src/main/java/de/ozgcloud/admin/setting/MapBasedApplicationSettingDto.java
similarity index 67%
rename from src/test/java/de/ozgcloud/admin/common/LinkedResourceTestObject.java
rename to src/main/java/de/ozgcloud/admin/setting/MapBasedApplicationSettingDto.java
index d30ab26ef5568705572702d1e5401c215a5b40cb..178302ff18d14392d8f33ab8249c40c32c13c7b9 100644
--- a/src/test/java/de/ozgcloud/admin/common/LinkedResourceTestObject.java
+++ b/src/main/java/de/ozgcloud/admin/setting/MapBasedApplicationSettingDto.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -21,18 +21,25 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.common;
+package de.ozgcloud.admin.setting;
 
-import de.ozgcloud.admin.common.user.TestId;
-import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitController;
-import lombok.AllArgsConstructor;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+
+import lombok.Builder;
 import lombok.Getter;
-import lombok.NoArgsConstructor;
+import lombok.Singular;
 
+@Builder
 @Getter
-@AllArgsConstructor
-@NoArgsConstructor
-class LinkedResourceTestObject {
-	@LinkedResource(controllerClass = OrganisationsEinheitController.class)
-	private TestId id;
+public class MapBasedApplicationSettingDto implements ApplicationSettingDTO {
+
+	@Singular
+	private Map<String, Object> settings;
+
+	@JsonAnyGetter
+	public Map<String, Object> getSettings() {
+		return settings;
+	}
 }
diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingConstants.java b/src/main/java/de/ozgcloud/admin/setting/SettingConstants.java
index 9c40c6120a702447e27ebc8093025568763de5d3..afcf09344d8f76dc3519c635b99bfc933e185d24 100644
--- a/src/main/java/de/ozgcloud/admin/setting/SettingConstants.java
+++ b/src/main/java/de/ozgcloud/admin/setting/SettingConstants.java
@@ -32,4 +32,6 @@ public class SettingConstants {
 	static final String REL = "settings";
 
 	public static final String PATH = "settings";
+
+	public static final String AGGREGATION_MANAGER = "OzgCloud_AggregationManager";
 }
diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java b/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java
index db793f2f49805d18a48037b96817cdd1aa4c88e3..a6e74eac7d909eeefc363eebb43cb5cf078e49e5 100644
--- a/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java
+++ b/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java
@@ -23,6 +23,8 @@
  */
 package de.ozgcloud.admin.setting;
 
+import static de.ozgcloud.admin.setting.SettingConstants.*;
+
 import java.util.Map;
 import java.util.Optional;
 
@@ -41,13 +43,12 @@ import lombok.RequiredArgsConstructor;
 @Component
 public class SettingEnvironmentRepository implements EnvironmentRepository {
 
-	private final SettingService settingService;
-
-	private final ObjectMapper objectMapper;
-
 	private static final String ALFA = "Alfa";
 	private static final String VORGANG_MANAGER = "OzgCloud_VorgangManager";
 
+	private final SettingService settingService;
+	private final ObjectMapper objectMapper;
+
 	@Override
 	public Environment findOne(String application, String profile, String label) {
 		return buildEnvironment(application, findAnwendungSettingDTO(application));
@@ -59,6 +60,8 @@ public class SettingEnvironmentRepository implements EnvironmentRepository {
 				return Optional.of(settingService.getAlfaSettingDTO());
 			case VORGANG_MANAGER:
 				return Optional.of(settingService.getVorgangManagerSettingDTO());
+			case AGGREGATION_MANAGER:
+				return Optional.of(settingService.getAggregationManagerSettingDto());
 			default:
 				return Optional.empty();
 		}
diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java b/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java
index 5180dea45a85d6007717a4e2a3d64cbb6ad7c6d9..ddeeae9fd0a5cb80dec50bf3c9b5c41492318c3a 100644
--- a/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java
+++ b/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java
@@ -23,13 +23,25 @@
  */
 package de.ozgcloud.admin.setting;
 
+import java.util.List;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.mongodb.repository.Query;
 import org.springframework.data.rest.core.annotation.RepositoryRestResource;
+import org.springframework.security.access.annotation.Secured;
 
 @RepositoryRestResource(collectionResourceRel = SettingConstants.REL, path = SettingConstants.PATH)
-interface SettingRepository extends MongoRepository<Setting, String> {
+public interface SettingRepository extends MongoRepository<Setting, String> {
+
+	@Secured("ROLE_ADMIN_ADMIN")
+	@Override
+	@Query("{'_class': 'Setting'}")
+	List<Setting> findAll();
 
 	Optional<Setting> findOneByName(String name);
+
+	@Query("{'_class': ?0}")
+	<T> Stream<T> findByType(String typeName, Class<T> clazz);
 }
diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingService.java b/src/main/java/de/ozgcloud/admin/setting/SettingService.java
index 51b8529add8a7e42cb367f1fc6b4a062f8eaa4cb..aa9c8e2d7eea1a4eadf373331b4c369578968218 100644
--- a/src/main/java/de/ozgcloud/admin/setting/SettingService.java
+++ b/src/main/java/de/ozgcloud/admin/setting/SettingService.java
@@ -23,11 +23,25 @@
  */
 package de.ozgcloud.admin.setting;
 
+import static de.ozgcloud.admin.setting.SettingConstants.*;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jakarta.annotation.PostConstruct;
 
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.beans.factory.ListableBeanFactory;
 import org.springframework.stereotype.Service;
 
+import static java.util.stream.Collectors.*;
+
+import de.ozgcloud.admin.common.DtoService;
+import de.ozgcloud.admin.common.SettingDtoService;
 import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitSettings;
 import de.ozgcloud.admin.setting.postfach.PostfachSettingBody;
 import lombok.RequiredArgsConstructor;
@@ -41,6 +55,22 @@ class SettingService {
 	private final SettingRepository repository;
 
 	private final SettingMapper mapper;
+	private final ListableBeanFactory beanFactory;
+
+	private Map<String, List<SettingDtoService>> dtoServiceByManager;
+
+	@PostConstruct
+	void initDtoServices() {
+		this.dtoServiceByManager = beanFactory.getBeansWithAnnotation(DtoService.class).values().stream()
+				.map(SettingDtoService.class::cast)
+				.flatMap(this::getManagerForService)
+				.collect(Collectors.groupingBy(Pair::getKey, mapping(Pair::getValue, toList())));
+	}
+
+	private Stream<Pair<String, SettingDtoService>> getManagerForService(SettingDtoService dtoService) {
+		var annotation = dtoService.getClass().getDeclaredAnnotation(DtoService.class);
+		return Arrays.stream(annotation.value()).map(manager -> Pair.of(manager, dtoService));
+	}
 
 	public AlfaSettingDTO getAlfaSettingDTO() {
 		var postfachData = getSettingWithPostfachFromDb();
@@ -75,4 +105,20 @@ class SettingService {
 				OrganisationsEinheitWithSettings::organisationsEinheitId,
 				OrganisationsEinheitWithSettings::settings));
 	}
+
+	public ApplicationSettingDTO getAggregationManagerSettingDto() {
+		return MapBasedApplicationSettingDto.builder()
+				.settings(buildSettingsMap(AGGREGATION_MANAGER))
+				.build();
+	}
+
+	private Map<String, Object> buildSettingsMap(String managerName) {
+		return getDtoService(managerName).stream()
+				.collect(Collectors.toMap(SettingDtoService::getSettingKeyName, SettingDtoService::getDataTransferObject));
+	}
+
+	private List<SettingDtoService> getDtoService(String managerName) {
+		return dtoServiceByManager.getOrDefault(managerName, Collections.emptyList());
+	}
+
 }
diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml
index c5bb57b37de68a6c4b610d764df4023e48e248f4..7faeb3acc343d6320c0c77fcfcd3da7aca6dffbb 100644
--- a/src/main/resources/application-local.yaml
+++ b/src/main/resources/application-local.yaml
@@ -1,3 +1,6 @@
+logging:
+  config: classpath:log4j2-local.xml
+
 spring:
   data:
     mongodb:
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index f4a4954da71dc34a7be41330ce9d37169793c969..0ff2d17a8b35216926b5e4f4732c8d30fba13146 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -21,9 +21,27 @@
 # unter der Lizenz sind dem Lizenztext zu entnehmen.
 logging:
   level:
-    ROOT: INFO
+    ROOT: WARN
     '[de.ozgcloud]': INFO
 
+spring:
+  application:
+    name: OzgCloud_Administration
+  data:
+    mongodb:
+      authentication-database: admin
+    rest:
+      basePath: /api/configuration
+  cloud:
+    config:
+      server:
+        prefix: /configserver
+  security:
+    oauth2:
+      resourceserver:
+        jwt:
+          issuer-uri: ${ozgcloud.oauth2.auth-server-url}/realms/${ozgcloud.oauth2.realm}
+
 management:
   server:
     port: 8081
@@ -55,23 +73,7 @@ mongock:
     - de.ozgcloud.admin.migration
   enabled: true
 
-spring:
-  application:
-    name: OzgCloud_Administration
-  data:
-    mongodb:
-      authentication-database: admin
-    rest:
-      basePath: /api/configuration
-  cloud:
-    config:
-      server:
-        prefix: /configserver
-  security:
-    oauth2:
-      resourceserver:
-        jwt:
-          issuer-uri: ${ozgcloud.oauth2.auth-server-url}/realms/${ozgcloud.oauth2.realm}
+
 
 ozgcloud:
   keycloak:
diff --git a/src/test/java/de/ozgcloud/admin/AdministrationRepositoryRestConfigurerTest.java b/src/test/java/de/ozgcloud/admin/AdministrationRepositoryRestConfigurerTest.java
deleted file mode 100644
index a45fc711558b6073f96283db4ce04e98ad691077..0000000000000000000000000000000000000000
--- a/src/test/java/de/ozgcloud/admin/AdministrationRepositoryRestConfigurerTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin;
-
-import static org.assertj.core.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.InjectMocks;
-import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
-import org.springframework.hateoas.server.LinkRelationProvider;
-import org.springframework.hateoas.server.core.DefaultLinkRelationProvider;
-
-class AdministrationRepositoryRestConfigurerTest {
-
-	@InjectMocks
-	private AdministrationRepositoryRestConfigurer configurer;
-
-	@Nested
-	class TestConfigureRepositoryRestConfiguration {
-
-		@Captor
-		private ArgumentCaptor<LinkRelationProvider> linkRelationProviderArgumentCaptor;
-
-		@Test
-		void shouldUseDefaultLinkRelationProvider() {
-			var configuration = mock(RepositoryRestConfiguration.class);
-
-			configurer.configureRepositoryRestConfiguration(configuration, null);
-
-			verify(configuration).setLinkRelationProvider(linkRelationProviderArgumentCaptor.capture());
-			assertThat(linkRelationProviderArgumentCaptor.getValue()).isInstanceOf(DefaultLinkRelationProvider.class);
-		}
-	}
-
-}
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/admin/OzgCloudDelegatingResourceMetadataTest.java b/src/test/java/de/ozgcloud/admin/OzgCloudDelegatingResourceMetadataTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..12253c9025542a549059c4979f7cbc458c151c36
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/OzgCloudDelegatingResourceMetadataTest.java
@@ -0,0 +1,152 @@
+package de.ozgcloud.admin;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Optional;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.repository.support.Repositories;
+import org.springframework.data.rest.core.mapping.ResourceMetadata;
+import org.springframework.security.authorization.AuthorizationDecision;
+import org.springframework.security.authorization.method.SecuredAuthorizationManager;
+
+import de.ozgcloud.admin.OzgCloudDelegatingRepositoryResourceMappings.OzgCloudDelegatingResourceMetadata;
+import de.ozgcloud.common.test.ReflectionTestUtils;
+
+class OzgCloudDelegatingResourceMetadataTest {
+
+	@Spy
+	@InjectMocks
+	private OzgCloudDelegatingResourceMetadata delegatingResourceMetadata;
+
+	@Mock
+	private ResourceMetadata metadata;
+	@Mock
+	private Repositories repositories;
+	@Mock
+	private SecuredAuthorizationManager authManager;
+
+	@Nested
+	class TestIsExported {
+
+		@Test
+		void shouldReturnTrue() {
+			when(metadata.isExported()).thenReturn(true);
+			doReturn(true).when(delegatingResourceMetadata).isAccessPermitted(any());
+
+			var result = delegatingResourceMetadata.isExported();
+
+			assertThat(result).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalseIfNotPermitted() {
+			doReturn(false).when(delegatingResourceMetadata).isAccessPermitted(any());
+
+			var result = delegatingResourceMetadata.isExported();
+
+			assertThat(result).isFalse();
+		}
+
+		@Test
+		void shouldReturnFalseIfNotExported() {
+			doReturn(true).when(delegatingResourceMetadata).isAccessPermitted(any());
+			when(metadata.isExported()).thenReturn(false);
+
+			var result = delegatingResourceMetadata.isExported();
+
+			assertThat(result).isFalse();
+		}
+	}
+
+	@Nested
+	class TestIsAccessPermitted {
+		@Mock
+		private Object repository;
+		@Mock
+		private AuthorizationDecision decision;
+
+		private final MethodInvocation invocation = Mockito.mock(MethodInvocation.class);
+
+		@BeforeEach
+		void initMock() {
+			when(repositories.getRepositoryFor(any())).thenReturn(Optional.of(repository));
+
+			doReturn(invocation).when(delegatingResourceMetadata).getFindAllInvocation(any());
+		}
+
+		@BeforeEach
+		void mockAuthManager() {
+			when(authManager.check(any(), any())).thenReturn(decision);
+
+			ReflectionTestUtils.setField(delegatingResourceMetadata, "authManager", authManager);
+		}
+
+		@Test
+		void shouldCallDecisionManager() {
+			delegatingResourceMetadata.isAccessPermitted(Object.class);
+
+			verify(decision).isGranted();
+		}
+
+		@Test
+		void shouldReturnTrueIfGranted() {
+			when(decision.isGranted()).thenReturn(true);
+
+			var result = delegatingResourceMetadata.isAccessPermitted(any());
+
+			assertThat(result).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalseIfNotGranted() {
+			when(decision.isGranted()).thenReturn(false);
+
+			var result = delegatingResourceMetadata.isAccessPermitted(any());
+
+			assertThat(result).isFalse();
+		}
+
+		@Test
+		void shouldCallAuthManager() {
+			delegatingResourceMetadata.isAccessPermitted(Object.class);
+
+			verify(authManager).check(any(), eq(invocation));
+		}
+
+		@Test
+		void shouldReturnTrueIfNotSecured() {
+			when(authManager.check(any(), any())).thenReturn(null);
+
+			var result = delegatingResourceMetadata.isAccessPermitted(any());
+
+			assertThat(result).isTrue();
+		}
+	}
+
+	@Nested
+	class TestGetFindAllInvocation {
+
+		@Mock
+		private MongoRepository<String, Object> repository;
+
+		@Test
+		void shouldReturnMethod() {
+			var method = delegatingResourceMetadata.getFindAllInvocation(repository);
+
+			assertThat(method).isNotNull()
+					.extracting(invocation -> invocation.getMethod().getName()).isEqualTo("findAll");
+		}
+	}
+
+}
diff --git a/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java
index 0427eb6fbed96cef7143a875cb42d6510654c6ce..5c4ed0d6bc38bf1c40399d0fad93cc488644b05d 100644
--- a/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java
+++ b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java
@@ -39,9 +39,6 @@ import org.mockito.Spy;
 import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties;
 import org.springframework.hateoas.Link;
 
-import de.ozgcloud.admin.common.user.CurrentUserService;
-import de.ozgcloud.admin.common.user.UserRole;
-
 class RootModelAssemblerTest {
 
 	private static final String BASE_PATH = "/api/base";
@@ -51,15 +48,12 @@ class RootModelAssemblerTest {
 
 	@Mock
 	private RepositoryRestProperties restProperties;
-	@Mock
-	private CurrentUserService currentUserService;
 
 	@DisplayName("Entity Model")
 	@Nested
 	class TestEntityModel {
 		@BeforeEach
 		void beforeEach() {
-			Mockito.when(currentUserService.hasRole(UserRole.ADMIN_ADMIN)).thenReturn(true);
 			Mockito.when(restProperties.getBasePath()).thenReturn(BASE_PATH);
 		}
 
@@ -92,7 +86,6 @@ class RootModelAssemblerTest {
 		@Test
 		void shouldHaveHrefToBasePathIfAuthorized() {
 			Mockito.when(restProperties.getBasePath()).thenReturn(BASE_PATH);
-			Mockito.when(currentUserService.hasRole(UserRole.ADMIN_ADMIN)).thenReturn(true);
 
 			List<Link> links = modelAssembler.buildRootModelLinks();
 
@@ -101,15 +94,6 @@ class RootModelAssemblerTest {
 					Link.of(BASE_PATH, REL_CONFIGURATION));
 		}
 
-		@Test
-		void shouldNotHaveHrefToBasePathIfUnauthorized() {
-			Mockito.when(currentUserService.hasRole(UserRole.ADMIN_ADMIN)).thenReturn(false);
-
-			List<Link> links = modelAssembler.buildRootModelLinks();
-
-			assertThat(links).containsExactly(
-					Link.of(RootController.PATH));
-		}
 	}
 
 }
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/admin/common/CollectionModelBuilderTest.java b/src/test/java/de/ozgcloud/admin/common/CollectionModelBuilderTest.java
deleted file mode 100644
index 8327c18845e9ead36fc76bfff226334adac98881..0000000000000000000000000000000000000000
--- a/src/test/java/de/ozgcloud/admin/common/CollectionModelBuilderTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import static org.assertj.core.api.Assertions.*;
-
-import java.util.List;
-import java.util.stream.Stream;
-
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.springframework.hateoas.Link;
-
-import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheit;
-import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitTestFactory;
-
-class CollectionModelBuilderTest {
-
-	private final String HREF = "http://test";
-	private final String REL = "rel";
-
-	@Nested
-	class TestBuildModel {
-
-		@Test
-		void shouldBuildModel() {
-			var vorgang = OrganisationsEinheitTestFactory.create();
-
-			var model = CollectionModelBuilder.fromEntities(List.of(vorgang)).buildModel();
-
-			assertThat(model.getContent()).hasSize(1).first().usingRecursiveComparison().isEqualTo(vorgang);
-		}
-	}
-
-	@Nested
-	class TestAddLink {
-
-		@Test
-		void shouldAddLink() {
-			var model = CollectionModelBuilder.fromEntities(List.of()).addLink(Link.of(HREF, REL)).buildModel();
-
-			assertThat(model.getLinks()).hasSize(1).first().extracting(Link::getHref, link -> link.getRel().value()).containsExactly(HREF, REL);
-		}
-	}
-
-	@Nested
-	class TestIfMatch {
-
-		@Nested
-		class TestWithBooleanSupplier {
-
-			@Test
-			void shouldAddLink() {
-				var model = CollectionModelBuilder.fromEntities(List.of()).ifMatch(() -> true).addLink(Link.of(HREF, REL)).buildModel();
-
-				assertThat(model.getLinks()).hasSize(1).first().extracting(Link::getHref, link -> link.getRel().value()).containsExactly(HREF, REL);
-			}
-
-			@Test
-			void shouldNotAddLink() {
-				var model = CollectionModelBuilder.fromEntities(List.of()).ifMatch(() -> false).addLink(Link.of(HREF, REL)).buildModel();
-
-				assertThat(model.getLinks()).isEmpty();
-			}
-		}
-
-		@Nested
-		class TestWithPredicate {
-
-			private final Stream<OrganisationsEinheit> wiedervorlageStream = Stream.of(OrganisationsEinheitTestFactory.create());
-
-			@Test
-			void shouldAddLink() {
-				var model = CollectionModelBuilder.fromEntities(wiedervorlageStream)
-						.ifMatch(wiedervorlagen -> true)
-						.addLink(Link.of(HREF, REL))
-						.buildModel();
-
-				assertThat(model.getLinks()).hasSize(1).first().extracting(Link::getHref, link -> link.getRel().value()).containsExactly(HREF, REL);
-			}
-
-			@Test
-			void shouldNotAddLink() {
-				var model = CollectionModelBuilder.fromEntities(wiedervorlageStream)
-						.ifMatch(wiedervorlagen -> false)
-						.addLink(Link.of(HREF, REL))
-						.buildModel();
-
-				assertThat(model.getLinks()).isEmpty();
-			}
-		}
-	}
-
-}
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/admin/common/IdBuilderTest.java b/src/test/java/de/ozgcloud/admin/common/IdBuilderTest.java
deleted file mode 100644
index 608fe7e6e3607c04bdcedca85b29238bd840db66..0000000000000000000000000000000000000000
--- a/src/test/java/de/ozgcloud/admin/common/IdBuilderTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import static org.assertj.core.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import com.fasterxml.jackson.databind.BeanProperty;
-
-class IdBuilderTest {
-
-	@DisplayName("Test building ID when deserializing linked resources")
-	@Nested
-	class TestBuilingId {
-		private static final String ID = "id";
-
-		@Test
-		void shouldBuildId() {
-			IdBuilder idBuilder = new IdBuilder();
-
-			var idObject = idBuilder.build(ID);
-
-			assertThat(idObject).isInstanceOf(Object.class).asString().isEqualTo(ID);
-		}
-
-		@Test
-		void shouldCreateObjectBuilder() {
-			BeanProperty property = mock(BeanProperty.class);
-			ObjectBuilder<Object> idBuilder = new IdBuilder().constructContextAware(property);
-
-			assertThat(idBuilder).isNotNull();
-		}
-	}
-}
diff --git a/src/test/java/de/ozgcloud/admin/common/LinkedResourceDeserializerTest.java b/src/test/java/de/ozgcloud/admin/common/LinkedResourceDeserializerTest.java
deleted file mode 100644
index 57b29873233059f02882fe1b56c5f4079f57c792..0000000000000000000000000000000000000000
--- a/src/test/java/de/ozgcloud/admin/common/LinkedResourceDeserializerTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import static org.assertj.core.api.Assertions.*;
-
-import java.io.IOException;
-
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import com.fasterxml.jackson.core.exc.StreamReadException;
-import com.fasterxml.jackson.databind.DatabindException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import de.ozgcloud.admin.common.user.TestId;
-import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitTestFactory;
-
-class LinkedResourceDeserializerTest {
-	private static final String TEST_JSON = "{\"id\":\"/api/vorgangs/" + OrganisationsEinheitTestFactory.ID + "\"}";
-
-	@DisplayName("Test the deserilization of linked resource json")
-	@Nested
-	class TestDeserialization {
-		@Test
-		void shouldDeserialize() throws IOException {
-			LinkedResourceTestObject res = new ObjectMapper().readValue(TEST_JSON.getBytes(), LinkedResourceTestObject.class);
-
-			assertThat(res).hasFieldOrPropertyWithValue("id", TestId.from(OrganisationsEinheitTestFactory.ID));
-		}
-
-	}
-
-}
diff --git a/src/test/java/de/ozgcloud/admin/common/LinkedResourceSerializerTest.java b/src/test/java/de/ozgcloud/admin/common/LinkedResourceSerializerTest.java
deleted file mode 100644
index 05764d09b88e72edd2032e861bbc58cd863a36c9..0000000000000000000000000000000000000000
--- a/src/test/java/de/ozgcloud/admin/common/LinkedResourceSerializerTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import static org.assertj.core.api.Assertions.*;
-
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import de.ozgcloud.admin.common.user.TestId;
-import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitTestFactory;
-
-class LinkedResourceSerializerTest {
-
-	@DisplayName("Test the json serialization of linked resource annotations")
-	@Nested
-	class TestSerialization {
-		@Test
-		void shouldSerialize() throws JsonProcessingException {
-			var testObj = new LinkedResourceTestObject(TestId.from(OrganisationsEinheitTestFactory.ID));
-
-			String serialized = new ObjectMapper().writeValueAsString(testObj);
-
-			assertThat(serialized).isEqualTo("{\"id\":\"/api/organisationseinheits/" + OrganisationsEinheitTestFactory.ID + "\"}");
-		}
-
-	}
-}
diff --git a/src/test/java/de/ozgcloud/admin/common/ModelBuilderTest.java b/src/test/java/de/ozgcloud/admin/common/ModelBuilderTest.java
deleted file mode 100644
index eaaf4500527625ff9707498335e93fb6bc6210a3..0000000000000000000000000000000000000000
--- a/src/test/java/de/ozgcloud/admin/common/ModelBuilderTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2024 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.ozgcloud.admin.common;
-
-import static org.assertj.core.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
-import java.util.UUID;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.NullAndEmptySource;
-import org.mockito.Mock;
-import org.springframework.context.ApplicationContext;
-import org.springframework.core.env.Environment;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import lombok.Builder;
-
-class ModelBuilderTest {
-
-	@DisplayName("Add link by annotation if missing")
-	@Nested
-	class TestAddLinkByAnnotationIfMissing {
-
-		private static final String USER_MANAGER_URL = "http://localhost";
-		private static final String USER_MANAGER_PROFILE_TEMPLATE = "/api/profile/%s";
-
-		@Mock
-		private ApplicationContext context;
-
-		private TestEntity entity = TestEntityTestFactory.create();
-
-		@Test
-		void shouldHaveAddLinkByLinkedResource() {
-			var model = ModelBuilder.fromEntity(entity).buildModel();
-
-			assertThat(model.getLink(TestController.FILE_REL).get().getHref()).isEqualTo(TestController.PATH + "/" + TestEntityTestFactory.FILE);
-		}
-
-		@ParameterizedTest
-		@NullAndEmptySource
-		void shouldNotAddLinkByLinkedRessourceIfFieldValueIsNotSet(String fileId) {
-			var model = ModelBuilder.fromEntity(TestEntityTestFactory.createBuilder().file(fileId).build()).buildModel();
-
-			assertThat(model.getLink(TestController.FILE_REL)).isEmpty();
-		}
-	}
-}
-
-@Builder
-class TestEntity {
-
-	@LinkedResource(controllerClass = TestController.class)
-	private String file;
-}
-
-@RequestMapping(TestController.PATH)
-class TestController {
-
-	static final String PATH = "/api/test";
-
-	static final String USER_REL = "user";
-	static final String FILE_REL = "file";
-
-}
-
-class TestEntityTestFactory {
-
-	static final String USER = UUID.randomUUID().toString();
-	static final String FILE = UUID.randomUUID().toString();
-
-	public static TestEntity create() {
-		return createBuilder().build();
-	}
-
-	public static TestEntity.TestEntityBuilder createBuilder() {
-		return TestEntity.builder()
-				.file(FILE);
-	}
-}
diff --git a/src/test/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessorITCase.java b/src/test/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessorITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..52b0d04414085b50de8397ba2db9d32838c20765
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessorITCase.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.keycloak;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+
+import de.ozgcloud.common.test.ITCase;
+
+class KeyCloakRootProcessorITCase {
+
+	@Nested
+	@SpringBootTest(properties = {
+			"ozgcloud.feature.benutzer-rollen=true"
+	})
+	@ITCase
+	class TestFeatureEnabled {
+
+		@Autowired
+		private ApplicationContext applicationContext;
+
+		@Test
+		void shouldHaveKeyCloakRootProcessorBean() {
+			assertDoesNotThrow(() -> applicationContext.getBean(KeyCloakRootProcessor.class));
+		}
+	}
+
+	@Nested
+	@SpringBootTest(properties = {
+			"ozgcloud.feature.benutzer-rollen=false"
+	})
+	@ITCase
+	class TestFeatureDisabled {
+
+		@Autowired
+		private ApplicationContext applicationContext;
+
+		@Test
+		void shouldHaveKeyCloakRootProcessorBean() {
+			assertThrows(NoSuchBeanDefinitionException.class, () -> applicationContext.getBean(KeyCloakRootProcessor.class));
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessorTest.java b/src/test/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..604e2281fe3b99b0f976988221f7b0d57bb2afe1
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/keycloak/KeyCloakRootProcessorTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.keycloak;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.Link;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.admin.Root;
+import de.ozgcloud.admin.RootTestFactory;
+import de.ozgcloud.admin.common.user.CurrentUserService;
+import de.ozgcloud.admin.common.user.UserRole;
+
+class KeyCloakRootProcessorTest {
+
+	@InjectMocks
+	@Spy
+	private KeyCloakRootProcessor processor;
+	@Mock
+	private CurrentUserService currentUserService;
+	@Mock
+	private KeycloakApiProperties keycloakApiProperties;
+
+	@Nested
+	class TestProcess {
+		private final String href = LoremIpsum.getInstance().getUrl();
+
+		@Test
+		void shouldCheckUserRole() {
+			processModel();
+
+			verify(currentUserService).hasRole(UserRole.ADMIN_ADMIN);
+		}
+
+		@Nested
+		class TestOnAdminRole {
+
+			@BeforeEach
+			void givenHasAdminRole() {
+				when(currentUserService.hasRole(anyString())).thenReturn(true);
+				doReturn(href).when(processor).buildUsersHref();
+			}
+
+			@Test
+			void shouldCallBuildUsersHref() {
+				processModel();
+
+				verify(processor).buildUsersHref();
+			}
+
+			@Test
+			void shouldAddUsersLink() {
+				var model = processModel();
+
+				assertThat(model.getLink(KeyCloakRootProcessor.REL_USERS)).isNotEmpty();
+			}
+
+			@Test
+			void shouldSetHref() {
+				var model = processModel();
+
+				assertThat(model.getLink(KeyCloakRootProcessor.REL_USERS))
+						.get()
+						.extracting(Link::getHref)
+						.isEqualTo(href);
+			}
+		}
+
+		@Nested
+		class TestOnWrongUserRole {
+
+			@BeforeEach
+			void givenHasWrongRole() {
+				when(currentUserService.hasRole(anyString())).thenReturn(false);
+			}
+
+			@Test
+			void shouldNotAddAnyLinks() {
+				var model = processModel();
+
+				assertThat(model.getLinks()).isEmpty();
+			}
+		}
+
+		private EntityModel<Root> processModel() {
+			return processor.process(EntityModel.of(RootTestFactory.create()));
+		}
+	}
+
+	@Nested
+	class TestBuildUsersHref {
+		private final String baseUrl = "https://keycloak.domain.de";
+		private final String realm = LoremIpsum.getInstance().getWords(1);
+
+		@BeforeEach
+		void mockProperties() {
+			when(keycloakApiProperties.getUrl()).thenReturn(baseUrl);
+			when(keycloakApiProperties.getRealm()).thenReturn(realm);
+		}
+
+		@Test
+		void shouldGetKeyCloakUrl() {
+			processor.buildUsersHref();
+
+			verify(keycloakApiProperties).getUrl();
+		}
+
+		@Test
+		void shouldGetKeyCloakRealm() {
+			processor.buildUsersHref();
+
+			verify(keycloakApiProperties).getRealm();
+		}
+
+		@Test
+		void shouldReturnApiEndpoint() {
+			var uriString = processor.buildUsersHref();
+
+			assertThat(uriString).isEqualTo(baseUrl + "/admin/realms/" + realm + "/users");
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java b/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java
index dc560c4ed05543fb219f0d6e98376dbbe6c977e8..8f121650c6aa2d05a7904a7d2097996a91bfb793 100644
--- a/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java
+++ b/src/test/java/de/ozgcloud/admin/keycloak/KeycloakApiServiceITCase.java
@@ -29,6 +29,7 @@ import static org.assertj.core.groups.Tuple.tuple;
 import java.util.List;
 import java.util.Optional;
 
+import org.assertj.core.api.InstanceOfAssertFactories;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.keycloak.representations.idm.GroupRepresentation;
@@ -122,9 +123,9 @@ class KeycloakApiServiceITCase {
 
 		private String getOrganisationsEinheitId(GroupRepresentation group) {
 			var attributes = group.getAttributes();
-			return attributes.containsKey(properties.getOrganisationsEinheitIdKey()) ?
-					attributes.get(properties.getOrganisationsEinheitIdKey()).getFirst() :
-					null;
+			return attributes.containsKey(properties.getOrganisationsEinheitIdKey())
+					? attributes.get(properties.getOrganisationsEinheitIdKey()).getFirst()
+					: null;
 		}
 	}
 
@@ -175,7 +176,7 @@ class KeycloakApiServiceITCase {
 			var groupId = service.addGroup(groupToAdd);
 
 			assertThat(findGroupInKeycloak(groupId)).isPresent().get().extracting(GroupRepresentation::getSubGroups)
-					.asList().isEmpty();
+					.asInstanceOf(InstanceOfAssertFactories.LIST).isEmpty();
 		}
 
 		private GroupRepresentation createUniqueGroupRepresentation(String nameSuffix) {
diff --git a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitITCase.java b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitITCase.java
index 8483a40cc9f385ecc6c48cbcb1a57a58ac89ed60..6d136531fc4b9de0489a0a69a8ec2232a987ba12 100644
--- a/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitITCase.java
+++ b/src/test/java/de/ozgcloud/admin/organisationseinheit/OrganisationsEinheitITCase.java
@@ -25,7 +25,6 @@ package de.ozgcloud.admin.organisationseinheit;
 
 import static org.mockito.Mockito.*;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
 
 import java.util.List;
@@ -82,22 +81,22 @@ class OrganisationsEinheitITCase {
 		void shouldContainList() {
 			var response = mockMvc.perform(get(PATH)).andExpect(status().isOk());
 
-			response.andDo(print()).andExpect(jsonPath("$._embedded.organisationsEinheitList").isNotEmpty());
+			response.andExpect(jsonPath("$._embedded.organisationsEinheits").isNotEmpty());
 		}
 
 		@SneakyThrows
 		@Test
 		void shouldContainOrganisationsEinheit() {
 			mockMvc.perform(get(PATH))
-					.andExpect(jsonPath("$._embedded.organisationsEinheitList[0].name").value(OrganisationsEinheitTestFactory.NAME))
-					.andExpect(jsonPath("$._embedded.organisationsEinheitList[0].organisationsEinheitId").value(
+					.andExpect(jsonPath("$._embedded.organisationsEinheits[0].name").value(OrganisationsEinheitTestFactory.NAME))
+					.andExpect(jsonPath("$._embedded.organisationsEinheits[0].organisationsEinheitId").value(
 							OrganisationsEinheitTestFactory.ORGANISATIONS_EINHEIT_ID))
 					.andExpect(
-							jsonPath("$._embedded.organisationsEinheitList[0].syncResult").value(OrganisationsEinheitTestFactory.SYNC_RESULT.name()))
-					.andExpect(jsonPath("$._embedded.organisationsEinheitList[0].zufiId").doesNotExist())
-					.andExpect(jsonPath("$._embedded.organisationsEinheitList[0].parentId").doesNotExist())
-					.andExpect(jsonPath("$._embedded.organisationsEinheitList[0].keycloakId").doesNotExist())
-					.andExpect(jsonPath("$._embedded.organisationsEinheitList[0].id").doesNotExist());
+							jsonPath("$._embedded.organisationsEinheits[0].syncResult").value(OrganisationsEinheitTestFactory.SYNC_RESULT.name()))
+					.andExpect(jsonPath("$._embedded.organisationsEinheits[0].zufiId").doesNotExist())
+					.andExpect(jsonPath("$._embedded.organisationsEinheits[0].parentId").doesNotExist())
+					.andExpect(jsonPath("$._embedded.organisationsEinheits[0].keycloakId").doesNotExist())
+					.andExpect(jsonPath("$._embedded.organisationsEinheits[0].id").doesNotExist());
 		}
 	}
 
diff --git a/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingDtoTestFactory.java b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingDtoTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..f0c601d43a316e0456cd6b73acd012535d1d6033
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingDtoTestFactory.java
@@ -0,0 +1,22 @@
+package de.ozgcloud.admin.reporting;
+
+import static de.ozgcloud.admin.reporting.AggregationMappingTestFactory.*;
+
+import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.AggregationMappingDto;
+import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.FieldMappingDto;
+import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.FormIdentifierDto;
+
+public class AggregationMappingDtoTestFactory {
+
+	public static final FormIdentifierDto FORM_IDENTIFIER = FormIdentifierDto.builder().formId(FORM_ID).formEngineName(FORM_ENGINE_NAME).build();
+
+	public static AggregationMappingDto create() {
+		return createBuilder().build();
+	}
+
+	public static AggregationMappingDto.AggregationMappingDtoBuilder createBuilder() {
+		return AggregationMappingDto.builder()
+				.formIdentifier(FORM_IDENTIFIER)
+				.fieldMapping(FieldMappingDto.builder().sourcePath(SOURCE_PATH).targetPath(TARGET_PATH).build());
+	}
+}
diff --git a/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingMapperTest.java b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingMapperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f98c2ede8306f10acc1d5fd7e75c7da9b0662cd
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingMapperTest.java
@@ -0,0 +1,26 @@
+package de.ozgcloud.admin.reporting;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mapstruct.factory.Mappers;
+import org.mockito.InjectMocks;
+
+class AggregationMappingMapperTest {
+
+	@InjectMocks
+	private AggregationMappingMapper mapper = Mappers.getMapper(AggregationMappingMapper.class);
+
+	@Nested
+	class TestToMapping {
+
+		@Test
+		void shouldMapToDto() {
+			var dto = mapper.toMapping(AggregationMappingTestFactory.create());
+
+			assertThat(dto).usingRecursiveComparison().isEqualTo(AggregationMappingDtoTestFactory.create());
+		}
+	}
+
+}
diff --git a/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingRepositoryITCase.java b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingRepositoryITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..a92bcc6b3e210f27a066f54f3dc28db551f45086
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingRepositoryITCase.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.reporting;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.security.authorization.AuthorizationDeniedException;
+import org.springframework.security.test.context.support.WithMockUser;
+
+import de.ozgcloud.admin.common.user.UserRole;
+import de.ozgcloud.admin.setting.SettingTestFactory;
+import de.ozgcloud.common.test.DataITCase;
+
+@DataITCase
+class AggregationMappingRepositoryITCase {
+
+	@Autowired
+	private AggregationMappingRepository repository;
+
+	@Autowired
+	private MongoOperations operations;
+
+	@BeforeEach
+	void dropCollection() {
+		operations.dropCollection("settings");
+	}
+
+	@Test
+	@WithMockUser(roles = UserRole.DATENBEAUFTRAGUNG)
+	void shouldLoadOnlyFieldMapping() {
+		operations.save(AggregationMappingTestFactory.create());
+		operations.save(SettingTestFactory.create());
+
+		var result = repository.findAll();
+
+		assertThat(result).hasSize(1);
+	}
+
+	@Test
+	@WithMockUser
+	void shouldThrowExceptionOnMissingRole() {
+		operations.save(AggregationMappingTestFactory.create());
+
+		assertThatThrownBy(() -> repository.findAll()).isInstanceOf(AuthorizationDeniedException.class);
+	}
+
+}
diff --git a/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingTestFactory.java b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d41bec21628058b6a5f84ef2858746b1b348d26
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingTestFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.reporting;
+
+import java.util.UUID;
+
+import de.ozgcloud.admin.reporting.AggregationMapping.FieldMapping;
+import de.ozgcloud.admin.reporting.AggregationMapping.FormIdentifier;
+
+public class AggregationMappingTestFactory {
+
+	public static final String ID = UUID.randomUUID().toString();
+	public static final String FORM_ENGINE_NAME = "A12";
+	public static final String FORM_ID = "42";
+
+	public static final String SOURCE_PATH = "name";
+	public static final String TARGET_PATH = "antragsteller.name";
+
+	public static AggregationMapping create() {
+		return createBuilder().build();
+	}
+
+	public static AggregationMapping.AggregationMappingBuilder createBuilder() {
+		return AggregationMapping.builder()
+				.id(UUID.randomUUID().toString())
+				.formIdentifier(FormIdentifier.builder()
+						.formEngineName(FORM_ENGINE_NAME)
+						.formId(FORM_ID)
+						.build())
+				.mapping(FieldMapping.builder().sourcePath(SOURCE_PATH).targetPath(TARGET_PATH).build());
+	}
+
+}
diff --git a/src/main/java/de/ozgcloud/admin/common/IdBuilder.java b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationMAnagerSettingDtoTestFactory.java
similarity index 64%
rename from src/main/java/de/ozgcloud/admin/common/IdBuilder.java
rename to src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationMAnagerSettingDtoTestFactory.java
index f893795312adcde8c17d1c0da58cf1eaa4e5cf26..27dc2735fa90521e76642ad8eda61e74c308db75 100644
--- a/src/main/java/de/ozgcloud/admin/common/IdBuilder.java
+++ b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationMAnagerSettingDtoTestFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -21,22 +21,17 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.common;
+package de.ozgcloud.admin.reporting;
 
-import com.fasterxml.jackson.databind.BeanProperty;
+class ReportingAggregationMAnagerSettingDtoTestFactory {
 
-import lombok.NoArgsConstructor;
-
-@NoArgsConstructor
-class IdBuilder implements ObjectBuilder<Object> {
-
-	@Override
-	public Object build(Object id) {
-		return id;
+	public static ReportingAggregationManagerSettingDto create() {
+		return createBuilder().build();
 	}
 
-	@Override
-	public ObjectBuilder<Object> constructContextAware(BeanProperty property) {
-		return new IdBuilder();
+	public static ReportingAggregationManagerSettingDto.ReportingAggregationManagerSettingDtoBuilder createBuilder() {
+		return ReportingAggregationManagerSettingDto.builder()
+				.aggregationMapping(AggregationMappingDtoTestFactory.create());
 	}
+
 }
diff --git a/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoServiceTest.java b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..38b5d5e310295cecf06d3fd9d4ff723f14c00d54
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoServiceTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.reporting;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+import de.ozgcloud.admin.setting.SettingRepository;
+
+class ReportingAggregationManagerSettingDtoServiceTest {
+
+	@Spy
+	@InjectMocks
+	private ReportingAggregationManagerSettingDtoService service;
+
+	@Mock
+	private AggregationMappingMapper mapper;
+	@Mock
+	private SettingRepository repository;
+
+	@Nested
+	class TestMapToDto {
+
+		@BeforeEach
+		void setupMapperMock() {
+			when(mapper.toMapping(any())).thenReturn(AggregationMappingDtoTestFactory.create());
+		}
+
+		@Test
+		void shouldCallMapper() {
+			var mapping = AggregationMappingTestFactory.create();
+			service.mapToDto(Stream.of(mapping));
+
+			verify(mapper).toMapping(mapping);
+		}
+
+		@Test
+		void shouldBuildDto() {
+			var dto = service.mapToDto(Stream.of(AggregationMappingTestFactory.create()));
+
+			assertThat(dto).usingRecursiveComparison().isEqualTo(ReportingAggregationMAnagerSettingDtoTestFactory.create());
+		}
+	}
+
+	@Nested
+	class TestGetDataTransferObject {
+
+		@Captor
+		private ArgumentCaptor<Stream<AggregationMapping>> streamCaptor;
+
+		@BeforeEach
+		void disableMapToDtoFunction() {
+			doReturn(ReportingAggregationMAnagerSettingDtoTestFactory.create()).when(service).mapToDto(any());
+		}
+
+		@Test
+		void shouldCallRepository() {
+			service.getDataTransferObject();
+
+			verify(repository).findByType(AggregationMapping.TYPE_ALIAS, AggregationMapping.class);
+		}
+
+		@Test
+		void shouldCallMapToDto() {
+			AggregationMapping mapping = AggregationMappingTestFactory.create();
+			when(repository.findByType(any(), any())).thenReturn(Stream.of(mapping));
+
+			service.getDataTransferObject();
+
+			verify(service).mapToDto(streamCaptor.capture());
+			assertThat(streamCaptor.getValue()).contains(mapping);
+		}
+	}
+
+}
diff --git a/src/test/java/de/ozgcloud/admin/reporting/ReportingSettingITCase.java b/src/test/java/de/ozgcloud/admin/reporting/ReportingSettingITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f347868585a14067918bae7d96351cde99fb9e6
--- /dev/null
+++ b/src/test/java/de/ozgcloud/admin/reporting/ReportingSettingITCase.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2025 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.ozgcloud.admin.reporting;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.http.MediaType;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+
+import de.ozgcloud.admin.common.user.UserRole;
+import de.ozgcloud.common.test.DataITCase;
+import de.ozgcloud.common.test.TestUtils;
+import lombok.SneakyThrows;
+
+@AutoConfigureMockMvc
+@WithMockUser(roles = UserRole.DATENBEAUFTRAGUNG)
+@DataITCase
+class ReportingSettingITCase {
+
+	@Autowired
+	private MockMvc mockMvc;
+
+	@Autowired
+	private MongoOperations mongoOperations;
+
+	@BeforeEach
+	void clearDatabase() {
+		mongoOperations.dropCollection("settings");
+	}
+
+	@Test
+	@SneakyThrows
+	void shouldHaveLinkToAggregationMapping() {
+		mockMvc.perform(get("/api/configuration"))
+				.andExpect(status().is2xxSuccessful())
+				.andExpect(jsonPath("$._links.aggregationMappings").exists());
+	}
+
+	@Test
+	@SneakyThrows
+	@WithMockUser(roles = UserRole.ADMIN_ADMIN)
+	void shouldNotHaveLinkOnMissingRole() {
+		mockMvc.perform(get("/api/configuration"))
+				.andExpect(status().is2xxSuccessful())
+				.andExpect(jsonPath("$._links.aggregationMappings").doesNotExist());
+	}
+
+	@Test
+	@SneakyThrows
+	void shouldDenyWhileMissingFields() {
+		mockMvc.perform(post("/api/configuration/aggregationMappings").with(csrf())
+				.contentType(MediaType.APPLICATION_JSON).content("{}"))
+				.andExpect(status().isUnprocessableEntity());
+	}
+
+	@Disabled("is returning 500")
+	@Test
+	@SneakyThrows
+	@WithMockUser(roles = UserRole.ADMIN_ADMIN)
+	void shouldNotAllowAddingMapping() {
+		mockMvc.perform(post("/api/configuration/aggregationMappings").with(csrf())
+				.contentType(MediaType.APPLICATION_JSON).content(TestUtils.loadTextFile("reporting/request.json")))
+				.andExpect(status().is(403));
+	}
+
+	@Test
+	@SneakyThrows
+	void shouldAddAggregationMappings() {
+		mockMvc.perform(post("/api/configuration/aggregationMappings").with(csrf())
+				.contentType(MediaType.APPLICATION_JSON).content(TestUtils.loadTextFile("reporting/request.json")))
+				.andExpect(status().isCreated());
+
+		var collection = mongoOperations.getCollection("settings");
+		assertThat(collection.countDocuments()).isEqualTo(1);
+		var mapping = mongoOperations.findAll(AggregationMapping.class).getFirst();
+		assertThat(mapping).usingRecursiveComparison().ignoringFields("id").isEqualTo(AggregationMappingTestFactory.create());
+	}
+
+	@Test
+	@SneakyThrows
+	void shouldListReportings() {
+		mockMvc.perform(get("/api/configuration/aggregationMappings"))
+				.andExpect(status().is2xxSuccessful());
+	}
+
+}
diff --git a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java
index 00e842613b7e62c8d62236a7f589f5e4affe887d..f8a507f213af4b16ae613bfca2560f5422f35ce1 100644
--- a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java
+++ b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java
@@ -35,6 +35,7 @@ import org.junit.jupiter.params.provider.ValueSource;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.http.HttpStatus;
+import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.ResultActions;
 
@@ -137,15 +138,10 @@ class SecurityConfigurationITCase {
 	@DisplayName("with authentication")
 	@Nested
 	class TestWithAuthentication {
-		static final String CLAIMS = """
-				{
-				  "preferredUsername": "testUser",
-				  "scope": "openid testscope"
-				}""";
 
 		@Test
 		@SneakyThrows
-		@WithJwt(CLAIMS)
+		@WithMockUser
 		void shouldAllowApiEndpoint() {
 			var result = doPerformAuthenticated("/api");
 
@@ -154,8 +150,8 @@ class SecurityConfigurationITCase {
 
 		@Test
 		@SneakyThrows
-		@WithJwt(CLAIMS)
-		void shouldForbidSettingsEndpoint() {
+		@WithMockUser
+		void shouldForbidSettingsEndpointOnMissingRole() {
 			var result = doPerformAuthenticated("/api/configuration/settings");
 
 			result.andExpect(status().isForbidden());
@@ -163,7 +159,7 @@ class SecurityConfigurationITCase {
 
 		@Test
 		@SneakyThrows
-		@WithJwt(CLAIMS)
+		@WithMockUser
 		void shouldForbidConfigurationsEndpoint() {
 			var result = doPerformAuthenticated("/api/configuration");
 
@@ -180,17 +176,9 @@ class SecurityConfigurationITCase {
 	@Nested
 	class TestWithAdminRole {
 
-		static final String CLAIMS = """
-				{
-				  "preferredUsername": "testUser",
-				  "scope": "openid testscope",
-				  "resource_access": { "admin": { "roles": ["ADMIN_ADMIN"] } }
-				}""";
-
-
 		@Test
 		@SneakyThrows
-		@WithJwt(CLAIMS)
+		@WithMockUser(roles = "ADMIN_ADMIN")
 		void shouldAllowSettings() {
 			var result = mockMvc.perform(get("/api/configuration/settings"));
 
@@ -199,7 +187,7 @@ class SecurityConfigurationITCase {
 
 		@Test
 		@SneakyThrows
-		@WithJwt(CLAIMS)
+		@WithMockUser(roles = "ADMIN_ADMIN")
 		void shouldAllowConfiguration() {
 			var result = mockMvc.perform(get("/api/configuration"));
 
diff --git a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java
index df88ea5f503807b4b58878d8ced4e09eff353d79..c84999918e651d428abdb93d54e6dff5f0c7eb35 100644
--- a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java
+++ b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java
@@ -23,10 +23,10 @@
  */
 package de.ozgcloud.admin.security;
 
-import static de.ozgcloud.admin.security.JwtTestFactory.*;
 import static de.ozgcloud.admin.security.SecurityConfiguration.*;
 import static java.util.Collections.*;
 import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 import java.util.List;
@@ -77,9 +77,8 @@ class SecurityConfigurationTest {
 		@Test
 		void shouldUsePreferredUsername() {
 			var preferredName = LoremIpsum.getInstance().getName();
-			var jwtWithPreferredName = JwtTestFactory.createBuilder()
-					.claim(StandardClaimNames.PREFERRED_USERNAME, preferredName)
-					.build();
+			var jwtWithPreferredName = JwtTestFactory.createBuilder().claim(StandardClaimNames.PREFERRED_USERNAME,
+					preferredName).build();
 
 			var jwtAuthenticationConverter = securityConfiguration.jwtAuthenticationConverter();
 
@@ -109,8 +108,10 @@ class SecurityConfigurationTest {
 
 		@BeforeEach
 		void mock() {
-			var keycloakRoles = List.of(ROLE_1, JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3);
-			expectedSecurityRoleStrings = keycloakRoles.stream().map(role -> SIMPLE_GRANT_AUTHORITY_PREFIX + role).toList();
+			var keycloakRoles = List.of(JwtTestFactory.ROLE_1,
+					JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3);
+			expectedSecurityRoleStrings = keycloakRoles.stream().map(role -> SIMPLE_GRANT_AUTHORITY_PREFIX +
+					role).toList();
 			doReturn(keycloakRoles).when(securityConfiguration).getRolesFromJwt(any());
 		}
 
@@ -131,14 +132,14 @@ class SecurityConfigurationTest {
 
 			var grantedAuthorities = securityConfiguration.convertJwtToGrantedAuthorities(jwt);
 
-			var securityRoles = grantedAuthorities
-					.stream()
+			var securityRoles = grantedAuthorities.stream()
 					.map(GrantedAuthority::getAuthority).toList();
 			assertThat(securityRoles).containsAll(expectedSecurityRoleStrings);
 		}
 	}
 
 	@DisplayName("get roles from jwt")
+
 	@Nested
 	class TestGetRolesFromJwt {
 
@@ -158,16 +159,16 @@ class SecurityConfigurationTest {
 
 		private static Stream<Arguments> getIncompleteJwt() {
 			return Stream.of(JwtTestFactory.create(),
-							JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of()).build(),
-							JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of("admin", Map.of())).build(),
-							JwtTestFactory.createWithRoles(emptyList()).build())
+					JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of()).build(),
+					JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of("admin", Map.of())).build(),
+					JwtTestFactory.createWithRoles(emptyList()).build())
 					.map(Arguments::of);
 		}
 
 		@DisplayName("should return resource_access.admin.roles list")
 		@Test
 		void shouldReturnResourceAccessAdminRolesList() {
-			var expectedRoles = List.of(ROLE_1, JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3);
+			var expectedRoles = List.of(JwtTestFactory.ROLE_1, JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3);
 			var jwtWithRoles = JwtTestFactory.createWithRoles(expectedRoles).build();
 
 			var roleStrings = securityConfiguration.getRolesFromJwt(jwtWithRoles);
@@ -176,4 +177,5 @@ class SecurityConfigurationTest {
 		}
 
 	}
+
 }
diff --git a/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java b/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java
index c50d09934b9cfd835215a4589a0c70000fdc9419..4fe44a5e5de623e8c08dfd39cb6073058c497ed5 100644
--- a/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java
+++ b/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java
@@ -38,6 +38,7 @@ import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.ResultActions;
 
+import de.ozgcloud.admin.common.user.UserRole;
 import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheit;
 import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitTestFactory;
 import de.ozgcloud.admin.setting.postfach.PostfachSettingBodyTestFactory;
@@ -46,7 +47,7 @@ import lombok.SneakyThrows;
 
 @DataITCase
 @AutoConfigureMockMvc
-@WithMockUser
+@WithMockUser(roles = UserRole.ADMIN_ADMIN)
 class SettingEnvironmentITCase {
 
 	@Autowired
diff --git a/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java b/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java
index 3fb17b47e79176424afab28bcc63cf082a17ade2..4f7dc9e6b6b543a1c701b5c875cf70244600f442 100644
--- a/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java
+++ b/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java
@@ -29,31 +29,46 @@ import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.security.test.context.support.WithMockUser;
 
+import de.ozgcloud.admin.common.user.UserRole;
+import de.ozgcloud.admin.reporting.AggregationMappingTestFactory;
 import de.ozgcloud.common.test.DataITCase;
 
 @DataITCase
+@WithMockUser(roles = UserRole.ADMIN_ADMIN)
 class SettingRepositoryITCase {
+
 	@Autowired
 	private MongoOperations mongoOperations;
 	@Autowired
 	private SettingRepository repository;
 
-	private final static String SETTING_NAME = "Name";
-	private Setting setting = SettingTestFactory.createBuilder()
-			.name(SETTING_NAME)
-			.build();
-
 	@Nested
 	class TestFindOneByName {
 		@Test
 		void shouldGetSavedData() {
 			mongoOperations.dropCollection(Setting.COLLECTION_NAME);
-			mongoOperations.save(setting);
+			mongoOperations.save(SettingTestFactory.create());
+
+			var settingFromDb = repository.findOneByName(SettingTestFactory.SETTING_NAME).get();
+
+			assertThat(settingFromDb).usingRecursiveComparison().ignoringFields("id").isEqualTo(SettingTestFactory.create());
+		}
+	}
+
+	@Nested
+	class TestFindByType {
+
+		@Test
+		void shouldReturnOnlySetting() {
+			mongoOperations.dropCollection(Setting.COLLECTION_NAME);
+			mongoOperations.save(SettingTestFactory.create());
+			mongoOperations.save(AggregationMappingTestFactory.create());
 
-			var settingFromDb = repository.findOneByName(SETTING_NAME).get();
+			var loaded = repository.findByType("Setting", Setting.class);
 
-			assertThat(settingFromDb).usingRecursiveComparison().isEqualTo(setting);
+			assertThat(loaded).hasSize(1).first().isInstanceOf(Setting.class);
 		}
 	}
 }
diff --git a/src/test/java/de/ozgcloud/admin/setting/SettingTestFactory.java b/src/test/java/de/ozgcloud/admin/setting/SettingTestFactory.java
index 07e9533f4895b545042a35186f8d96080dd14952..54c4ae3b42514c653e28615ccc8b54e0cbc5f7b3 100644
--- a/src/test/java/de/ozgcloud/admin/setting/SettingTestFactory.java
+++ b/src/test/java/de/ozgcloud/admin/setting/SettingTestFactory.java
@@ -27,12 +27,14 @@ import de.ozgcloud.common.test.TestUtils;
 
 public class SettingTestFactory {
 
+	static final String SETTING_NAME = "Name";
+
 	public static Setting create() {
 		return createBuilder().build();
 	}
 
 	public static Setting.SettingBuilder createBuilder() {
-		return Setting.builder();
+		return Setting.builder().name(SETTING_NAME);
 	}
 
 	public static String buildSettingJson(Setting setting, String settingBodyString) {
diff --git a/src/test/resources/application-itcase.yaml b/src/test/resources/application-itcase.yaml
index 1217c868aaa994671a26171005505ce110d401a5..1361c8ede1a7c0664bb56cdd718ac67942899c4c 100644
--- a/src/test/resources/application-itcase.yaml
+++ b/src/test/resources/application-itcase.yaml
@@ -1,3 +1,9 @@
+logging:
+  level:
+    '[org.springframework.data.mongodb]': WARN
+    '[org.springframework.security]': WARN
+  config: classpath:log4j2-local.xml
+
 spring:
   data:
     mongodb:
diff --git a/src/test/resources/reporting/request.json b/src/test/resources/reporting/request.json
new file mode 100644
index 0000000000000000000000000000000000000000..c2db9de85906742429d7bcd56bc4ae61a28f2580
--- /dev/null
+++ b/src/test/resources/reporting/request.json
@@ -0,0 +1,12 @@
+{
+	"formIdentifier": {
+		"formEngineName": "A12",
+		"formId": "42"
+	},
+	"mappings": [
+		{
+			"sourcePath": "name",
+			"targetPath": "antragsteller.name"
+		}
+	] 
+}
\ No newline at end of file