diff --git a/archive-manager-interface/pom.xml b/archive-manager-interface/pom.xml
index 45418c34646ed3129139c9450eb3e1aeb7ad2e67..b3d32c02ff8d18b6a41663d4c4d77e2a90438b1a 100644
--- a/archive-manager-interface/pom.xml
+++ b/archive-manager-interface/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>de.ozgcloud.archive</groupId>
         <artifactId>archive-manager</artifactId>
-        <version>0.1.0-SNAPSHOT</version>
+        <version>0.2.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>archive-manager-interface</artifactId>
@@ -66,18 +66,6 @@
                 </executions>
             </plugin>
 
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-source-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>attach-sources</id>
-                        <goals>
-                            <goal>jar</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
             <plugin>
                 <groupId>io.github.floverfelt</groupId>
                 <artifactId>find-and-replace-maven-plugin</artifactId>
diff --git a/archive-manager-server/pom.xml b/archive-manager-server/pom.xml
index 3dc366b19a4698cc0e15c97bd06be4de17feff37..0b6f5f4eabc7bf886484ec58c3f2e10c31d4bea8 100644
--- a/archive-manager-server/pom.xml
+++ b/archive-manager-server/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>de.ozgcloud.archive</groupId>
 		<artifactId>archive-manager</artifactId>
-		<version>0.1.0-SNAPSHOT</version>
+		<version>0.2.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>archive-manager-server</artifactId>
@@ -69,12 +69,6 @@
 			<groupId>de.ozgcloud.document</groupId>
 			<artifactId>document-manager-interface</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>de.ozgcloud.api-lib</groupId>
-			<artifactId>api-lib-core</artifactId>
-			<type>test-jar</type>
-			<scope>test</scope>
-		</dependency>
 		<dependency>
 			<groupId>de.ozgcloud.xta</groupId>
 			<artifactId>xta-client-lib</artifactId>
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java
index 79e21e02f53e0f993669341d6beab9319b21b1ec..247277431b87bdb7fa32e063f090e427db734f6a 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/ArchiveManagerConfiguration.java
@@ -1,15 +1,41 @@
 package de.ozgcloud.archive;
 
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
+import de.ozgcloud.apilib.client_attribute.OzgCloudClientAttributeService;
+import de.ozgcloud.apilib.client_attribute.grpc.OzgCloudClientAttributeGrpcService;
+import de.ozgcloud.apilib.client_attribute.grpc.OzgCloudClientAttributeMapper;
+import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
+import de.ozgcloud.apilib.common.command.grpc.CommandMapper;
+import de.ozgcloud.apilib.common.command.grpc.GrpcOzgCloudCommandService;
+import de.ozgcloud.apilib.file.OzgCloudFileService;
+import de.ozgcloud.apilib.file.grpc.GrpcOzgCloudFileService;
+import de.ozgcloud.apilib.file.grpc.OzgCloudFileMapper;
+import de.ozgcloud.apilib.user.GrpcOzgCloudUserProfileService;
+import de.ozgcloud.apilib.user.OzgCloudUserProfileService;
+import de.ozgcloud.apilib.user.UserProfileMapper;
+import de.ozgcloud.archive.common.callcontext.CallContextProvider;
+import de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub;
+import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub;
+import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub;
+import de.ozgcloud.vorgang.grpc.clientAttribute.ClientAttributeServiceGrpc.ClientAttributeServiceBlockingStub;
+import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub;
+import lombok.RequiredArgsConstructor;
+import net.devh.boot.grpc.client.inject.GrpcClient;
+
 @Configuration
-public class ArchiveManagerConfiguration { // NOSONAR
+@RequiredArgsConstructor
+public class ArchiveManagerConfiguration {
 
+	public static final String VORGANG_SERVICE_NAME = "archive_VorgangService";
 	public static final String VORGANG_REMOTE_MANAGER_SERVICE_NAME = "archive_VorgangRemoteService";
 	public static final String VORGANG_WITH_EINGANG_MAPPER_NAME = "archive_VorgangWithEingangMapper";
 
 	public static final String CURRENT_USER_SERVICE_NAME = "archive_CurrentUserService";
 	public static final String DOCUMENT_MAPPER_NAME = "archive_DocumentMapper";
+	public static final String DOCUMENT_REMOTE_SERVICE_NAME = "archive_DocumentRemoteService";
 
 	public static final String USER_SERVICE_NAME = "archive_UserService";
 	public static final String USER_PROFILE_MAPPER_NAME = "archive_UserProfileMapper";
@@ -18,6 +44,7 @@ public class ArchiveManagerConfiguration { // NOSONAR
 	public static final String COMMAND_SERVICE_NAME = "archive_CommandService";
 	public static final String COMMAND_REMOTE_SERVICE_NAME = "archive_CommandRemoteService";
 	public static final String COMMAND_MAPPER_NAME = "archive_CommandMapper";
+	public static final String OZGCLOUD_COMMAND_SERVICE_NAME = "archive_OzgCloudCommandService";
 
 	public static final String BINARY_FILE_SERVICE_NAME = "archive_BinaryFileService";
 	public static final String BINARY_FILE_REMOTE_SERVICE_NAME = "archive_BinaryFileRemoteService";
@@ -28,6 +55,59 @@ public class ArchiveManagerConfiguration { // NOSONAR
 	public static final String BESCHEID_REMOTE_SERVICE_NAME = "archive_BescheidRemoteService";
 	public static final String BESCHEID_MAPPER_NAME = "archive_BescheidMapper";
 
-	public static final String OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME = "archive_CallContextProvider";
+	public static final String CALL_CONTEXT_PROVIDER_NAME = "archive_CallContextProvider";
+	public static final String CALL_CONTEXT_MAPPER_NAME = "archive_CallContextMapper";
+
+	public static final String CLIENT_ATTRIBUTE_SERVICE_NAME = "archive_ClientAttributeService";
+	public static final String OZGCLOUD_CLIENT_ATTRIBUTE_SERVICE_NAME = "archive_OzgCloudClientAttributeService";
+
+	public static final String KOMMENTAR_SERVICE_NAME = "archive_KommentarService";
+	public static final String KOMMENTAR_REMOTE_SERVICE_NAME = "archive_KommentarRemoteService";
+
+	public static final String CALL_CONTEXT_SERVER_INTERCEPTOR_NAME = "archive_CallContextGrpcServerInterceptor";
+
+	public static final String GRPC_VORGANG_MANAGER_CLIENT_NAME = "vorgang-manager";
+	public static final String GRPC_COMMAND_MANAGER_CLIENT_NAME = "command-manager";
+	public static final String GRPC_FILE_MANAGER_CLIENT_NAME = "file-manager";
+	public static final String GRPC_USER_MANAGER_CLIENT_NAME = "user-manager";
+
+	@GrpcClient(GRPC_VORGANG_MANAGER_CLIENT_NAME)
+	private final ClientAttributeServiceBlockingStub clientAttributeServiceBlockingStub;
+
+	@GrpcClient(GRPC_COMMAND_MANAGER_CLIENT_NAME)
+	private final CommandServiceBlockingStub commandServiceStub;
+
+	@GrpcClient(GRPC_USER_MANAGER_CLIENT_NAME)
+	private final UserProfileServiceBlockingStub userProfileServiceBlockingStub;
+
+	@GrpcClient(GRPC_FILE_MANAGER_CLIENT_NAME)
+	private final BinaryFileServiceBlockingStub binaryFileServiceBlockingStub;
+
+	@GrpcClient(GRPC_FILE_MANAGER_CLIENT_NAME)
+	private final BinaryFileServiceStub binaryFileServiceStub;
+
+	@Bean(ArchiveManagerConfiguration.OZGCLOUD_FILE_SERVICE_NAME) // NOSONAR
+	OzgCloudFileService ozgCloudFileService(OzgCloudFileMapper mapper,
+			@Qualifier(CALL_CONTEXT_PROVIDER_NAME) CallContextProvider callContextProvider) {
+		return new GrpcOzgCloudFileService(binaryFileServiceBlockingStub, binaryFileServiceStub, callContextProvider, mapper);
+	}
+
+	@Bean(ArchiveManagerConfiguration.OZGCLOUD_USER_PROFILE_SERVICE_NAME) // NOSONAR
+	OzgCloudUserProfileService grpcOzgCloudUserProfileService(UserProfileMapper userProfileMapper,
+			@Qualifier(CALL_CONTEXT_PROVIDER_NAME) CallContextProvider callContextProvider) {
+		return new GrpcOzgCloudUserProfileService(userProfileServiceBlockingStub, userProfileMapper, callContextProvider);
+	}
+
+	@Bean(OZGCLOUD_CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR
+	OzgCloudClientAttributeService ozgCloudAttributesService(OzgCloudClientAttributeMapper mapper,
+			@Qualifier(CALL_CONTEXT_PROVIDER_NAME) CallContextProvider callContextProvider) {
+		return new OzgCloudClientAttributeGrpcService(clientAttributeServiceBlockingStub, mapper, callContextProvider);
+	}
 
+	@Bean(OZGCLOUD_COMMAND_SERVICE_NAME) // NOSONAR
+	OzgCloudCommandService ozgCloudCommandService(CommandMapper commandMapper,
+			@Qualifier(CALL_CONTEXT_PROVIDER_NAME) CallContextProvider callContextProvider) {
+		return new GrpcOzgCloudCommandService(commandServiceStub, commandMapper, callContextProvider,
+				GrpcOzgCloudCommandService.DEFAULT_COMMAND_REQUEST_THRESHOLD_MILLIS);
+	}
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/OzgcloudConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/OzgcloudConfiguration.java
deleted file mode 100644
index 0311d0420c079af88e3f04daa8e831741f7d359b..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/OzgcloudConfiguration.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package de.ozgcloud.archive;
-
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
-import de.ozgcloud.apilib.file.OzgCloudFileService;
-import de.ozgcloud.apilib.file.grpc.GrpcOzgCloudFileService;
-import de.ozgcloud.apilib.file.grpc.OzgCloudFileMapper;
-import de.ozgcloud.apilib.user.GrpcOzgCloudUserProfileService;
-import de.ozgcloud.apilib.user.OzgCloudUserProfileService;
-import de.ozgcloud.apilib.user.UserProfileMapper;
-import de.ozgcloud.archive.common.GrpcUtil;
-import de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub;
-import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub;
-import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub;
-import net.devh.boot.grpc.client.inject.GrpcClient;
-
-@Configuration
-class OzgcloudConfiguration {
-
-	@GrpcClient(GrpcUtil.USER_MANAGER_GRPC_CLIENT)
-	private UserProfileServiceBlockingStub userProfileServiceBlockingStub;
-
-	@GrpcClient(GrpcUtil.FILE_MANAGER_GRPC_CLIENT)
-	private BinaryFileServiceBlockingStub binaryFileServiceBlockingStub;
-
-	@GrpcClient(GrpcUtil.FILE_MANAGER_GRPC_CLIENT)
-	private BinaryFileServiceStub binaryFileServiceStub;
-
-	@Bean(ArchiveManagerConfiguration.OZGCLOUD_FILE_SERVICE_NAME)
-	OzgCloudFileService ozgCloudFileService(
-			@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME) OzgCloudCallContextProvider contextProvider,
-			OzgCloudFileMapper mapper) {
-
-		return new GrpcOzgCloudFileService(binaryFileServiceBlockingStub, binaryFileServiceStub, contextProvider, mapper);
-	}
-
-	@Bean(ArchiveManagerConfiguration.OZGCLOUD_USER_PROFILE_SERVICE_NAME) // NOSONAR
-	OzgCloudUserProfileService grpcOzgCloudUserProfileService(
-			@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME) OzgCloudCallContextProvider callContextProvider,
-			UserProfileMapper userProfileMapper) {
-		return new GrpcOzgCloudUserProfileService(userProfileServiceBlockingStub, userProfileMapper, callContextProvider);
-	}
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/XtaConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/XtaConfiguration.java
deleted file mode 100644
index 2c75525bc1cb91a82f24613875d96c9c3c86d16e..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/XtaConfiguration.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package de.ozgcloud.archive;
-
-import java.io.IOException;
-
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import de.ozgcloud.archive.XtaProperties.XtaClientKeyStore;
-import de.ozgcloud.common.errorhandling.TechnicalException;
-import de.ozgcloud.xta.client.XtaClient;
-import de.ozgcloud.xta.client.config.XtaClientConfig;
-import de.ozgcloud.xta.client.config.XtaClientConfig.KeyStore;
-import de.ozgcloud.xta.client.exception.XtaClientInitializationException;
-
-@Configuration
-class XtaConfiguration {
-
-	@Bean
-	@ConditionalOnProperty(XtaProperties.XTA_PROPERTIES_PREFIX)
-	XtaClient xtaClient(XtaProperties xtaProperties) {
-		try {
-			return XtaClient.from(buildXtaClientConfig(xtaProperties));
-		} catch (XtaClientInitializationException e) {
-			throw new TechnicalException("Error on initializing Xta client.", e);
-		}
-	}
-
-	XtaClientConfig buildXtaClientConfig(XtaProperties xtaProperties) {
-		try {
-			return XtaClientConfig.builder()
-					.sendServiceUrl(xtaProperties.getSendServiceUrl())
-					.managementServiceUrl(xtaProperties.getManagementServiceUrl())
-					.msgBoxServiceUrl(xtaProperties.getMsgBoxServiceUrl())
-					.clientCertKeystore(buildClientCertKeystore(xtaProperties.getKeyStore()))
-					.maxListItems(xtaProperties.getMaxListItems())
-					.clientIdentifiers(xtaProperties.getClientIdentifiers())
-					.build();
-		} catch (IOException e) {
-			throw new TechnicalException("Error on reading Xta client certificate.", e);
-		}
-	}
-
-	private KeyStore buildClientCertKeystore(XtaClientKeyStore clientCert) throws IOException {
-		return XtaClientConfig.KeyStore.builder()
-				.content(clientCert.getFile().getContentAsByteArray())
-				.type(clientCert.getType())
-				.password(clientCert.getPassword())
-				.build();
-	}
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java
new file mode 100644
index 0000000000000000000000000000000000000000..21d24f804eb7d430b399243e9af5baaa8affecb8
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/attributes/ClientAttributeService.java
@@ -0,0 +1,61 @@
+/*
+ * 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.archive.attributes;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import de.ozgcloud.apilib.client_attribute.OzgCloudAccessPermission;
+import de.ozgcloud.apilib.client_attribute.OzgCloudBooleanClientAttribute;
+import de.ozgcloud.apilib.client_attribute.OzgCloudClientAttributeService;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper;
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
+import de.ozgcloud.archive.common.callcontext.CallContextUser;
+import lombok.RequiredArgsConstructor;
+
+@Service(ArchiveManagerConfiguration.CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR
+@RequiredArgsConstructor
+public class ClientAttributeService {
+
+	public static final String ATTRIBUTE_NAME_ANTRAG_ARCHIVING = "ARCHIVING";
+
+	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR
+	private final OzgCloudClientAttributeService ozgCloudAttributesService;
+
+	private final OzgCloudVorgangIdMapper vorgangIdMapper;
+
+	public void setVorgangArchiving(String vorgangId) {
+		ozgCloudAttributesService.setClientAttribute(buildBooleanClientAttribute(true), vorgangIdMapper.fromString(vorgangId));
+	}
+
+	OzgCloudBooleanClientAttribute buildBooleanClientAttribute(boolean isArchiving) {
+		return OzgCloudBooleanClientAttribute.builder()
+				.clientName(CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME)
+				.access(OzgCloudAccessPermission.READ_ONLY)
+				.attributeName(ATTRIBUTE_NAME_ANTRAG_ARCHIVING)
+				.value(isArchiving)
+				.build();
+	}
+
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/BescheidRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/BescheidRemoteService.java
index eda3d0ccd43ec3a5c9a419f183af1a13015e08e7..7b1e5095cc9d5f4f4afc72be229788472c3817c8 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/BescheidRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/BescheidRemoteService.java
@@ -2,29 +2,27 @@ package de.ozgcloud.archive.bescheid;
 
 import java.util.stream.Stream;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.GrpcUtil;
 import de.ozgcloud.document.bescheid.BescheidServiceGrpc.BescheidServiceBlockingStub;
 import de.ozgcloud.document.bescheid.GrpcGetAllBescheidRequest;
+import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
 @Service(ArchiveManagerConfiguration.BESCHEID_REMOTE_SERVICE_NAME) // NOSONAR
+@RequiredArgsConstructor
 class BescheidRemoteService {
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
-	private BescheidServiceBlockingStub grpcService;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	private OzgCloudCallContextProvider contextProvider;
-	@Autowired
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME)
+	private final BescheidServiceBlockingStub grpcService;
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
+	private final OzgCloudCallContextProvider contextProvider;
 	@Qualifier(ArchiveManagerConfiguration.BESCHEID_MAPPER_NAME) // NOSONAR
-	private BescheidMapper bescheidMapper;
+	private final BescheidMapper bescheidMapper;
 
 	public Stream<Bescheid> findByVorgangId(String vorgangId) {
 		var request = buildGetAllBescheidRequest(vorgangId);
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/DocumentRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/DocumentRemoteService.java
index 1eead2e35a5cef9783cf6f9bbb465179a619e001..5428fdda81422b96ac5ee1d0490e2e7773367785 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/DocumentRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/DocumentRemoteService.java
@@ -1,29 +1,27 @@
 package de.ozgcloud.archive.bescheid;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.GrpcUtil;
 import de.ozgcloud.common.binaryfile.FileId;
 import de.ozgcloud.document.DocumentServiceGrpc.DocumentServiceBlockingStub;
 import de.ozgcloud.document.GrpcGetDocumentRequest;
+import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
-@Service
+@Service(ArchiveManagerConfiguration.DOCUMENT_REMOTE_SERVICE_NAME) // NOSONAR
+@RequiredArgsConstructor
 class DocumentRemoteService {
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
-	private DocumentServiceBlockingStub grpcService;
-	@Autowired
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME) // NOSONAR
+	private final DocumentServiceBlockingStub grpcService;
 	@Qualifier(ArchiveManagerConfiguration.DOCUMENT_MAPPER_NAME) // NOSONAR
-	private DocumentMapper documentMapper;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	private OzgCloudCallContextProvider contextProvider;
+	private final DocumentMapper documentMapper;
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
+	private final OzgCloudCallContextProvider contextProvider;
 
 	public FileId getDocument(String documentId) {
 		var response = getGrpcServiceWithInterceptor().getDocument(GrpcGetDocumentRequest.newBuilder().setId(documentId).build());
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/ExportBescheidService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/ExportBescheidService.java
index 7fe61a04059da950ac3cd7950cc0f8854ed4dc3b..0a120e71f6e69af9060f471df95714e3713ec328 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/ExportBescheidService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/bescheid/ExportBescheidService.java
@@ -23,6 +23,7 @@ public class ExportBescheidService {
 	@Qualifier(ArchiveManagerConfiguration.BINARY_FILE_SERVICE_NAME) // NOSONAR
 	private final BinaryFileService binaryFileService;
 
+	@Qualifier(ArchiveManagerConfiguration.DOCUMENT_REMOTE_SERVICE_NAME) // NOSONAR
 	private final DocumentRemoteService documentRemoteService;
 
 	@Qualifier(ArchiveManagerConfiguration.USER_SERVICE_NAME) // NOSONAR
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/GrpcUtil.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/GrpcUtil.java
deleted file mode 100644
index c7ecb0d7e72af32754fcb642ed011d36c58ab42c..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/GrpcUtil.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.ozgcloud.archive.common;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class GrpcUtil {
-
-	public static final String VORGANG_MANAGER_GRPC_CLIENT = "vorgang-manager";
-	public static final String FILE_MANAGER_GRPC_CLIENT = "file-manager";
-	public static final String USER_MANAGER_GRPC_CLIENT = "user-manager";
-
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/binaryfile/BinaryFileRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/binaryfile/BinaryFileRemoteService.java
index 81d450f5df26ba8bb5eb6f02e0e49a5477929bd1..733788b6492552491eb97d7ad78a1486d813c697 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/binaryfile/BinaryFileRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/binaryfile/BinaryFileRemoteService.java
@@ -4,7 +4,6 @@ import java.io.OutputStream;
 import java.util.List;
 import java.util.stream.Stream;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
@@ -12,32 +11,32 @@ import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterce
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.apilib.file.OzgCloudFileService;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.GrpcUtil;
 import de.ozgcloud.archive.file.OzgFile;
 import de.ozgcloud.archive.file.OzgFileMapper;
 import de.ozgcloud.common.binaryfile.FileId;
 import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcBinaryFilesRequest;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcFindFilesResponse;
+import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
 @Service(ArchiveManagerConfiguration.BINARY_FILE_REMOTE_SERVICE_NAME) // NOSONAR
+@RequiredArgsConstructor
 class BinaryFileRemoteService {
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
-	private BinaryFileServiceBlockingStub grpcService;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_FILE_SERVICE_NAME)
-	private OzgCloudFileService ozgCloudFileService;
-	@Autowired
-	private OzgFileMapper ozgFileMapper;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	private OzgCloudCallContextProvider contextProvider;
-
-	@Autowired
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME) // NOSONAR
+	private final BinaryFileServiceBlockingStub grpcService;
+
+	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_FILE_SERVICE_NAME) // NOSONAR
+	private final OzgCloudFileService ozgCloudFileService;
+
+	private final OzgFileMapper ozgFileMapper;
+
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
+	private final OzgCloudCallContextProvider contextProvider;
+
 	@Qualifier(ArchiveManagerConfiguration.FILE_ID_MAPPER_NAME) // NOSONAR
-	private FileIdMapper fileIdMapper;
+	private final FileIdMapper fileIdMapper;
 
 	public Stream<OzgFile> getFiles(List<FileId> fileIds) {
 		var response = getGrpcServiceWithInterceptor().findBinaryFilesMetaData(buildBinaryFilesRequest(fileIds));
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContext.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContext.java
deleted file mode 100644
index 5af38120e0ee69c9359462afc7b3b175a8dad594..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContext.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-import java.util.Collection;
-import java.util.UUID;
-
-import lombok.Builder;
-import lombok.Getter;
-import lombok.Singular;
-
-@Builder
-@Getter
-public class ArchiveCallContext {
-
-	public static final String CLIENT_NAME = "OzgCloud_ArchiveManager";
-
-	@Builder.Default
-	private String clientName = CLIENT_NAME;
-	private String userId;
-
-	@Builder.Default
-	private String requestId = UUID.randomUUID().toString();
-	@Builder.Default
-	private boolean accessLimited = false;
-	@Singular
-	private Collection<String> accessLimitedToOrgaIds;
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextMapper.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextMapper.java
deleted file mode 100644
index 43c2125c9914a943cf5a2ceba8dcc6558658e33c..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextMapper.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
-
-import de.ozgcloud.apilib.common.callcontext.CallContext;
-import de.ozgcloud.archive.common.user.OzgCloudUserIdMapper;
-
-@Mapper(uses = OzgCloudUserIdMapper.class)
-public interface ArchiveCallContextMapper {
-
-	@Mapping(target = "accessLimitedToOrgaId", ignore = true)
-	CallContext toOzgCloudCallContext(ArchiveCallContext archiveCallContext);
-
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextAuthenticationToken.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextAuthenticationToken.java
index d9709a8aa4f6f0953a5c19611374accaa56564c7..156357c600baab2fe7d0034cdb77729a24fd709e 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextAuthenticationToken.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextAuthenticationToken.java
@@ -31,7 +31,9 @@ import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
 import lombok.EqualsAndHashCode;
+import lombok.Getter;
 
+@Getter
 @EqualsAndHashCode(callSuper = true)
 public class CallContextAuthenticationToken extends AbstractAuthenticationToken {
 
@@ -42,7 +44,7 @@ public class CallContextAuthenticationToken extends AbstractAuthenticationToken
 	}
 
 	private CallContextAuthenticationToken(CallContextUser user) {
-		super(user.getOrganisatorischeEinheitenIds().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet()));
+		super(user.getAccessLimitedToOrgaIds().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet()));
 		this.user = user;
 		super.setAuthenticated(true);
 	}
@@ -54,11 +56,11 @@ public class CallContextAuthenticationToken extends AbstractAuthenticationToken
 
 	@Override
 	public Object getPrincipal() {
-		return user;
+		return getUser();
 	}
 
 	@Override
 	public Collection<GrantedAuthority> getAuthorities() {
-		return user.getOrganisatorischeEinheitenIds().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toUnmodifiableSet());
+		return user.getAccessLimitedToOrgaIds().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toUnmodifiableSet());
 	}
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextConfiguration.java
deleted file mode 100644
index ffaabe7c2236d88f41f561056f620ac9306817cb..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextConfiguration.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
-import de.ozgcloud.archive.ArchiveManagerConfiguration;
-
-@Configuration
-public class CallContextConfiguration {
-
-	@Bean(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	OzgCloudCallContextProvider callContextProvider(ArchiveCallContextMapper mapper) {
-		return new CallContextProvider(mapper, CallContextInterceptor.CONTEXT_KEY_CALL_CONTEXT::get);
-	}
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextGrpcServerInterceptor.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextGrpcServerInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ea2660d6c5ca7cee1400f01a572da5ab9cb87a3
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextGrpcServerInterceptor.java
@@ -0,0 +1,86 @@
+package de.ozgcloud.archive.common.callcontext;
+
+import java.util.UUID;
+
+import org.apache.logging.log4j.CloseableThreadContext;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
+import de.ozgcloud.common.grpc.GrpcUtil;
+import io.grpc.ForwardingServerCallListener;
+import io.grpc.Metadata;
+import io.grpc.ServerCall;
+import io.grpc.ServerCall.Listener;
+import io.grpc.ServerCallHandler;
+import io.grpc.ServerInterceptor;
+import lombok.RequiredArgsConstructor;
+
+@Component(ArchiveManagerConfiguration.CALL_CONTEXT_SERVER_INTERCEPTOR_NAME) // NOSONAR
+@RequiredArgsConstructor
+public class CallContextGrpcServerInterceptor implements ServerInterceptor {
+
+	@Qualifier(ArchiveManagerConfiguration.CURRENT_USER_SERVICE_NAME) // NOSONAR
+	private final CurrentUserService currentUserService;
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_MAPPER_NAME) // NOSONAR
+	private final CallContextMapper callContextMapper;
+
+	@Override
+	public <A, B> Listener<A> interceptCall(ServerCall<A, B> call, Metadata headers, ServerCallHandler<A, B> next) {
+		return new LogContextSettingListener<>(next.startCall(call, headers), headers);
+	}
+
+	class LogContextSettingListener<A> extends ForwardingServerCallListener.SimpleForwardingServerCallListener<A> {
+
+		private final String requestId;
+		private final Metadata headers;
+
+		public LogContextSettingListener(ServerCall.Listener<A> delegate, Metadata headers) {
+			super(delegate);
+			this.headers = headers;
+			this.requestId = getRequestId(headers);
+		}
+
+		String getRequestId(Metadata headers) {
+			return GrpcUtil.getRequestId(headers).orElseGet(() -> UUID.randomUUID().toString());
+		}
+
+		@Override
+		public void onMessage(A message) {
+			doSurroundOn(() -> super.onMessage(message));
+		}
+
+		@Override
+		public void onHalfClose() {
+			doSurroundOn(super::onHalfClose);
+		}
+
+		@Override
+		public void onCancel() {
+			doSurroundOn(super::onCancel);
+		}
+
+		@Override
+		public void onComplete() {
+			doSurroundOn(super::onComplete);
+		}
+
+		@Override
+		public void onReady() {
+			doSurroundOn(super::onReady);
+		}
+
+		void doSurroundOn(Runnable runnable) {
+			SecurityContext securityContext = null;
+			try (var ctc = CloseableThreadContext.put(GrpcUtil.KEY_REQUEST_ID, requestId)) {
+				securityContext = currentUserService.startAndReturnPreviousSecurityContext(callContextMapper.toCallContextUser(headers, requestId));
+				runnable.run();
+			} finally {
+				currentUserService.resetSecurityContext(securityContext);
+			}
+		}
+
+	}
+
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextInterceptor.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextInterceptor.java
deleted file mode 100644
index f2736787df9f53f3bb11ced8b6af76b9d2d7d24e..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextInterceptor.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-import static de.ozgcloud.common.grpc.GrpcUtil.*;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Component;
-
-import io.grpc.Context;
-import io.grpc.Contexts;
-import io.grpc.Metadata;
-import io.grpc.ServerCall;
-import io.grpc.ServerCall.Listener;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerInterceptor;
-import lombok.RequiredArgsConstructor;
-
-@Component
-@RequiredArgsConstructor
-public class CallContextInterceptor implements ServerInterceptor {
-
-	static final String KEY_USER_ID = "USER_ID-bin";
-	static final String KEY_ACCESS_LIMITED = "ACCESS_LIMITED-bin";
-	static final String KEY_ACCESS_LIMITED_ORGAID = "ACCESS_LIMITED_TO_ORGANISATORISCHEEINHEITENID-bin";
-
-	public static final Context.Key<ArchiveCallContext> CONTEXT_KEY_CALL_CONTEXT = Context.key("archiveCallContext");
-
-	@Override
-	public <A, B> Listener<A> interceptCall(ServerCall<A, B> call, Metadata headers, ServerCallHandler<A, B> next) {
-		var newContext = Context.current().withValue(CONTEXT_KEY_CALL_CONTEXT, createArchiveCallContext(headers));
-		return Contexts.interceptCall(newContext, call, headers, next);
-	}
-
-	ArchiveCallContext createArchiveCallContext(Metadata headers) {
-		return ArchiveCallContext.builder()
-				.userId(getFromHeaders(KEY_USER_ID, headers).orElse(StringUtils.EMPTY))
-				.accessLimited(getFromHeaders(KEY_ACCESS_LIMITED, headers).map(isLimited -> isLimited.equals("true")).orElse(false))
-				.accessLimitedToOrgaIds(getCollection(KEY_ACCESS_LIMITED_ORGAID, headers))
-				.build();
-	}
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextMapper.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..5731f307fa3e96f9c59692bb28da2b33665031ba
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextMapper.java
@@ -0,0 +1,60 @@
+/*
+ * 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.archive.common.callcontext;
+
+import org.mapstruct.AnnotateWith;
+import org.mapstruct.CollectionMappingStrategy;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.apilib.common.callcontext.CallContext;
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
+import de.ozgcloud.archive.common.user.OzgCloudUserIdMapper;
+import de.ozgcloud.common.grpc.GrpcUtil;
+import io.grpc.Metadata;
+import lombok.extern.log4j.Log4j2;
+
+@Mapper(uses = OzgCloudUserIdMapper.class, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
+@AnnotateWith(value = Component.class, elements = @AnnotateWith.Element(strings = ArchiveManagerConfiguration.CALL_CONTEXT_MAPPER_NAME))
+@Log4j2
+abstract class CallContextMapper { // NOSONAR
+
+	@Mapping(target = "accessLimitedToOrgaId", ignore = true)
+	@Mapping(target = "clientName", constant = CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME)
+	abstract CallContext toOzgCloudCallContext(CallContextUser callContextUser);
+
+	public CallContextUser toCallContextUser(Metadata headers, String requestId) {
+		var builder = CallContextUser.builder()
+				.requestId(requestId)
+				.userId(GrpcUtil.getUserId(headers))
+				.userName(GrpcUtil.getUserName(headers));
+		GrpcUtil.getAccessLimited(headers).ifPresentOrElse(
+				isAccessLimited -> builder.accessLimited(isAccessLimited).accessLimitedToOrgaIds(GrpcUtil.getAccessLimitedOrgaIds(headers)),
+				() -> builder.accessLimited(false));
+		// TODO throw exception if missing required data as soon all clients are fine
+		GrpcUtil.getClientName(headers).ifPresentOrElse(builder::clientName, () -> LOG.warn("Missing client name in grpc header."));
+		return builder.build();
+	}
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextProvider.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextProvider.java
index 5ce75ee17473a0f65c2483dc18cc1c2ec7f8a718..9fd0d350ed11048aded7be7715f289c52cf6c941 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextProvider.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextProvider.java
@@ -1,18 +1,24 @@
 package de.ozgcloud.archive.common.callcontext;
 
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
 import de.ozgcloud.apilib.common.callcontext.CallContext;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import lombok.RequiredArgsConstructor;
 
+@Component(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
 @RequiredArgsConstructor
 public class CallContextProvider implements OzgCloudCallContextProvider {
 
-	private final ArchiveCallContextMapper mapper;
-	private final GrpcCallContextSupplier contextSupplier;
+	@Qualifier(ArchiveManagerConfiguration.CURRENT_USER_SERVICE_NAME) // NOSONAR
+	private final CurrentUserService currentUserService;
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_MAPPER_NAME) // NOSONAR
+	private final CallContextMapper mapper;
 
 	@Override
 	public CallContext provideContext() {
-		var archiveCallContext = contextSupplier.get();
-		return mapper.toOzgCloudCallContext(archiveCallContext);
+		return mapper.toOzgCloudCallContext(currentUserService.getUser());
 	}
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextUser.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextUser.java
index baca08b2a58088decfde17f8fc3559e266dc56e0..0d74bf0b07f69f8f5ca9da3b1805f4483147716a 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextUser.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CallContextUser.java
@@ -1,28 +1,6 @@
-/*
- * 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.archive.common.callcontext;
 
+import java.io.Serial;
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Optional;
@@ -37,21 +15,27 @@ import lombok.Singular;
 @Getter
 public class CallContextUser implements AuthenticatedPrincipal, Serializable {
 
+	public static final String ARCHIVE_MANAGER_CLIENT_NAME = "OzgCloud_ArchiveManager";
+
+	@Serial
 	private static final long serialVersionUID = 1L;
 
-	private final String clientName;
+	private String requestId;
+
+	private String clientName;
 
 	@Builder.Default
-	private final transient Optional<String> userId = Optional.empty();
+	private Optional<String> userId = Optional.empty();
 	@Builder.Default
-	private final transient Optional<String> userName = Optional.empty();
-	@Singular
-	private final Collection<String> organisatorischeEinheitenIds;
+	private Optional<String> userName = Optional.empty();
 	@Builder.Default
-	private final transient boolean organisationEinheitenIdCheckNecessary = false;
+	private boolean accessLimited = false;
+
+	@Singular
+	private Collection<String> accessLimitedToOrgaIds;
 
 	@Override
 	public String getName() {
 		return clientName;
 	}
-}
\ No newline at end of file
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CurrentUserService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CurrentUserService.java
index b45454745ceb121335ab490e531f094732b74eb2..07e867d69de62efecc026ddec84cf92644a3e241 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CurrentUserService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/CurrentUserService.java
@@ -25,9 +25,10 @@ package de.ozgcloud.archive.common.callcontext;
 
 import java.util.Objects;
 import java.util.Optional;
-import java.util.stream.Collectors;
+import java.util.UUID;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.ThreadContext;
 import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
@@ -37,6 +38,7 @@ import org.springframework.stereotype.Service;
 
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import de.ozgcloud.command.Command;
+import de.ozgcloud.common.grpc.GrpcUtil;
 import lombok.RequiredArgsConstructor;
 
 @RequiredArgsConstructor
@@ -56,16 +58,14 @@ public class CurrentUserService {
 				.filter(user -> StringUtils.isNotBlank(user.getClientName()));
 	}
 
-	private CallContextUser mapToCallContextUser(Authentication auth) {
-		if (auth instanceof CallContextAuthenticationToken) {
-			return (CallContextUser) auth.getPrincipal();
-		} else {
-			return CallContextUser.builder()
-					.clientName(auth.getName())
-					.organisatorischeEinheitenIds(
-							auth.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toUnmodifiableSet()))
-					.build();
-		}
+	CallContextUser mapToCallContextUser(Authentication auth) {
+		return auth instanceof CallContextAuthenticationToken token ? token.getUser() : buildDefaultCallContextUser(auth);
+	}
+
+	CallContextUser buildDefaultCallContextUser(Authentication auth) {
+		var defaultContextUser = CallContextUser.builder().clientName(auth.getName());
+		auth.getAuthorities().stream().map(GrantedAuthority::getAuthority).forEach(defaultContextUser::accessLimitedToOrgaId);
+		return defaultContextUser.build();
 	}
 
 	public Optional<Authentication> findAuthentication() {
@@ -79,23 +79,32 @@ public class CurrentUserService {
 				.filter(Authentication::isAuthenticated);
 	}
 
-	public SecurityContext startSecurityContext(Command command) {
-		var prevContext = SecurityContextHolder.getContext();
-
-		SecurityContextHolder.clearContext();
-		SecurityContextHolder.getContext().setAuthentication(CallContextAuthenticationToken.authenticate(createUser(command)));
-
-		return prevContext;
+	public SecurityContext startAndReturnPreviousSecurityContext(Command command) {
+		return startAndReturnPreviousSecurityContext(createUser(command));
 	}
 
 	CallContextUser createUser(Command command) {
-		var builder = CallContextUser.builder()
+		return CallContextUser.builder()
 				.userId(Optional.ofNullable(command.getCreatedBy()))
 				.userName(Optional.ofNullable(command.getCreatedByName()))
 				.clientName(command.getCreatedByClientName())
-				.organisationEinheitenIdCheckNecessary(false);
+				.requestId(getRequestId())
+				.accessLimited(false)
+				.build();
+	}
 
-		return builder.build();
+	String getRequestId() {
+		return ThreadContext.getContext().getOrDefault(GrpcUtil.KEY_REQUEST_ID, UUID.randomUUID().toString());
+	}
+
+
+	public SecurityContext startAndReturnPreviousSecurityContext(CallContextUser user) {
+		var prevContext = SecurityContextHolder.getContext();
+
+		SecurityContextHolder.clearContext();
+		SecurityContextHolder.getContext().setAuthentication(CallContextAuthenticationToken.authenticate(user));
+
+		return prevContext;
 	}
 
 	public void resetSecurityContext(SecurityContext context) {
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/GrpcCallContextSupplier.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/GrpcCallContextSupplier.java
deleted file mode 100644
index a5237a7877c7805d6724a480b3062a257028dadb..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/callcontext/GrpcCallContextSupplier.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-import java.util.function.Supplier;
-
-interface GrpcCallContextSupplier extends Supplier<ArchiveCallContext> {
-
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java
index 5f108c823fff0b6741058edc2e7ac069ebc0eff4..30737473d4f5ecf767f9abdaa55e193aaac5698f 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandRemoteService.java
@@ -3,33 +3,30 @@ package de.ozgcloud.archive.common.command;
 import java.util.Optional;
 import java.util.stream.Stream;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.GrpcUtil;
-import de.ozgcloud.command.Command;
 import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub;
 import de.ozgcloud.vorgang.grpc.command.GrpcExistsPendingCommandsRequest;
 import de.ozgcloud.vorgang.grpc.command.GrpcFindCommandsRequest;
+import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
+@RequiredArgsConstructor
 @Service(ArchiveManagerConfiguration.COMMAND_REMOTE_SERVICE_NAME) // NOSONAR
 class CommandRemoteService {
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
-	private CommandServiceBlockingStub grpcService;
-	@Autowired
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME) // NOSONAR
+	private final CommandServiceBlockingStub grpcService;
 	@Qualifier(ArchiveManagerConfiguration.COMMAND_MAPPER_NAME) // NOSONAR
-	private CommandMapper mapper;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	private OzgCloudCallContextProvider contextProvider;
+	private final CommandMapper mapper;
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
+	private final OzgCloudCallContextProvider contextProvider;
 
-	public Stream<Command> findCommands(String vorgangId, Optional<String> status, Optional<String> order) {
+	public Stream<ArchiveManagerCommand> findCommands(String vorgangId, Optional<String> status, Optional<String> order) {
 		var response = getGrpcServiceWithInterceptor().findCommands(buildFindCommandsRequest(vorgangId, status, order));
 
 		return response.getCommandList().stream().map(mapper::fromGrpc);
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java
index a6b4fa22312cf7fd9e4a239dd30474483fab3721..87ec01c91c8a18da8fad5f749702e028ce955ae9 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/command/CommandService.java
@@ -1,13 +1,17 @@
 package de.ozgcloud.archive.common.command;
 
 import java.util.Optional;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
+import de.ozgcloud.apilib.common.command.OzgCloudCommand;
+import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.command.Command;
 import de.ozgcloud.command.CommandStatus;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
@@ -18,8 +22,10 @@ public class CommandService {
 
 	@Qualifier(ArchiveManagerConfiguration.COMMAND_REMOTE_SERVICE_NAME) // NOSONAR
 	private final CommandRemoteService remoteService;
+	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_COMMAND_SERVICE_NAME) // NOSONAR
+	private final OzgCloudCommandService ozgCloudCommandService;
 
-	public Stream<Command> findPending(String vorgangId, CommandOrder order) {
+	public Stream<ArchiveManagerCommand> findPending(String vorgangId, CommandOrder order) {
 		return remoteService.findCommands(vorgangId, Optional.of(CommandStatus.PENDING.name()), Optional.of(order.name()));
 	}
 
@@ -28,7 +34,12 @@ public class CommandService {
 				.map(ArchiveManagerCommand.class::cast);
 	}
 
-	public boolean hasPendingCommands(String vorgangId) {
-		return remoteService.hasPendingCommands(vorgangId);
+	public boolean hasPendingCommandsExceptWithOrder(String vorgangId, String order) {
+		var pendingCommands = ozgCloudCommandService.getPendingCommands(OzgCloudVorgangId.from(vorgangId));
+		return pendingCommands.stream().anyMatch(hasNotOrder(order));
+	}
+
+	private Predicate<? super OzgCloudCommand> hasNotOrder(String order) {
+		return command -> !StringUtils.equals(command.getOrder(), order);
 	}
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/user/OzgCloudUserIdMapper.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/user/OzgCloudUserIdMapper.java
index d662419ad8a5e575b713e40fe9a09ba927688404..0c41a4e443df0290a12785c043df33b28068b7af 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/user/OzgCloudUserIdMapper.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/user/OzgCloudUserIdMapper.java
@@ -1,5 +1,7 @@
 package de.ozgcloud.archive.common.user;
 
+import java.util.Optional;
+
 import org.mapstruct.Mapper;
 
 import de.ozgcloud.apilib.user.OzgCloudUserId;
@@ -7,6 +9,10 @@ import de.ozgcloud.apilib.user.OzgCloudUserId;
 @Mapper
 public interface OzgCloudUserIdMapper {
 
+	default OzgCloudUserId fromString(Optional<String> id) {
+		return id.map(this::fromString).orElse(null);
+	}
+
 	default OzgCloudUserId fromString(String id) {
 		return OzgCloudUserId.from(id);
 	}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d112b2c26dbfe68d4d97b819afd6a9b667e20549
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverter.java
@@ -0,0 +1,34 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.util.List;
+
+import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.model.XtaIdentifier;
+import lombok.RequiredArgsConstructor;
+
+@Component
+@ConfigurationPropertiesBinding
+@RequiredArgsConstructor
+public class JsonToXtaIdentifierListConverter implements Converter<String, List<XtaIdentifier>> {
+
+	private final ObjectMapper objectMapper;
+
+	@Override
+	public List<XtaIdentifier> convert(String source) {
+		try {
+			return objectMapper.readValue(source, new TypeReference<List<XtaIdentifier>>() {
+			});
+		} catch (JsonProcessingException e) {
+			throw new TechnicalException("Error on converting XtaIdentifier!", e);
+		}
+	}
+
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..a58411a47551496e1813c02934e5310ef4c91188
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaConfiguration.java
@@ -0,0 +1,61 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.io.IOException;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ozgcloud.archive.common.xta.XtaProperties.XtaClientKeyStore;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.XtaClient;
+import de.ozgcloud.xta.client.config.XtaClientConfig;
+import de.ozgcloud.xta.client.config.XtaClientConfig.KeyStore;
+import de.ozgcloud.xta.client.exception.XtaClientInitializationException;
+
+@Configuration
+class XtaConfiguration {
+
+	@Bean
+	@ConditionalOnProperty(prefix = XtaProperties.XTA_PROPERTIES_PREFIX, name = "enabled")
+	XtaClient xtaClient(XtaProperties xtaProperties) {
+		try {
+			return XtaClient.from(buildXtaClientConfig(xtaProperties));
+		} catch (XtaClientInitializationException e) {
+			throw new TechnicalException("Error on initializing Xta client.", e);
+		}
+	}
+
+	XtaClientConfig buildXtaClientConfig(XtaProperties xtaProperties) {
+		return XtaClientConfig.builder()
+				.sendServiceUrl(xtaProperties.getSendServiceUrl())
+				.managementServiceUrl(xtaProperties.getManagementServiceUrl())
+				.msgBoxServiceUrl(xtaProperties.getMsgBoxServiceUrl())
+				.clientCertKeystore(buildKeystore(xtaProperties.getKeyStore()))
+				.trustStore(buildKeystore(xtaProperties.getTrustStore()))
+				.maxListItems(xtaProperties.getMaxListItems())
+				.clientIdentifiers(xtaProperties.getClientIdentifiers())
+				.build();
+	}
+
+	private KeyStore buildKeystore(XtaClientKeyStore clientCert) {
+		try {
+			return XtaClientConfig.KeyStore.builder()
+					.content(clientCert.getFile().getContentAsByteArray())
+					.type(clientCert.getType())
+					.password(clientCert.getPassword())
+					.build();
+		} catch (IOException e) {
+			throw new TechnicalException("Error on reading Xta client certificate.", e);
+		}
+	}
+
+	@Bean
+	@Lazy
+	ObjectMapper objectMapper() {
+		return new ObjectMapper();
+	}
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/XtaProperties.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java
similarity index 52%
rename from archive-manager-server/src/main/java/de/ozgcloud/archive/XtaProperties.java
rename to archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java
index 2084814f8fefdc6b5b0460cfc639dad861129199..678fe4036516ee34edc6128065096472798e4744 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/XtaProperties.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaProperties.java
@@ -1,4 +1,4 @@
-package de.ozgcloud.archive;
+package de.ozgcloud.archive.common.xta;
 
 import java.util.List;
 
@@ -17,11 +17,38 @@ import lombok.Setter;
 public class XtaProperties {
 
 	static final String XTA_PROPERTIES_PREFIX = "ozgcloud.xta";
+
+	/*
+	 * Flag to enable/disable XTA adapter usage.
+	 */
+	private boolean enabled = false;
+	/*
+	 * XTA endpoint messages are sent to.
+	 */
 	private String sendServiceUrl;
+	/*
+	 * XTA endpoint to message box.
+	 */
 	private String msgBoxServiceUrl;
+	/*
+	 * XTA endpoint to management information
+	 */
 	private String managementServiceUrl;
-	private int maxListItems;
+	/*
+	 * Maximum number of Messages loaded from message box.
+	 */
+	private int maxListItems = 50;
+	/*
+	 * Reference to client certifiaction key store.
+	 */
 	private XtaClientKeyStore keyStore;
+	/*
+	 * Reference to trust store.
+	 */
+	private XtaClientKeyStore trustStore;
+	/*
+	 * Client identifiers used to identify cleint at XTA adapter.
+	 */
 	private List<XtaIdentifier> clientIdentifiers;
 
 	private String schedulerCron;
@@ -29,8 +56,17 @@ public class XtaProperties {
 	@Getter
 	@Setter
 	public static class XtaClientKeyStore {
+		/*
+		 * Reference to key store reference.
+		 */
 		private Resource file;
-		private String type = "PKCS12";
+		/*
+		 * Type of the referenced key store.
+		 */
+		private String type;
+		/*
+		 * Password to access key store.
+		 */
 		private char[] password;
 	}
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java
new file mode 100644
index 0000000000000000000000000000000000000000..9aac41082bcaaa23dbb2b1acbadaf85411791ef5
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java
@@ -0,0 +1,41 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.util.Optional;
+
+import org.springframework.stereotype.Service;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.XtaClient;
+import de.ozgcloud.xta.client.exception.XtaClientException;
+import de.ozgcloud.xta.client.model.XtaFile;
+import de.ozgcloud.xta.client.model.XtaMessage;
+import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+@Service
+public class XtaService {
+	private static final String XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE = "XtaClient is not configured! Cannot send message to DMS.";
+
+	private final Optional<XtaClient> xtaClient;
+
+	public void sendXdomeaFile(XtaFile xdomeaFile) {
+		try {
+			getXtaClient().sendMessage(createMessage(xdomeaFile));
+		} catch (XtaClientException e) {
+			throw new TechnicalException("Error on sending xDomea message!", e);
+		}
+	}
+
+	XtaMessage createMessage(XtaFile xdomeaFile) {
+		try {
+			return XdomeaXtaMessageCreator.createInstance().createMessage(xdomeaFile);
+		} catch (XtaClientException e) {
+			throw new TechnicalException("Error on creating xDomea message!", e);
+		}
+	}
+
+	XtaClient getXtaClient() {
+		return xtaClient.orElseThrow(() -> new TechnicalException(XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE));
+	}
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java
index 0af9d44fe26c1f9cc92d6c0af711c4200b53b283..4044d715486da1fa0487d400a1b3501fc4c8dec0 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportGrpcService.java
@@ -6,7 +6,7 @@ import org.springframework.core.task.TaskExecutor;
 
 import com.google.protobuf.ByteString;
 
-import de.ozgcloud.archive.common.callcontext.CallContextInterceptor;
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import de.ozgcloud.archive.grpc.export.ExportServiceGrpc.ExportServiceImplBase;
 import de.ozgcloud.archive.grpc.export.GrpcExportVorgangRequest;
 import de.ozgcloud.archive.grpc.export.GrpcExportVorgangResponse;
@@ -17,7 +17,7 @@ import io.grpc.stub.StreamObserver;
 import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.server.service.GrpcService;
 
-@GrpcService(interceptors = { CallContextInterceptor.class })
+@GrpcService(interceptorNames = { ArchiveManagerConfiguration.CALL_CONTEXT_SERVER_INTERCEPTOR_NAME })
 @RequiredArgsConstructor
 class ExportGrpcService extends ExportServiceImplBase {
 
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java
index 169d99df79b822219f4e83c9950f839bba999e99..1aba00ad27c8df1d694853f33ebb8e8d67286060 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/export/ExportService.java
@@ -1,21 +1,29 @@
 package de.ozgcloud.archive.export;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Optional;
 import java.util.Set;
+import java.util.UUID;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+import jakarta.activation.DataHandler;
+import jakarta.activation.FileDataSource;
+
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import de.ozgcloud.archive.bescheid.ExportBescheidService;
 import de.ozgcloud.archive.common.ExportFilenameGenerator;
+import de.ozgcloud.archive.common.xta.XtaService;
 import de.ozgcloud.archive.file.ExportFileService;
 import de.ozgcloud.archive.file.OzgFile;
 import de.ozgcloud.archive.historie.ExportHistorieService;
@@ -23,9 +31,11 @@ import de.ozgcloud.archive.kommentar.ExportKommentarService;
 import de.ozgcloud.archive.postfach.ExportNachrichtService;
 import de.ozgcloud.archive.vorgang.Eingang;
 import de.ozgcloud.archive.vorgang.EingangHeader;
-import de.ozgcloud.archive.vorgang.ExportVorgangService;
+import de.ozgcloud.archive.vorgang.VorgangService;
 import de.ozgcloud.archive.vorgang.VorgangWithEingang;
+import de.ozgcloud.command.Command;
 import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.model.XtaFile;
 import de.xoev.xdomea.AbgabeAbgabe0401;
 import lombok.RequiredArgsConstructor;
 
@@ -40,11 +50,52 @@ public class ExportService {
 	private final XdomeaXmlMarshaller xDomeaXmlMarshaller;
 
 	private final ExportFileService exportFileService;
-	private final ExportVorgangService exportVorgangService;
+	@Qualifier(ArchiveManagerConfiguration.VORGANG_SERVICE_NAME) // NOSONAR
+	private final VorgangService vorgangService;
 	private final ExportHistorieService exportHistorieService;
+	@Qualifier(ArchiveManagerConfiguration.KOMMENTAR_SERVICE_NAME) // NOSONAR
 	private final ExportKommentarService exportKommentarService;
 	private final ExportNachrichtService exportNachrichtService;
 	private final ExportBescheidService exportBescheidService;
+	private final XtaService xtaService;
+
+	public void archiveVorgang(Command command) {
+		xtaService.sendXdomeaFile(buildXdomeaXtaFile(command.getVorgangId()));
+	}
+
+	XtaFile buildXdomeaXtaFile(String vorgangId) {
+		var fileNameId = createFileNameId();
+		return XtaFile.builder()
+				.name(buildXdomeaFileName(fileNameId))
+				.content(createFileContent(vorgangId, fileNameId))
+				.contentType("application/zip")
+				.build();
+	}
+
+	String createFileNameId() {
+		return UUID.randomUUID().toString();
+	}
+
+	public String buildXdomeaFileName(String fileNameId) {
+		return String.format(EXPORT_XDOMEA_FILENAME_TEMPLATE, fileNameId);
+	}
+
+	DataHandler createFileContent(String vorgangId, String fileNameId) {
+		try {
+			var tempFile = createTempFile(fileNameId);
+			var fileDataSource = new FileDataSource(tempFile);
+			writeXdomeaFileContent(vorgangId, fileNameId, fileDataSource.getOutputStream());
+			return new DataHandler(fileDataSource);
+		} catch (IOException e) {
+			throw new TechnicalException("Error on creating file content for xDomea file!", e);
+		}
+	}
+
+	File createTempFile(String fileNameId) throws IOException {
+		var tempFile = File.createTempFile(fileNameId, ".zip");
+		tempFile.deleteOnExit();
+		return tempFile;
+	}
 
 	public void writeXdomeaFileContent(String vorgangId, String filenameId, OutputStream outputStream) {
 		var exportData = collectExportData(vorgangId, filenameId);
@@ -52,7 +103,7 @@ public class ExportService {
 	}
 
 	ExportData collectExportData(String vorgangId, String filenameId) {
-		var vorgang = exportVorgangService.getVorgang(vorgangId);
+		var vorgang = vorgangService.getVorgang(vorgangId);
 		var kommentarsData = exportKommentarService.createExportData(vorgang);
 		var postfachMailData = exportNachrichtService.createExportData(vorgang);
 		var bescheidData = exportBescheidService.createExportData(vorgang);
@@ -60,9 +111,9 @@ public class ExportService {
 		var attachments = exportFileService.getAttachments(vorgang).toList();
 		var formEngineName = getFormEngineName(vorgang);
 		var abgabe = XdomeaNachrichtBuilder.builder()
-				.withKopf(exportVorgangService.createKopf(vorgang))
-				.withVorgang(exportVorgangService.createVorgangType(vorgang))
-				.withAktenzeichen(exportVorgangService.createAkteType(vorgang))
+				.withKopf(vorgangService.createKopf(vorgang))
+				.withVorgang(vorgangService.createVorgangType(vorgang))
+				.withAktenzeichen(vorgangService.createAkteType(vorgang))
 				.withRepresentations(exportFileService.createDokumentTypes(representations, formEngineName).toList())
 				.withAttachments(exportFileService.createDokumentTypes(attachments, formEngineName).toList())
 				.withHistorie(exportHistorieService.createHistorienProtokollInformationTypes(vorgang).toList())
@@ -124,8 +175,4 @@ public class ExportService {
 			throw new TechnicalException("Cannot add file to ZIP.", e);
 		}
 	}
-
-	public String buildXdomeaFileName(String fileNameId) {
-		return String.format(EXPORT_XDOMEA_FILENAME_TEMPLATE, fileNameId);
-	}
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/file/OzgFileRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/file/OzgFileRemoteService.java
index aca984a632b909c87ec502ee7e9c8b4bd9cebc91..89968a704a490af97603a2fb33bd35e0bd62e79c 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/file/OzgFileRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/file/OzgFileRemoteService.java
@@ -2,29 +2,27 @@ package de.ozgcloud.archive.file;
 
 import java.util.stream.Stream;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.GrpcUtil;
 import de.ozgcloud.vorgang.grpc.file.FileServiceGrpc.FileServiceBlockingStub;
 import de.ozgcloud.vorgang.grpc.file.GrpcGetAttachmentsRequest;
 import de.ozgcloud.vorgang.grpc.file.GrpcGetRepresentationsRequest;
+import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
 @Service
+@RequiredArgsConstructor
 class OzgFileRemoteService {
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
-	private FileServiceBlockingStub grpcService;
-	@Autowired
-	private OzgFileMapper fileMapper;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	private OzgCloudCallContextProvider contextProvider;
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME) // NOSONAR
+	private final FileServiceBlockingStub grpcService;
+	private final OzgFileMapper fileMapper;
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
+	private final OzgCloudCallContextProvider contextProvider;
 
 	public Stream<OzgFile> getAttachments(String vorgangId) {
 		return getGrpcServiceWithInterceptor().getAttachments(buildGrpcGetAttachmentsRequest(vorgangId)).getFileList().stream()
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/ExportKommentarService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/ExportKommentarService.java
index 4790c966b921543e3982778cf65bf7e35b712699..147ca0b8104ef487ecbbd00a89f2e82553476561 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/ExportKommentarService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/ExportKommentarService.java
@@ -15,10 +15,12 @@ import de.ozgcloud.archive.vorgang.VorgangWithEingang;
 import lombok.RequiredArgsConstructor;
 
 @RequiredArgsConstructor
-@Service
+@Service(ArchiveManagerConfiguration.KOMMENTAR_SERVICE_NAME)
 public class ExportKommentarService {
 
+	@Qualifier(ArchiveManagerConfiguration.KOMMENTAR_REMOTE_SERVICE_NAME) // NOSONAR
 	private final KommentarRemoteService kommentarRemoteService;
+	@Qualifier(ArchiveManagerConfiguration.BINARY_FILE_SERVICE_NAME) // NOSONAR
 	private final BinaryFileService binaryFileService;
 	@Qualifier(ArchiveManagerConfiguration.USER_SERVICE_NAME) // NOSONAR
 	private final UserService userService;
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/KommentarRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/KommentarRemoteService.java
index 0fc1e206b70090a2ab26a0714d44139c5c1bad26..f42be6e0c777fbae782c822e3cef108d7ec812f1 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/KommentarRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/kommentar/KommentarRemoteService.java
@@ -25,30 +25,28 @@ package de.ozgcloud.archive.kommentar;
 
 import java.util.stream.Stream;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.GrpcUtil;
 import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcFindVorgangAttachedItemRequest;
 import de.ozgcloud.vorgang.vorgangAttachedItem.VorgangAttachedItemServiceGrpc.VorgangAttachedItemServiceBlockingStub;
+import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
-@Service
+@Service(ArchiveManagerConfiguration.KOMMENTAR_REMOTE_SERVICE_NAME) // NOSONAR
+@RequiredArgsConstructor
 class KommentarRemoteService {
 
 	static final String ITEM_NAME = "Kommentar";
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
-	private VorgangAttachedItemServiceBlockingStub grpcService;
-	@Autowired
-	private KommentarMapper mapper;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	private OzgCloudCallContextProvider contextProvider;
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME)
+	private final VorgangAttachedItemServiceBlockingStub grpcService;
+	private final KommentarMapper mapper;
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
+	private final OzgCloudCallContextProvider contextProvider;
 
 	public Stream<Kommentar> findByVorgangId(String vorgangId) {
 		var response = getGrpcServiceWithInterceptor().find(buildFindRequest(vorgangId));
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailMapper.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailMapper.java
index 97aa69608ea3e5868d60118525b6200a570dbe75..85c5806c361a24443e04d784a2e79bfee1ee8936 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailMapper.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailMapper.java
@@ -25,6 +25,7 @@ package de.ozgcloud.archive.postfach;
 
 import java.util.List;
 
+import org.apache.commons.lang3.StringUtils;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.MappingConstants;
@@ -37,7 +38,7 @@ import de.ozgcloud.archive.common.TimeMapper;
 import de.ozgcloud.common.binaryfile.FileId;
 import de.ozgcloud.nachrichten.postfach.GrpcPostfachMail;
 
-@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, uses = TimeMapper.class)
+@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, uses = TimeMapper.class, imports = StringUtils.class)
 interface PostfachMailMapper {
 
 	@Mapping(target = "attachment", ignore = true)
@@ -45,6 +46,7 @@ interface PostfachMailMapper {
 	@ValueMapping(target = MappingConstants.NULL, source = "UNRECOGNIZED")
 	@ValueMapping(target = MappingConstants.NULL, source = "UNDEFINED")
 	@Mapping(target = "attachments", source = "attachmentList")
+	@Mapping(target = "createdBy", expression = "java(StringUtils.trimToNull(grpcPostfachMail.getCreatedBy()))")
 	PostfachMail toPostfachMail(GrpcPostfachMail grpcPostfachMail);
 
 	default List<FileId> fromStringList(ProtocolStringList stringList) {
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailRemoteService.java
index 26cf2d7e8d59fe78ed1a627265ac5e9a7ce15c75..6510a7cb91cde5ac1a01751cdc2b636b5696ba4e 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/postfach/PostfachMailRemoteService.java
@@ -28,7 +28,7 @@ import java.util.stream.Stream;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import de.ozgcloud.archive.common.GrpcUtil;
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
 import de.ozgcloud.nachrichten.postfach.GrpcFindPostfachMailsRequest;
 import de.ozgcloud.nachrichten.postfach.PostfachServiceGrpc.PostfachServiceBlockingStub;
 import net.devh.boot.grpc.client.inject.GrpcClient;
@@ -36,7 +36,7 @@ import net.devh.boot.grpc.client.inject.GrpcClient;
 @Service
 class PostfachMailRemoteService {
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME)
 	private PostfachServiceBlockingStub grpcService;
 	@Autowired
 	private PostfachMailMapper postfachNachrichtMapper;
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java
index c071f50160f310d78427af76b6d2f21f265da6c0..e863cb332126c190d4808cdc5c65a64777c0a2ad 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ArchiveEventListener.java
@@ -23,16 +23,9 @@
  */
 package de.ozgcloud.archive.vorgang;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Optional;
-import java.util.UUID;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 
-import jakarta.activation.DataHandler;
-import jakarta.activation.FileDataSource;
-
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.ApplicationEventPublisher;
@@ -41,7 +34,8 @@ import org.springframework.security.core.context.SecurityContext;
 import org.springframework.stereotype.Component;
 
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.callcontext.ArchiveCallContext;
+import de.ozgcloud.archive.attributes.ClientAttributeService;
+import de.ozgcloud.archive.common.callcontext.CallContextUser;
 import de.ozgcloud.archive.common.callcontext.CurrentUserService;
 import de.ozgcloud.archive.common.command.CommandService;
 import de.ozgcloud.archive.common.errorhandling.TimeoutException;
@@ -50,12 +44,6 @@ import de.ozgcloud.command.Command;
 import de.ozgcloud.command.CommandCreatedEvent;
 import de.ozgcloud.command.CommandFailedEvent;
 import de.ozgcloud.command.VorgangLockedEvent;
-import de.ozgcloud.common.errorhandling.TechnicalException;
-import de.ozgcloud.xta.client.XtaClient;
-import de.ozgcloud.xta.client.exception.XtaClientException;
-import de.ozgcloud.xta.client.model.XtaFile;
-import de.ozgcloud.xta.client.model.XtaMessage;
-import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 
@@ -64,124 +52,69 @@ import lombok.extern.log4j.Log4j2;
 @Log4j2
 class ArchiveEventListener {
 
+	static final int MAXIMUM_CHECKS_FOR_PENDING_COMMANDS = 3;
 	static final int WAIT_INTERVAL = 30 * 1000;
 	private static final String LOG_MESSAGE_TEMPLATE = "{}. Command failed.";
 	private static final String ERROR_MESSAGE_TEMPLATE = "Error on executing %s Command (id: %s).";
 
 	static final String ARCHIVE_VORGANG_ORDER = "ARCHIVE_VORGANG";
-	private static final String IS_ARCHIVE_VORGANG_EVENT = "{T(de.ozgcloud.archive.vorgang.ArchiveEventListener)."
-			+ "IS_ARCHIVE_VORGANG_COMMAND.test(event.getSource())}";
+	private static final String IS_ARCHIVE_VORGANG_EVENT = "{T(de.ozgcloud.archive.vorgang.ArchiveEventListener).IS_ARCHIVE_VORGANG_COMMAND.test(event.getSource())}";
 	public static final Predicate<Command> IS_ARCHIVE_VORGANG_COMMAND = command -> ARCHIVE_VORGANG_ORDER.equals(command.getOrder());
 
 	private static final String IS_LOCKED_BY_ARCHIVE_MANAGER_EVENT = "{T(de.ozgcloud.archive.vorgang.ArchiveEventListener)."
 			+ "IS_LOCK_BY_ARCHIVE_MANAGER_COMMAND.test(event.getCommand())}";
-	public static final Predicate<Command> IS_LOCK_BY_ARCHIVE_MANAGER_COMMAND = command -> ArchiveCallContext.CLIENT_NAME
+	public static final Predicate<Command> IS_LOCK_BY_ARCHIVE_MANAGER_COMMAND = command -> CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME
 			.equals(command.getCreatedByClientName());
 
 	@Qualifier(ArchiveManagerConfiguration.CURRENT_USER_SERVICE_NAME) // NOSONAR
 	private final CurrentUserService currentUserService;
+
+	@Qualifier(ArchiveManagerConfiguration.CLIENT_ATTRIBUTE_SERVICE_NAME) // NOSONAR
+	private final ClientAttributeService clientAttributeService;
+
+	@Qualifier(ArchiveManagerConfiguration.VORGANG_SERVICE_NAME) // NOSONAR
+	private final VorgangService vorgangService;
+
 	private final ApplicationEventPublisher eventPublisher;
-	private final ExportService exportService;
-	private final Optional<XtaClient> xtaClient;
 	private final CommandService commandService;
+	private final ExportService exportService;
 
 	@EventListener(condition = IS_ARCHIVE_VORGANG_EVENT)
 	void onArchiveVorgangEvent(CommandCreatedEvent event) {
-		runWithSecurityContext(event.getSource(), this::doArchiveVorgang);
+		runWithSecurityContext(event.getSource(), this::doLockVorgang);
 	}
 
-	void doArchiveVorgang(Command command) {
-	}
-
-	private String buildErrorMessage(String message, Exception cause) {
-		try {
-			StringBuilder sb = new StringBuilder(message);
-			if (StringUtils.isNotBlank(cause.getMessage())) {
-				sb.append(" Cause: ").append(cause.getMessage());
-			}
-			return sb.toString();
-		} catch (Exception e2) {
-			LOG.error("Error in building Error Message (sick).", e2);
-			return message;
-		}
+	void doLockVorgang(Command command) {
+		clientAttributeService.setVorgangArchiving(command.getVorgangId());
+		vorgangService.lockVorgang(command);
 	}
 
 	@EventListener(condition = IS_LOCKED_BY_ARCHIVE_MANAGER_EVENT)
 	public void onVorgangLockedEvent(VorgangLockedEvent event) {
 		waitForPendingCommandsToFinish(event.getCommand().getVorgangId(), WAIT_INTERVAL);
-		runWithSecurityContext(event.getCommand(), command -> sendXdomeaFile(buildXdomeaXtaFile(command.getVorgangId())));
+		runWithSecurityContext(event.getCommand(), exportService::archiveVorgang);
 	}
 
 	void waitForPendingCommandsToFinish(String vorgangId, long waitIntervalInMillis) {
 		var numberOfAttempts = 0;
-		while (commandService.hasPendingCommands(vorgangId)) {
+		while (commandService.hasPendingCommandsExceptWithOrder(vorgangId, ARCHIVE_VORGANG_ORDER)) {
 			numberOfAttempts++;
-			if (numberOfAttempts >= 3) {
+			if (numberOfAttempts >= MAXIMUM_CHECKS_FOR_PENDING_COMMANDS) {
 				throw new TimeoutException("Waiting for pending commands");
 			}
 			try {
 				Thread.sleep(waitIntervalInMillis);
 			} catch (InterruptedException e) {
-				LOG.error("Error while waiting for commads to finish.", e);
+				LOG.error("Error while waiting for commands to finish.", e);
 				Thread.currentThread().interrupt();
 			}
 		}
 	}
 
-	XtaFile buildXdomeaXtaFile(String vorgangId) {
-		var fileNameId = createFileNameId();
-		return XtaFile.builder()
-				.name(exportService.buildXdomeaFileName(fileNameId))
-				.content(createFileContent(vorgangId, fileNameId))
-				.contentType("application/zip")
-				.build();
-	}
-
-	String createFileNameId() {
-		return UUID.randomUUID().toString();
-	}
-
-	DataHandler createFileContent(String vorgangId, String fileNameId) {
-		try {
-			var tempFile = createTempFile(fileNameId);
-			var fileDataSource = new FileDataSource(tempFile);
-			exportService.writeXdomeaFileContent(vorgangId, fileNameId, fileDataSource.getOutputStream());
-			return new DataHandler(fileDataSource);
-		} catch (IOException e) {
-			throw new TechnicalException("Error on creating file content for xDomea file!", e);
-		}
-	}
-
-	File createTempFile(String fileNameId) throws IOException {
-		var tempFile = File.createTempFile(fileNameId, ".zip");
-		tempFile.deleteOnExit();
-		return tempFile;
-	}
-
-	void sendXdomeaFile(XtaFile xdomeaFile) {
-		var message = createMessage(xdomeaFile);
-		xtaClient.ifPresentOrElse(client -> {
-			try {
-				client.sendMessage(message);
-			} catch (XtaClientException e) {
-				throw new TechnicalException("Error on sending xDomea message!", e);
-			}
-		}, () -> LOG.error("XtaClient is not configured. Cannot send message"));
-
-	}
-
-	XtaMessage createMessage(XtaFile xdomeaFile) {
-		try {
-			return XdomeaXtaMessageCreator.createInstance().createMessage(xdomeaFile);
-		} catch (XtaClientException e) {
-			throw new TechnicalException("Error on creating xDomea message!", e);
-		}
-	}
-
 	void runWithSecurityContext(Command command, Consumer<Command> commandExecutor) {
 		SecurityContext prevContext = null;
 		try {
-			prevContext = currentUserService.startSecurityContext(command);
+			prevContext = currentUserService.startAndReturnPreviousSecurityContext(command);
 			commandExecutor.accept(command);
 		} catch (Exception e) {
 			var errorMessage = ERROR_MESSAGE_TEMPLATE.formatted(command.getOrder(), command.getId());
@@ -191,4 +124,17 @@ class ArchiveEventListener {
 			currentUserService.resetSecurityContext(prevContext);
 		}
 	}
+
+	private String buildErrorMessage(String message, Exception cause) {
+		try {
+			StringBuilder sb = new StringBuilder(message);
+			if (StringUtils.isNotBlank(cause.getMessage())) {
+				sb.append(" Cause: ").append(cause.getMessage());
+			}
+			return sb.toString();
+		} catch (Exception e2) {
+			LOG.error("Error in building Error Message (sick).", e2);
+			return message;
+		}
+	}
 }
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ExportVorgangService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ExportVorgangService.java
deleted file mode 100644
index 4e3644613b0233d654d652afae09ef2c69cbaa84..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/ExportVorgangService.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package de.ozgcloud.archive.vorgang;
-
-import java.util.Optional;
-import java.util.UUID;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Service;
-
-import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.xoev.xdomea.AkteType;
-import de.xoev.xdomea.AllgemeineMetadatenType;
-import de.xoev.xdomea.IdentifikationObjektType;
-import de.xoev.xdomea.NkAbgabeType;
-import de.xoev.xdomea.VorgangType;
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-@Service
-public class ExportVorgangService {
-
-	@Qualifier(ArchiveManagerConfiguration.VORGANG_REMOTE_MANAGER_SERVICE_NAME) // NOSONAR
-	private final VorgangRemoteService vorgangRemoteService;
-
-	private final VorgangTypeCreator vorgangTypeCreator;
-	private final KopfCreator kopfCreator;
-
-	public VorgangWithEingang getVorgang(String vorgangId) {
-		return vorgangRemoteService.findVorgangWithEingang(vorgangId);
-	}
-
-	public VorgangType createVorgangType(VorgangWithEingang vorgangWithEingang) {
-		return vorgangTypeCreator.create(vorgangWithEingang);
-	}
-
-	public NkAbgabeType createKopf(VorgangWithEingang vorgangWithEingang) {
-		return kopfCreator.createKopf(vorgangWithEingang);
-	}
-
-	public AkteType createAkteType(VorgangWithEingang vorgangWithEingang) {
-		var akteType = new AkteType();
-		akteType.setIdentifikation(createIdentifikationObjektType());
-		akteType.setAllgemeineMetadaten(createAllgemeineMetadatenType(vorgangWithEingang));
-		return akteType;
-	}
-
-	IdentifikationObjektType createIdentifikationObjektType() {
-		var identifikationObjektType = new IdentifikationObjektType();
-		identifikationObjektType.setID(UUID.randomUUID().toString());
-		return identifikationObjektType;
-	}
-
-	AllgemeineMetadatenType createAllgemeineMetadatenType(VorgangWithEingang vorgangWithEingang) {
-		var allgemeineMetadatenType = new AllgemeineMetadatenType();
-		allgemeineMetadatenType.setKennzeichen(Optional.ofNullable(vorgangWithEingang.getAktenzeichen()).orElse(StringUtils.EMPTY));
-		return allgemeineMetadatenType;
-	}
-}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangRemoteService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangRemoteService.java
index f78836c848ab2d65bb92f2717a1578421053d224..3ae751e6d9f0131bc611195e49408948d26fc1bb 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangRemoteService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangRemoteService.java
@@ -1,13 +1,11 @@
 package de.ozgcloud.archive.vorgang;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
 import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
 import de.ozgcloud.archive.ArchiveManagerConfiguration;
-import de.ozgcloud.archive.common.GrpcUtil;
 import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest;
 import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub;
 import lombok.RequiredArgsConstructor;
@@ -17,14 +15,14 @@ import net.devh.boot.grpc.client.inject.GrpcClient;
 @RequiredArgsConstructor
 class VorgangRemoteService {
 
-	@GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT)
-	private VorgangServiceBlockingStub grpcService;
-	@Autowired
+	@GrpcClient(ArchiveManagerConfiguration.GRPC_VORGANG_MANAGER_CLIENT_NAME) // NOSONAR
+	private final VorgangServiceBlockingStub grpcService;
+
 	@Qualifier(ArchiveManagerConfiguration.VORGANG_WITH_EINGANG_MAPPER_NAME) // NOSONAR
-	private VorgangWithEingangMapper vorgangWithEingangMapper;
-	@Autowired
-	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_CALL_CONTEXT_PROVIDER_NAME)
-	private OzgCloudCallContextProvider contextProvider;
+	private final VorgangWithEingangMapper vorgangWithEingangMapper;
+
+	@Qualifier(ArchiveManagerConfiguration.CALL_CONTEXT_PROVIDER_NAME) // NOSONAR
+	private final OzgCloudCallContextProvider contextProvider;
 
 	public VorgangWithEingang findVorgangWithEingang(String vorgangId) {
 		return vorgangWithEingangMapper
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java
new file mode 100644
index 0000000000000000000000000000000000000000..497e0a0d40bb8d7601673e8aaaf2923c2088498e
--- /dev/null
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/vorgang/VorgangService.java
@@ -0,0 +1,109 @@
+package de.ozgcloud.archive.vorgang;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import de.ozgcloud.apilib.common.command.OzgCloudCommand;
+import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
+import de.ozgcloud.apilib.common.command.OzgCloudCreateSubCommandsRequest;
+import de.ozgcloud.apilib.common.command.grpc.CommandMapper;
+import de.ozgcloud.apilib.user.OzgCloudUserId;
+import de.ozgcloud.archive.ArchiveManagerConfiguration;
+import de.ozgcloud.archive.common.callcontext.CallContextUser;
+import de.ozgcloud.archive.common.callcontext.CurrentUserService;
+import de.ozgcloud.command.Command;
+import de.xoev.xdomea.AkteType;
+import de.xoev.xdomea.AllgemeineMetadatenType;
+import de.xoev.xdomea.IdentifikationObjektType;
+import de.xoev.xdomea.NkAbgabeType;
+import de.xoev.xdomea.VorgangType;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+@Service(ArchiveManagerConfiguration.VORGANG_SERVICE_NAME) // NOSONAR
+public class VorgangService {
+
+	static final String LOCK_VORGANG_ORDER = "LOCK_VORGANG";
+	static final String KEY_LOCK_VORGANG_REASON = "reason";
+	static final String LOCK_VORGANG_REASON = "Vorgang wird archiviert.";
+	static final String SUB_COMMAND_EXECUTION_MODE = "PARALLEL";
+
+	@Qualifier(ArchiveManagerConfiguration.VORGANG_REMOTE_MANAGER_SERVICE_NAME) // NOSONAR
+	private final VorgangRemoteService vorgangRemoteService;
+	@Qualifier(ArchiveManagerConfiguration.OZGCLOUD_COMMAND_SERVICE_NAME) // NOSONAR
+	private final OzgCloudCommandService ozgCloudCommandService;
+	@Qualifier(ArchiveManagerConfiguration.CURRENT_USER_SERVICE_NAME) // NOSONAR
+	private final CurrentUserService currentUserService;
+	private final CommandMapper commandMapper;
+
+	private final VorgangTypeCreator vorgangTypeCreator;
+	private final KopfCreator kopfCreator;
+
+	public VorgangWithEingang getVorgang(String vorgangId) {
+		return vorgangRemoteService.findVorgangWithEingang(vorgangId);
+	}
+
+	public VorgangType createVorgangType(VorgangWithEingang vorgangWithEingang) {
+		return vorgangTypeCreator.create(vorgangWithEingang);
+	}
+
+	public NkAbgabeType createKopf(VorgangWithEingang vorgangWithEingang) {
+		return kopfCreator.createKopf(vorgangWithEingang);
+	}
+
+	public AkteType createAkteType(VorgangWithEingang vorgangWithEingang) {
+		var akteType = new AkteType();
+		akteType.setIdentifikation(createIdentifikationObjektType());
+		akteType.setAllgemeineMetadaten(createAllgemeineMetadatenType(vorgangWithEingang));
+		return akteType;
+	}
+
+	IdentifikationObjektType createIdentifikationObjektType() {
+		var identifikationObjektType = new IdentifikationObjektType();
+		identifikationObjektType.setID(UUID.randomUUID().toString());
+		return identifikationObjektType;
+	}
+
+	AllgemeineMetadatenType createAllgemeineMetadatenType(VorgangWithEingang vorgangWithEingang) {
+		var allgemeineMetadatenType = new AllgemeineMetadatenType();
+		allgemeineMetadatenType.setKennzeichen(Optional.ofNullable(vorgangWithEingang.getAktenzeichen()).orElse(StringUtils.EMPTY));
+		return allgemeineMetadatenType;
+	}
+
+	public void lockVorgang(Command command) {
+		ozgCloudCommandService.addSubCommands(buildCreateSubCommandsRequest(command.getId(), buildLockVorgangSubCommand(command)));
+	}
+
+	OzgCloudCommand buildLockVorgangSubCommand(Command command) {
+		var commandBuilder = OzgCloudCommand.builder()
+				.order(LOCK_VORGANG_ORDER)
+				.vorgangId(commandMapper.toOzgCloudVorgangId(command.getVorgangId()))
+				.relationId(commandMapper.mapRelationId(command.getVorgangId()))
+				.relationVersion(command.getRelationVersion())
+				.bodyObject(buildObjectBody());
+		getUserId().ifPresent(commandBuilder::createdBy);
+		return commandBuilder.build();
+	}
+
+	Map<String, Object> buildObjectBody() {
+		return Map.of(KEY_LOCK_VORGANG_REASON, LOCK_VORGANG_REASON);
+	}
+
+	Optional<OzgCloudUserId> getUserId() {
+		return currentUserService.findUser().flatMap(CallContextUser::getUserId).map(commandMapper::toOzgCloudUserId);
+	}
+
+	OzgCloudCreateSubCommandsRequest buildCreateSubCommandsRequest(String parentCommandId, OzgCloudCommand command) {
+		return OzgCloudCreateSubCommandsRequest.builder()
+				.parentId(parentCommandId)
+				.subCommand(command)
+				.completedIfSubsCompleted(false)
+				.executionMode(SUB_COMMAND_EXECUTION_MODE)
+				.build();
+	}
+}
diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/xta/XtaService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/xta/XtaService.java
index f1346ebcd1fba179d0ddd5fd2a38a11d92c80e08..59cf635ac808bd3557ba865b923f891148807e20 100644
--- a/archive-manager-server/src/main/java/de/ozgcloud/archive/xta/XtaService.java
+++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/xta/XtaService.java
@@ -6,6 +6,7 @@ import org.apache.commons.collections.CollectionUtils;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 
+import de.ozgcloud.archive.common.command.ArchiveManagerCommand;
 import de.ozgcloud.archive.common.command.CommandOrder;
 import de.ozgcloud.archive.common.command.CommandService;
 import de.ozgcloud.archive.xta.XtaImportConfirmationHandler.XtaAbgabeHandler;
@@ -61,11 +62,11 @@ class XtaService {
 		}
 	}
 
-	private List<Command> findPendingArchiveVorgangCommands(String vorgangId) {
+	private List<ArchiveManagerCommand> findPendingArchiveVorgangCommands(String vorgangId) {
 		return commandService.findPending(vorgangId, CommandOrder.ARCHIVE_VORGANG).toList();
 	}
 
-	void evaluateAbgabe(XtaAbgabeHandler abgabeHandler, List<Command> pendingCommands) {
+	void evaluateAbgabe(XtaAbgabeHandler abgabeHandler, List<ArchiveManagerCommand> pendingCommands) {
 		if (pendingCommands.size() > 1) {
 			LOG.warn("Multiple pending commands found for vorgang: %s.", abgabeHandler.getVorgangId());
 		}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/ArchiveTestApplication.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/ArchiveManagerTestApplication.java
similarity index 70%
rename from archive-manager-server/src/test/java/de/ozgcloud/archive/ArchiveTestApplication.java
rename to archive-manager-server/src/test/java/de/ozgcloud/archive/ArchiveManagerTestApplication.java
index 68472284ae21c0c15511a344aa57883b719f69d4..5bb43294d647a7e3ae8962348dcd08ebb3fb727e 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/ArchiveTestApplication.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/ArchiveManagerTestApplication.java
@@ -2,30 +2,33 @@ package de.ozgcloud.archive;
 
 import java.util.TimeZone;
 
+import org.mapstruct.factory.Mappers;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.info.BuildProperties;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
 
+import de.ozgcloud.apilib.client_attribute.grpc.OzgCloudClientAttributeMapper;
 import de.ozgcloud.apilib.common.command.grpc.CommandMapper;
-import de.ozgcloud.apilib.common.command.grpc.CommandMapperImpl;
 import de.ozgcloud.apilib.file.grpc.OzgCloudFileMapper;
 import de.ozgcloud.apilib.user.UserProfileMapper;
 import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper;
 import de.ozgcloud.apilib.vorgang.grpc.OzgCloudVorgangMapper;
-import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub;
+import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc;
 import de.ozgcloud.xta.client.XtaClient;
 
-@SpringBootApplication(scanBasePackages = { "de.ozgcloud" })
-public class ArchiveTestApplication {
+@SpringBootApplication
+@ComponentScan({ "de.ozgcloud.*" })
+public class ArchiveManagerTestApplication {
 
 	@MockBean
 	private OzgCloudVorgangMapper vorgangMapper;
 	@MockBean
-	private VorgangServiceBlockingStub vorgangServiceStub;
+	private VorgangServiceGrpc.VorgangServiceBlockingStub vorgangServiceStub;
 	@MockBean
 	private OzgCloudVorgangIdMapper vorgangIdMapper;
 	@MockBean
@@ -36,10 +39,12 @@ public class ArchiveTestApplication {
 	private BuildProperties properties;
 	@MockBean
 	private XtaClient xtaClient;
+	@MockBean
+	private OzgCloudClientAttributeMapper clientAttributeMapper;
 
 	public static void main(String[] args) {
 		TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-		SpringApplication.run(ArchiveTestApplication.class, args);
+		SpringApplication.run(ArchiveManagerTestApplication.class, args);
 	}
 
 	@Bean
@@ -49,6 +54,6 @@ public class ArchiveTestApplication {
 
 	@Bean
 	CommandMapper commandMapper() {
-		return new CommandMapperImpl();
+		return Mappers.getMapper(CommandMapper.class);
 	}
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextMapperTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextMapperTest.java
deleted file mode 100644
index 9f6b7bf30bafe159d441694294509113035ff5c1..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextMapperTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-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.mapstruct.factory.Mappers;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-
-import de.ozgcloud.archive.common.user.OzgCloudUserIdMapper;
-
-class ArchiveCallContextMapperTest {
-
-	@InjectMocks
-	private final ArchiveCallContextMapper mapper = Mappers.getMapper(ArchiveCallContextMapper.class);
-
-	@Mock
-	private OzgCloudUserIdMapper ozgCloudUserIdMapper;
-
-	@Nested
-	class TestToOzgCloudCallContext {
-
-		@BeforeEach
-		void setUpCallToUserIdMapper() {
-			when(ozgCloudUserIdMapper.fromString(any())).thenCallRealMethod();
-		}
-
-		@Test
-		void shouldMap() {
-			var mappedContext = mapper.toOzgCloudCallContext(ArchiveCallContextTestFactory.create());
-
-			assertThat(mappedContext).usingRecursiveComparison().isEqualTo(CallContextTestFactory.create());
-		}
-	}
-}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextTestFactory.java
deleted file mode 100644
index 004f98698822d130b8b91a17d0eb99025b04eed7..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/ArchiveCallContextTestFactory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-import static de.ozgcloud.common.grpc.GrpcUtil.*;
-
-import java.util.List;
-import java.util.UUID;
-
-import com.thedeanda.lorem.LoremIpsum;
-
-import de.ozgcloud.archive.common.callcontext.ArchiveCallContext.ArchiveCallContextBuilder;
-import io.grpc.Metadata;
-
-public class ArchiveCallContextTestFactory {
-
-	public static final String REQUEST_ID = UUID.randomUUID().toString();
-	public static final String USER_ID = UUID.randomUUID().toString();
-	public static final String CLIENT_NAME = LoremIpsum.getInstance().getName();
-	public static final List<String> ORGANISATIONS_EINHEITEN_IDS = List.of(UUID.randomUUID().toString());
-	public static final Boolean ACCESS_LIMITED = true;
-
-	public static ArchiveCallContext create() {
-		return createBuilder()
-				.build();
-	}
-
-	public static ArchiveCallContextBuilder createBuilder() {
-		return ArchiveCallContext.builder()
-				.requestId(REQUEST_ID)
-				.clientName(CLIENT_NAME)
-				.userId(USER_ID)
-				.accessLimited(ACCESS_LIMITED)
-				.accessLimitedToOrgaIds(ORGANISATIONS_EINHEITEN_IDS);
-	}
-
-	public static Metadata createMetadata() {
-		var metadata = new Metadata();
-		metadata.put(createKeyOf(CallContextInterceptor.KEY_ACCESS_LIMITED), ACCESS_LIMITED.toString().getBytes());
-		metadata.put(createKeyOf(CallContextInterceptor.KEY_ACCESS_LIMITED_ORGAID), ORGANISATIONS_EINHEITEN_IDS.get(0).getBytes());
-		metadata.put(createKeyOf(CallContextInterceptor.KEY_USER_ID), USER_ID.getBytes());
-		return metadata;
-	}
-}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextGrpcServerInterceptorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextGrpcServerInterceptorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..437490ce8620a3f5af6f6b587fae62e2a7e021ad
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextGrpcServerInterceptorTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.archive.common.callcontext;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import org.apache.logging.log4j.CloseableThreadContext;
+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.springframework.test.util.ReflectionTestUtils;
+
+import de.ozgcloud.common.grpc.GrpcUtil;
+import io.grpc.Metadata;
+import io.grpc.ServerCall;
+
+class CallContextGrpcServerInterceptorTest {
+
+	@InjectMocks
+	private CallContextGrpcServerInterceptor interceptor;
+
+	@Mock
+	private CurrentUserService currentUserService;
+	@Mock
+	private CallContextMapper callContextMapper;
+	@Mock
+	private ServerCall.Listener<RequestTest> callListener;
+	@Mock
+	private Metadata metadata;
+
+	private CallContextGrpcServerInterceptor.LogContextSettingListener<RequestTest> listener;
+
+	@BeforeEach
+	void init() {
+		listener = spy(interceptor.new LogContextSettingListener<>(callListener, metadata));
+	}
+
+	@Nested
+	class TestGetRequestId {
+
+		@Test
+		void shouldCallGetRequestId() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				listener.getRequestId(metadata);
+
+				grpcUtilMock.verify(() -> GrpcUtil.getRequestId(metadata));
+			}
+		}
+
+		@Test
+		void shouldGetRequestIdFromMetadata() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				var requestId = UUID.randomUUID().toString();
+				grpcUtilMock.when(() -> GrpcUtil.getRequestId(any())).thenReturn(Optional.of(requestId));
+
+				var result = listener.getRequestId(metadata);
+
+				assertThat(result).isEqualTo(requestId);
+			}
+		}
+
+		@Test
+		void shouldReturnGeneratedId() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				grpcUtilMock.when(() -> GrpcUtil.getRequestId(any())).thenReturn(Optional.empty());
+
+				var result = listener.getRequestId(metadata);
+
+				assertThat(result).isNotEmpty();
+			}
+		}
+	}
+
+	@Nested
+	class TestOnMessage {
+
+		@Test
+		void shouldCallDoSurroundOn() {
+			doNothing().when(listener).doSurroundOn(any());
+
+			listener.onMessage(new RequestTest());
+
+			verify(listener).doSurroundOn(any());
+		}
+	}
+
+	@Nested
+	class TestOnHalfClose {
+
+		@Test
+		void shouldCallDoSurroundOn() {
+			doNothing().when(listener).doSurroundOn(any());
+
+			listener.onHalfClose();
+
+			verify(listener).doSurroundOn(any());
+		}
+	}
+
+	@Nested
+	class TestOnCancel {
+
+		@Test
+		void shouldCallDoSurroundOn() {
+			doNothing().when(listener).doSurroundOn(any());
+
+			listener.onCancel();
+
+			verify(listener).doSurroundOn(any());
+		}
+	}
+
+	@Nested
+	class TestOnComplete {
+
+		@Test
+		void shouldCallDoSurroundOn() {
+			doNothing().when(listener).doSurroundOn(any());
+
+			listener.onComplete();
+
+			verify(listener).doSurroundOn(any());
+		}
+	}
+
+	@Nested
+	class TestOnReady {
+
+		@Test
+		void shouldCallDoSurroundOn() {
+			doNothing().when(listener).doSurroundOn(any());
+
+			listener.onReady();
+
+			verify(listener).doSurroundOn(any());
+		}
+	}
+
+	@Nested
+	class TestDoSurroundOn {
+
+		@Mock
+		private Runnable runnable;
+
+		private String requestId;
+
+		@BeforeEach
+		void init() {
+			requestId = (String) ReflectionTestUtils.getField(listener, "requestId");
+		}
+
+		@Test
+		void shouldSetThreadContext() {
+			try (var contextMock = mockStatic(CloseableThreadContext.class)) {
+				doSurroundOn();
+
+				contextMock.verify(() -> CloseableThreadContext.put(GrpcUtil.KEY_REQUEST_ID, requestId));
+			}
+		}
+
+		@Test
+		void shouldCallToCallContextMapper() {
+			doSurroundOn();
+
+			verify(callContextMapper).toCallContextUser(metadata, requestId);
+		}
+
+		@Test
+		void shouldCallStartSecurityContext() {
+			var user = CallContextUserTestFactory.create();
+			when(callContextMapper.toCallContextUser(any(), any())).thenReturn(user);
+
+			doSurroundOn();
+
+			verify(currentUserService).startAndReturnPreviousSecurityContext(user);
+		}
+
+		@Test
+		void shouldExecuteRunnable() {
+			doSurroundOn();
+
+			verify(runnable).run();
+		}
+
+		@Test
+		void shouldResetSecurityContext() {
+			doSurroundOn();
+
+			verify(currentUserService).resetSecurityContext(any());
+		}
+
+		@Test
+		void shouldResetSecurityContextOnException() {
+			doThrow(new RuntimeException()).when(runnable).run();
+
+			try {
+				doSurroundOn();
+			} catch (RuntimeException e) {
+				// expected
+			}
+
+			verify(currentUserService).resetSecurityContext(any());
+		}
+
+		private void doSurroundOn() {
+			listener.doSurroundOn(runnable);
+		}
+	}
+
+	private record RequestTest() {
+	}
+
+	private record ResponseTest() {
+	}
+}
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextInterceptorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextInterceptorTest.java
deleted file mode 100644
index 644c95dfbb8a9b4161bf1ce709589240635c9f4b..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextInterceptorTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package de.ozgcloud.archive.common.callcontext;
-
-import static org.assertj.core.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mock;
-import org.mockito.MockedStatic;
-import org.mockito.Spy;
-
-import io.grpc.Context;
-import io.grpc.Contexts;
-import io.grpc.Metadata;
-import io.grpc.ServerCall;
-import io.grpc.ServerCall.Listener;
-import io.grpc.ServerCallHandler;
-
-class CallContextInterceptorTest {
-
-	@Spy
-	private CallContextInterceptor interceptor;
-
-	@Nested
-	class TestInterceptCall {
-
-		@Mock
-		private ServerCall<Object, Object> call;
-		@Mock
-		private Metadata headers;
-		@Mock
-		private ServerCallHandler<Object, Object> next;
-		@Mock
-		private Context grpcContext;
-		@Mock
-		private Context newGrpcContext;
-		@Mock
-		private Listener<Object> listener;
-
-		private MockedStatic<Context> mockedStaticContext;
-
-		private final ArchiveCallContext archiveCallContext = ArchiveCallContextTestFactory.create();
-
-		@BeforeEach
-		void setUpMock() {
-			doReturn(archiveCallContext).when(interceptor).createArchiveCallContext(headers);
-			mockedStaticContext = mockStatic(Context.class);
-			mockedStaticContext.when(Context::current).thenReturn(grpcContext);
-			when(grpcContext.withValue(CallContextInterceptor.CONTEXT_KEY_CALL_CONTEXT, archiveCallContext)).thenReturn(newGrpcContext);
-		}
-
-		@AfterEach
-		void closeMock() {
-			mockedStaticContext.close();
-		}
-
-		@Test
-		void shouldCreateArchiveCallContext() {
-			intercept();
-
-			verify(interceptor).createArchiveCallContext(headers);
-		}
-
-		@Test
-		void shouldSetArchiveCallContextInGrpcContext() {
-			intercept();
-
-			verify(grpcContext).withValue(CallContextInterceptor.CONTEXT_KEY_CALL_CONTEXT, archiveCallContext);
-		}
-
-		@Test
-		void shouldAttachNewGrpcContextToCall() {
-			try (var mockedStaticContexts = mockStatic(Contexts.class)) {
-				intercept();
-
-				mockedStaticContexts.verify(() -> Contexts.interceptCall(newGrpcContext, call, headers, next));
-			}
-		}
-
-		@Test
-		void shouldReturnListenerWithAttachedGrpcContext() {
-			try (var mockedStaticContexts = mockStatic(Contexts.class)) {
-				mockedStaticContexts.when(() -> Contexts.interceptCall(newGrpcContext, call, headers, next)).thenReturn(listener);
-
-				var returnedListener = intercept();
-
-				assertThat(returnedListener).isEqualTo(listener);
-			}
-		}
-
-		private Listener<Object> intercept() {
-			return interceptor.interceptCall(call, headers, next);
-		}
-	}
-
-	@Nested
-	class TestCreateArchiveCallContext {
-
-		@Test
-		void shouldCreateArchiveCallContext() {
-			var archiveCallContext = callInterceptor();
-
-			assertThat(archiveCallContext).usingRecursiveComparison().ignoringFields("requestId")
-					.isEqualTo(ArchiveCallContextTestFactory.createBuilder()
-							.clientName(ArchiveCallContext.CLIENT_NAME)
-							.build());
-		}
-
-		@Test
-		void shouldHaveRequestId() {
-			var archiveCallContext = callInterceptor();
-
-			assertThat(archiveCallContext.getRequestId()).isNotBlank();
-		}
-
-		private ArchiveCallContext callInterceptor() {
-			return interceptor.createArchiveCallContext(ArchiveCallContextTestFactory.createMetadata());
-		}
-	}
-}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextProviderTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextProviderTest.java
index 6abea45385afc05903fad1155b64e3908e5db0b6..a396a5ea1b771ad31953a07a03b837c195853330 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextProviderTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextProviderTest.java
@@ -19,38 +19,38 @@ class CallContextProviderTest {
 	private CallContextProvider contextProvider;
 
 	@Mock
-	private ArchiveCallContextMapper mapper;
+	private CallContextMapper mapper;
 	@Mock
-	private GrpcCallContextSupplier contextSupplier;
+	private CurrentUserService currentUserService;
 
 	@Nested
 	class TestProvideContext {
 
-		private final ArchiveCallContext archiveCallContext = ArchiveCallContextTestFactory.create();
+		private final CallContextUser callContextUser = CallContextUserTestFactory.create();
 
 		@BeforeEach
 		void mock() {
-			when(contextSupplier.get()).thenReturn(archiveCallContext);
+			when(currentUserService.getUser()).thenReturn(callContextUser);
 		}
 
 		@Test
 		void shouldGetArchiveCallContextFromGrpcContext() {
 			callProvider();
 
-			verify(contextSupplier).get();
+			verify(currentUserService).getUser();
 		}
 
 		@Test
 		void shouldMapArchiveCallContext() {
 			callProvider();
 
-			verify(mapper).toOzgCloudCallContext(archiveCallContext);
+			verify(mapper).toOzgCloudCallContext(callContextUser);
 		}
 
 		@Test
 		void shouldReturnMappedCallContext() {
 			var mappedCallContext = CallContextTestFactory.create();
-			when(mapper.toOzgCloudCallContext(archiveCallContext)).thenReturn(mappedCallContext);
+			when(mapper.toOzgCloudCallContext(callContextUser)).thenReturn(mappedCallContext);
 
 			var context = callProvider();
 
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextTestFactory.java
index f6886e13340b0efb58c9abc42dff50334b30ccb4..922d37fa72bc5dc45ac97e9f49193cf227d77cbf 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextTestFactory.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextTestFactory.java
@@ -1,6 +1,6 @@
 package de.ozgcloud.archive.common.callcontext;
 
-import java.util.Collection;
+import java.util.List;
 
 import de.ozgcloud.apilib.common.callcontext.CallContext;
 import de.ozgcloud.apilib.common.callcontext.CallContext.CallContextBuilder;
@@ -8,11 +8,11 @@ import de.ozgcloud.apilib.user.OzgCloudUserId;
 
 public class CallContextTestFactory {
 
-	public static final String REQUEST_ID = ArchiveCallContextTestFactory.REQUEST_ID;
-	public static final OzgCloudUserId USER_ID = OzgCloudUserId.from(ArchiveCallContextTestFactory.USER_ID);
-	public static final String CLIENT_NAME = ArchiveCallContextTestFactory.CLIENT_NAME;
-	private static final Collection<? extends String> ORGANISATIONS_EINHEITEN_IDS = ArchiveCallContextTestFactory.ORGANISATIONS_EINHEITEN_IDS;
-	private static final boolean ACCESS_LIMITED = ArchiveCallContextTestFactory.ACCESS_LIMITED;
+	public static final String REQUEST_ID = CallContextUserTestFactory.REQUEST_ID;
+	public static final OzgCloudUserId USER_ID = OzgCloudUserId.from(CallContextUserTestFactory.USER_ID);
+	public static final String CLIENT_NAME = CallContextUserTestFactory.CLIENT_NAME;
+	public static final String ORGANISATIONS_EINHEITEN_ID = CallContextUserTestFactory.ORGANISATIONS_EINHEITEN_ID;
+	public static final boolean ACCESS_LIMITED = CallContextUserTestFactory.ACCESS_LIMITED;
 
 	public static CallContext create() {
 		return createBuilder()
@@ -25,6 +25,6 @@ public class CallContextTestFactory {
 				.clientName(CLIENT_NAME)
 				.userId(USER_ID)
 				.accessLimited(ACCESS_LIMITED)
-				.accessLimitedToOrgaIds(ORGANISATIONS_EINHEITEN_IDS);
+				.accessLimitedToOrgaIds(List.of(ORGANISATIONS_EINHEITEN_ID));
 	}
 }
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextUserMapperTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextUserMapperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5150f31c021c766130b21ecb1386bbb666b030e8
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextUserMapperTest.java
@@ -0,0 +1,132 @@
+package de.ozgcloud.archive.common.callcontext;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mapstruct.factory.Mappers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import de.ozgcloud.archive.common.user.OzgCloudUserIdMapper;
+import de.ozgcloud.common.grpc.GrpcUtil;
+import io.grpc.Metadata;
+
+class CallContextUserMapperTest {
+
+	@InjectMocks
+	private final CallContextMapper mapper = Mappers.getMapper(CallContextMapper.class);
+
+	@Mock
+	private OzgCloudUserIdMapper ozgCloudUserIdMapper;
+
+	@Nested
+	class TestToOzgCloudCallContext {
+
+		@BeforeEach
+		void setUpCallToUserIdMapper() {
+			when(ozgCloudUserIdMapper.fromString(any(Optional.class))).thenReturn(CallContextTestFactory.USER_ID);
+		}
+
+		@Test
+		void shouldMap() {
+			var mappedContext = CallContextTestFactory.createBuilder().clientName(CallContextUser.ARCHIVE_MANAGER_CLIENT_NAME).build();
+
+			var result = mapper.toOzgCloudCallContext(CallContextUserTestFactory.create());
+
+			assertThat(result).usingRecursiveComparison().isEqualTo(mappedContext);
+		}
+	}
+
+	@Nested
+	class TestToCallContextUser {
+
+		@Mock
+		private Metadata headers;
+
+		@Test
+		void shouldMapRequestId() {
+			var result = toCallContextUser();
+
+			assertThat(result.getRequestId()).isSameAs(CallContextUserTestFactory.REQUEST_ID);
+		}
+
+		@Test
+		void shouldMapClientName() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				grpcUtilMock.when(() -> GrpcUtil.getClientName(headers)).thenReturn(Optional.of(CallContextUserTestFactory.CLIENT_NAME));
+
+				var result = toCallContextUser();
+
+				grpcUtilMock.verify(() -> GrpcUtil.getClientName(headers));
+				assertThat(result.getClientName()).isSameAs(CallContextUserTestFactory.CLIENT_NAME);
+			}
+		}
+
+		@Test
+		void shouldMapUserId() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				grpcUtilMock.when(() -> GrpcUtil.getUserId(headers)).thenReturn(Optional.of(CallContextUserTestFactory.USER_ID));
+
+				var result = toCallContextUser();
+
+				grpcUtilMock.verify(() -> GrpcUtil.getUserId(headers));
+				assertThat(result.getUserId()).contains(CallContextUserTestFactory.USER_ID);
+
+			}
+		}
+
+		@Test
+		void shouldMapUserName() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				grpcUtilMock.when(() -> GrpcUtil.getUserName(headers)).thenReturn(Optional.of(CallContextUserTestFactory.USER_NAME));
+
+				var result = toCallContextUser();
+
+				grpcUtilMock.verify(() -> GrpcUtil.getUserName(headers));
+				assertThat(result.getUserName()).contains(CallContextUserTestFactory.USER_NAME);
+			}
+		}
+
+		@Test
+		void shouldMapAccessLimited() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				grpcUtilMock.when(() -> GrpcUtil.getAccessLimited(headers)).thenReturn(Optional.of(CallContextUserTestFactory.ACCESS_LIMITED));
+				grpcUtilMock.when(() -> GrpcUtil.getAccessLimitedOrgaIds(headers))
+						.thenReturn(List.of(CallContextUserTestFactory.ORGANISATIONS_EINHEITEN_ID));
+
+				var result = toCallContextUser();
+
+				grpcUtilMock.verify(() -> GrpcUtil.getAccessLimited(headers));
+				grpcUtilMock.verify(() -> GrpcUtil.getAccessLimitedOrgaIds(headers));
+				assertThat(result.isAccessLimited()).isEqualTo(CallContextUserTestFactory.ACCESS_LIMITED);
+				assertThat(result.getAccessLimitedToOrgaIds()).containsExactly(CallContextUserTestFactory.ORGANISATIONS_EINHEITEN_ID);
+			}
+		}
+
+		@Test
+		void shouldMapNoAccessLimited() {
+			try (var grpcUtilMock = mockStatic(GrpcUtil.class)) {
+				grpcUtilMock.when(() -> GrpcUtil.getAccessLimited(any())).thenReturn(Optional.empty());
+				grpcUtilMock.when(() -> GrpcUtil.getAccessLimitedOrgaIds(any()))
+						.thenReturn(List.of(CallContextTestFactory.ORGANISATIONS_EINHEITEN_ID));
+
+				var result = toCallContextUser();
+
+				grpcUtilMock.verify(() -> GrpcUtil.getAccessLimited(headers));
+				assertThat(result.isAccessLimited()).isFalse();
+				assertThat(result.getAccessLimitedToOrgaIds()).isEmpty();
+			}
+		}
+
+		private CallContextUser toCallContextUser() {
+			return mapper.toCallContextUser(headers, CallContextUserTestFactory.REQUEST_ID);
+		}
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextUserTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextUserTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..f91d32af84e6ac4de855e6e91420ec3675ff08e4
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CallContextUserTestFactory.java
@@ -0,0 +1,35 @@
+package de.ozgcloud.archive.common.callcontext;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.archive.common.callcontext.CallContextUser.CallContextUserBuilder;
+
+public class CallContextUserTestFactory {
+
+	public static final String REQUEST_ID = UUID.randomUUID().toString();
+	public static final String USER_ID = UUID.randomUUID().toString();
+	public static final String USER_NAME = LoremIpsum.getInstance().getName();
+	public static final String CLIENT_NAME = LoremIpsum.getInstance().getName();
+	public static final String ORGANISATIONS_EINHEITEN_ID = UUID.randomUUID().toString();
+	public static final Boolean ACCESS_LIMITED = true;
+
+	public static CallContextUser create() {
+		return createBuilder()
+				.build();
+	}
+
+	public static CallContextUserBuilder createBuilder() {
+		return CallContextUser.builder()
+				.requestId(REQUEST_ID)
+				.clientName(CLIENT_NAME)
+				.userId(Optional.of(USER_ID))
+				.userName(Optional.of(USER_NAME))
+				.accessLimited(ACCESS_LIMITED)
+				.accessLimitedToOrgaIds(List.of(ORGANISATIONS_EINHEITEN_ID));
+	}
+
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CurrentUserServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CurrentUserServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ada38a29b5b6dd1fb78f9655786f6c4b9f727c6
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/callcontext/CurrentUserServiceTest.java
@@ -0,0 +1,499 @@
+/*
+ * 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.archive.common.callcontext;
+
+import static org.assertj.core.api.AssertionsForClassTypes.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.assertj.core.api.InstanceOfAssertFactories;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Spy;
+import org.springframework.security.authentication.AuthenticationTrustResolver;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import de.ozgcloud.command.Command;
+import de.ozgcloud.command.CommandTestFactory;
+import de.ozgcloud.common.grpc.GrpcUtil;
+
+class CurrentUserServiceTest {
+
+	@Spy
+	@InjectMocks
+	private CurrentUserService service;
+
+	@Mock
+	private AuthenticationTrustResolver trustResolver;
+
+	@Nested
+	class TestGetUser {
+
+		@Test
+		void shouldCallFindUser() {
+			doReturn(Optional.of(CallContextUserTestFactory.create())).when(service).findUser();
+
+			service.getUser();
+
+			verify(service).findUser();
+		}
+
+		@Test
+		void shouldReturnUser() {
+			var user = CallContextUserTestFactory.create();
+			doReturn(Optional.of(user)).when(service).findUser();
+
+			var result = service.getUser();
+
+			assertThat(result).isSameAs(user);
+		}
+
+		@Test
+		void shouldThrowException() {
+			doReturn(Optional.empty()).when(service).findUser();
+
+			assertThatThrownBy(service::getUser).isInstanceOf(IllegalStateException.class);
+		}
+	}
+
+	@Nested
+	class TestFindUser {
+
+		@Mock
+		private Authentication auth;
+
+		@BeforeEach
+		void init() {
+			doReturn(Optional.of(auth)).when(service).findTrustedAuthentication();
+		}
+
+		@Test
+		void shouldCallFindTrustedAuthentication() {
+			service.findUser();
+
+			verify(service).findTrustedAuthentication();
+		}
+
+		@Test
+		void shouldCallMapToCallContextUser() {
+			service.findUser();
+
+			verify(service).mapToCallContextUser(auth);
+		}
+
+		@Test
+		void shouldReturnUser() {
+			var user = CallContextUserTestFactory.create();
+			doReturn(user).when(service).mapToCallContextUser(auth);
+
+			var result = service.findUser();
+
+			assertThat(result).contains(user);
+		}
+
+		@Test
+		void shouldFilterEmptyClientName() {
+			doReturn(CallContextUserTestFactory.createBuilder().clientName(null).build()).when(service).mapToCallContextUser(auth);
+
+			var result = service.findUser();
+
+			assertThat(result).isEmpty();
+		}
+	}
+
+	@Nested
+	class TestMapToCallContextUser {
+
+		@Mock
+		private Authentication auth;
+
+		@Test
+		void shouldReturnUser() {
+			var user = CallContextUserTestFactory.create();
+			doReturn(user).when(service).buildDefaultCallContextUser(any());
+
+			var result = service.mapToCallContextUser(auth);
+
+			assertThat(result).isSameAs(user);
+		}
+
+		@Test
+		void shouldCallBuildDefaultCallContextUser() {
+			service.mapToCallContextUser(auth);
+
+			verify(service).buildDefaultCallContextUser(auth);
+		}
+
+		@Test
+		void shouldReturnDefaultUser() {
+			var user = CallContextUserTestFactory.create();
+			doReturn(user).when(service).buildDefaultCallContextUser(auth);
+
+			var result = service.mapToCallContextUser(auth);
+
+			assertThat(result).isSameAs(user);
+		}
+	}
+
+	@Nested
+	class TestBuildDefaultCallContextUser {
+
+		@Mock
+		private Authentication auth;
+		@Mock
+		private GrantedAuthority grantedAuthority;
+
+		@Test
+		void shouldSetClientName() {
+			doReturn(CallContextUserTestFactory.CLIENT_NAME).when(auth).getName();
+
+			var result = service.buildDefaultCallContextUser(auth);
+
+			assertThat(result.getClientName()).isEqualTo(CallContextUserTestFactory.CLIENT_NAME);
+		}
+
+		@Test
+		void shouldSetAccessLimited() {
+			when(grantedAuthority.getAuthority()).thenReturn(CallContextUserTestFactory.ORGANISATIONS_EINHEITEN_ID);
+			doReturn(List.of(grantedAuthority)).when(auth).getAuthorities();
+
+			var user = service.buildDefaultCallContextUser(auth);
+
+			assertThat(user.getAccessLimitedToOrgaIds()).asInstanceOf(InstanceOfAssertFactories.LIST)
+					.containsExactly(CallContextUserTestFactory.ORGANISATIONS_EINHEITEN_ID);
+		}
+
+	}
+
+	@Nested
+	class TestFindAuthentication {
+
+		@Mock
+		private Authentication auth;
+
+		@Test
+		void shouldCallFindTrustedAuthentication() {
+			service.findAuthentication();
+
+			verify(service).findTrustedAuthentication();
+		}
+
+		@Test
+		void shouldReturnAuthentication() {
+			doReturn(Optional.of(auth)).when(service).findTrustedAuthentication();
+
+			var result = service.findAuthentication();
+
+			assertThat(result).contains(auth);
+		}
+	}
+
+	@Nested
+	class TestFindTrustedAuthentication {
+
+		@Mock
+		private SecurityContext context;
+		@Mock
+		private Authentication auth;
+
+		private MockedStatic<SecurityContextHolder> contextHolderMock;
+
+		@BeforeEach
+		void init() {
+			contextHolderMock = mockStatic(SecurityContextHolder.class);
+			contextHolderMock.when(SecurityContextHolder::getContext).thenReturn(context);
+			when(context.getAuthentication()).thenReturn(auth);
+		}
+
+		@AfterEach
+		void cleanup() {
+			contextHolderMock.close();
+		}
+
+		@Test
+		void shouldCallGetContext() {
+			service.findTrustedAuthentication();
+
+			contextHolderMock.verify(SecurityContextHolder::getContext);
+		}
+
+		@Test
+		void shouldCallGetAuthentication() {
+			service.findTrustedAuthentication();
+
+			verify(context).getAuthentication();
+		}
+
+		@Test
+		void shouldCallIsAnonymous() {
+			service.findTrustedAuthentication();
+
+			verify(trustResolver).isAnonymous(auth);
+		}
+
+		@Test
+		void shouldCallIsAuthenticated() {
+			service.findTrustedAuthentication();
+
+			verify(auth).isAuthenticated();
+		}
+
+		@Test
+		void shouldFilterAnonymous() {
+			when(trustResolver.isAnonymous(any())).thenReturn(true);
+
+			var result = service.findTrustedAuthentication();
+
+			assertThat(result).isEmpty();
+			verify(auth, never()).isAuthenticated();
+		}
+
+		@Test
+		void shouldFilterNotAuthenticated() {
+			doReturn(false).when(trustResolver).isAnonymous(auth);
+			doReturn(false).when(auth).isAuthenticated();
+
+			var result = service.findTrustedAuthentication();
+
+			assertThat(result).isEmpty();
+		}
+	}
+
+	@DisplayName("Create user")
+	@Nested
+	class TestCreateUser {
+
+		@Test
+		void shouldSetUserId() {
+			var user = service.createUser(CommandTestFactory.create());
+
+			assertThat(user.getUserId()).contains(CommandTestFactory.CREATED_BY);
+		}
+
+		@Test
+		void shouldSetUserName() {
+			var createdByName = "user-name";
+
+			var user = service.createUser(CommandTestFactory.createBuilder().createdByName(createdByName).build());
+
+			assertThat(user.getUserName()).contains(createdByName);
+		}
+
+		@Test
+		void shouldSetClientName() {
+			var clientName = "client";
+
+			var user = service.createUser(CommandTestFactory.createBuilder().createdByClientName(clientName).build());
+
+			assertThat(user.getClientName()).isEqualTo(clientName);
+		}
+
+		@Test
+		void shouldSetAccessLimited() {
+			var user = service.createUser(CommandTestFactory.create());
+
+			assertThat(user.isAccessLimited()).isFalse();
+		}
+
+		@Test
+		void shouldCallGetRequestId() {
+			service.createUser(CommandTestFactory.create());
+
+			verify(service).getRequestId();
+		}
+
+		@Test
+		void shouldSetRequestId() {
+			var requestId = UUID.randomUUID().toString();
+			doReturn(requestId).when(service).getRequestId();
+
+			var user = service.createUser(CommandTestFactory.create());
+
+			assertThat(user.getRequestId()).isEqualTo(requestId);
+		}
+	}
+
+	@Nested
+	class TestGetRequestId {
+
+		@Test
+		void shouldReturnRequestId() {
+			var requestId = UUID.randomUUID().toString();
+			try (var contextMock = mockStatic(ThreadContext.class)) {
+				contextMock.when(ThreadContext::getContext).thenReturn(Map.of(GrpcUtil.KEY_REQUEST_ID, requestId));
+
+				var result = service.getRequestId();
+
+				assertThat(result).isEqualTo(requestId);
+			}
+		}
+
+		@Test
+		void shouldReturnNewRequestId() {
+			try (var ctc = mockStatic(ThreadContext.class)) {
+				ctc.when(ThreadContext::getContext).thenReturn(Collections.emptyMap());
+
+				var result = service.getRequestId();
+
+				assertThat(result).isNotEmpty();
+			}
+		}
+	}
+
+	@Nested
+	class TestStartAndReturnPreviousSecurityContext {
+
+		@Nested
+		class TestWithCommand {
+
+			private static final Command COMMAND = CommandTestFactory.create();
+
+			@Mock
+			private SecurityContext securityContext;
+
+			@Test
+			void shouldCallCreateUser() {
+				startAndReturnPreviousSecurityContext();
+
+				verify(service).createUser(COMMAND);
+			}
+
+			@Test
+			void shouldCallStartAndReturnPreviousSecurityContext() {
+				var user = CallContextUserTestFactory.create();
+				doReturn(user).when(service).createUser(any());
+
+				startAndReturnPreviousSecurityContext();
+
+				verify(service).startAndReturnPreviousSecurityContext(user);
+			}
+
+			@Test
+			void shouldReturnContext() {
+				doReturn(securityContext).when(service).startAndReturnPreviousSecurityContext(any(CallContextUser.class));
+
+				var result = startAndReturnPreviousSecurityContext();
+
+				assertThat(result).isSameAs(securityContext);
+			}
+
+			private SecurityContext startAndReturnPreviousSecurityContext() {
+				return service.startAndReturnPreviousSecurityContext(COMMAND);
+			}
+		}
+
+		@Nested
+		class TestWithCallContextUser {
+
+			private final CallContextUser newUser = CallContextUserTestFactory.create();
+			private final CallContextAuthenticationToken newAuthentication = CallContextAuthenticationToken.authenticate(newUser);
+
+			@Mock
+			private SecurityContext previousSecurityContext;
+
+			@BeforeEach
+			void init() {
+				SecurityContextHolder.setContext(previousSecurityContext);
+			}
+
+			@Test
+			void shouldReturnPreviousSecurityContext() {
+				var returnedContext = startAndReturnPreviousSecurityContext();
+
+				assertThat(returnedContext).isSameAs(previousSecurityContext);
+			}
+
+			@Test
+			void shouldSetContextWithNewUser() {
+				startAndReturnPreviousSecurityContext();
+
+				var currentAuthentication = SecurityContextHolder.getContext().getAuthentication();
+				assertThat(currentAuthentication).usingRecursiveComparison().isEqualTo(newAuthentication);
+			}
+
+			private SecurityContext startAndReturnPreviousSecurityContext() {
+				return service.startAndReturnPreviousSecurityContext(newUser);
+			}
+		}
+	}
+
+	@Nested
+	class TestResetSecurityContext {
+
+		@Mock
+		private SecurityContext securityContext;
+
+		private MockedStatic<SecurityContextHolder> contextHolderMock;
+
+		@BeforeEach
+		void init() {
+			contextHolderMock = mockStatic(SecurityContextHolder.class);
+		}
+
+		@AfterEach
+		void cleanup() {
+			contextHolderMock.close();
+		}
+
+		@Test
+		void shouldClearContext() {
+			resetSecurityContext();
+
+			contextHolderMock.verify(SecurityContextHolder::clearContext);
+		}
+
+		@Test
+		void shouldSetContext() {
+			resetSecurityContext();
+
+			contextHolderMock.verify(() -> SecurityContextHolder.setContext(securityContext));
+		}
+
+		@Test
+		void shouldNotSetContext() {
+			service.resetSecurityContext(null);
+
+			contextHolderMock.verify(() -> SecurityContextHolder.setContext(any()), never());
+		}
+
+		private void resetSecurityContext() {
+			service.resetSecurityContext(securityContext);
+		}
+	}
+}
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java
index c6e8b218d22988558b96c559733a3515d98bd5ab..0557c2400baeef93b4e8b0e68deb9cc83e460fc2 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/command/CommandServiceTest.java
@@ -4,18 +4,23 @@ import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 import java.util.stream.Stream;
 
 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.ValueSource;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
 
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
+import de.ozgcloud.apilib.common.command.grpc.OzgCloudCommandTestFactory;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId;
 import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
 import de.ozgcloud.command.CommandStatus;
 
@@ -26,6 +31,8 @@ class CommandServiceTest {
 	private CommandService service;
 	@Mock
 	private CommandRemoteService remoteService;
+	@Mock
+	private OzgCloudCommandService ozgCloudCommandService;
 
 	@Nested
 	class TestFindFinishedCommands {
@@ -64,23 +71,48 @@ class CommandServiceTest {
 	}
 
 	@Nested
-	class TestHasPendingCommands {
+	class TestHasPendingCommandsExceptArchive {
+
+		private final String order = LoremIpsum.getInstance().getWords(1);
 
 		@Test
-		void shouldCallRemoteService() {
-			service.hasPendingCommands(VorgangWithEingangTestFactory.ID);
+		void shouldCallOzgCloudCommandService() {
+			hasPendingCommandsExceptWithOrder();
 
-			verify(remoteService).hasPendingCommands(VorgangWithEingangTestFactory.ID);
+			verify(ozgCloudCommandService).getPendingCommands(OzgCloudVorgangId.from(VorgangWithEingangTestFactory.ID));
 		}
 
-		@ParameterizedTest
-		@ValueSource(booleans = { true, false })
-		void shouldReturnRemoteServiceResult(boolean hasPendingCommands) {
-			when(remoteService.hasPendingCommands(any())).thenReturn(hasPendingCommands);
+		@Test
+		void shouldReturnFalseOnNoPendingCommands() {
+			when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(Collections.emptyList());
 
-			var result = service.hasPendingCommands(VorgangWithEingangTestFactory.ID);
+			var result = hasPendingCommandsExceptWithOrder();
+
+			assertThat(result).isFalse();
+		}
+
+		@Test
+		void shouldReturnTrueOnPendingCommands() {
+			when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(List.of(OzgCloudCommandTestFactory.create()));
+
+			var result = hasPendingCommandsExceptWithOrder();
+
+			assertThat(result).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalseOnCommandWithExcpetionOrder() {
+			when(ozgCloudCommandService.getPendingCommands(any())).thenReturn(List.of(OzgCloudCommandTestFactory.createBuilder()
+					.order(order)
+					.build()));
+
+			var result = hasPendingCommandsExceptWithOrder();
+
+			assertThat(result).isFalse();
+		}
 
-			assertThat(result).isEqualTo(hasPendingCommands);
+		private boolean hasPendingCommandsExceptWithOrder() {
+			return service.hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, order);
 		}
 	}
 }
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..be5d9a974e360c0fdea92a0261e52a7c150553f1
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/JsonToXtaIdentifierListConverterTest.java
@@ -0,0 +1,48 @@
+package de.ozgcloud.archive.common.xta;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Spy;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import lombok.SneakyThrows;
+
+class JsonToXtaIdentifierListConverterTest {
+
+	@InjectMocks
+	private JsonToXtaIdentifierListConverter converter;
+
+	@Spy
+	private ObjectMapper objectMapper;
+
+	@Nested
+	class TestConvert {
+
+		@Test
+		void shouldReturnListOfXtaIdentifier() {
+			var jsonInput = XtaIdentifierTestFactory.createAsJson();
+
+			var identifiers = converter.convert(jsonInput);
+
+			assertThat(identifiers).usingRecursiveFieldByFieldElementComparator().containsExactly(XtaIdentifierTestFactory.create());
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldThrowTechnicalException() {
+			doThrow(JsonProcessingException.class).when(objectMapper).readValue(anyString(), any(TypeReference.class));
+
+			assertThrows(TechnicalException.class, () -> converter.convert("invalid input"));
+		}
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..35f2f02f7a09728f1293a89fa4c808c44aecdf91
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaIdentifierTestFactory.java
@@ -0,0 +1,30 @@
+package de.ozgcloud.archive.common.xta;
+
+import java.util.UUID;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.xta.client.model.XtaIdentifier;
+import de.ozgcloud.xta.client.model.XtaIdentifier.XtaIdentifierBuilder;
+
+public class XtaIdentifierTestFactory {
+
+	public static final String CATEGORY = LoremIpsum.getInstance().getWords(1);
+	public static final String VALUE = UUID.randomUUID().toString();
+	public static final String NAME = LoremIpsum.getInstance().getName();
+
+	public static XtaIdentifier create() {
+		return createBuilder().build();
+	}
+
+	public static XtaIdentifierBuilder createBuilder() {
+		return XtaIdentifier.builder()
+				.name(NAME)
+				.value(VALUE)
+				.category(CATEGORY);
+	}
+
+	public static String createAsJson() {
+		return "[{\"category\":\"%s\",\"name\":\"%s\",\"value\":\"%s\"}]".formatted(CATEGORY, NAME, VALUE);
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..536adb305f6e1acdac5731ff29f1c78eca0fec9a
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java
@@ -0,0 +1,186 @@
+package de.ozgcloud.archive.common.xta;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Optional;
+
+import org.junit.jupiter.api.AfterEach;
+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.MockedStatic;
+import org.mockito.Spy;
+
+import de.ozgcloud.archive.vorgang.XdomeaXtaFileTestFactory;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.XtaClient;
+import de.ozgcloud.xta.client.exception.XtaClientException;
+import de.ozgcloud.xta.client.model.XtaFile;
+import de.ozgcloud.xta.client.model.XtaMessage;
+import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator;
+import lombok.SneakyThrows;
+
+class XtaServiceTest {
+
+	@Spy
+	@InjectMocks
+	private XtaService service;
+
+	@Mock
+	private XtaClient xtaClient;
+
+	@Nested
+	class TestSendXdomeaFile {
+
+		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
+		@Mock
+		private XtaMessage xtaMessage;
+
+		@BeforeEach
+		void mock() {
+			doReturn(xtaMessage).when(service).createMessage(xdomeaFile);
+			doReturn(xtaClient).when(service).getXtaClient();
+		}
+
+		@Test
+		void shouldGetXtaClient() {
+			sendXdomeaFile();
+
+			verify(service).getXtaClient();
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldCallCreateMessage() {
+			sendXdomeaFile();
+
+			verify(service).createMessage(xdomeaFile);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldSendMessage() {
+			sendXdomeaFile();
+
+			verify(xtaClient).sendMessage(xtaMessage);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldThrowTechnicalException() {
+			when(xtaClient.sendMessage(any())).thenThrow(XtaClientException.class);
+
+			assertThrows(TechnicalException.class, () -> sendXdomeaFile());
+		}
+
+		private void sendXdomeaFile() {
+			service.sendXdomeaFile(xdomeaFile);
+		}
+	}
+
+	@Nested
+	class TestCreateMessage {
+		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
+
+		private MockedStatic<XdomeaXtaMessageCreator> mockedStaticXdomeaXtaMessageCreator;
+
+		@Mock
+		private XdomeaXtaMessageCreator xdomeaXtaMessageCreator;
+		@Mock
+		private XtaMessage xtaMessage;
+
+		@BeforeEach
+		void setUpMock() {
+			mockedStaticXdomeaXtaMessageCreator = mockStatic(XdomeaXtaMessageCreator.class);
+			mockedStaticXdomeaXtaMessageCreator.when(XdomeaXtaMessageCreator::createInstance).thenReturn(xdomeaXtaMessageCreator);
+		}
+
+		@AfterEach
+		void cleanUp() {
+			mockedStaticXdomeaXtaMessageCreator.close();
+		}
+
+		@Test
+		void shouldCreateXdomeaXtaMessageCreator() {
+			createMessage();
+
+			mockedStaticXdomeaXtaMessageCreator.verify(XdomeaXtaMessageCreator::createInstance);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldCallCreateMessage() {
+			createMessage();
+
+			verify(xdomeaXtaMessageCreator).createMessage(xdomeaFile);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldReturnMessage() {
+			when(xdomeaXtaMessageCreator.createMessage(any())).thenReturn(xtaMessage);
+
+			var message = createMessage();
+
+			assertThat(message).isEqualTo(xtaMessage);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldThrowTechnicalException() {
+			when(xdomeaXtaMessageCreator.createMessage(any())).thenThrow(XtaClientException.class);
+
+			assertThrows(TechnicalException.class, () -> createMessage());
+		}
+
+		private XtaMessage createMessage() {
+			return service.createMessage(xdomeaFile);
+		}
+	}
+
+	@Nested
+	class TestGetXtaClient {
+
+		private XtaService xtaService;
+
+		@Nested
+		class TestOnConfiguredXtaClient {
+
+			@BeforeEach
+			void givenXtaClientConfigured() {
+				xtaService = spy(new XtaService(Optional.of(xtaClient)));
+			}
+
+			@Test
+			void shouldReturnXtaClient() {
+				var returnedXtaClient = getXtaClient();
+
+				assertThat(returnedXtaClient).isSameAs(xtaClient);
+			}
+
+		}
+
+		@Nested
+		class TestOnUnconfiguredXtaClient {
+
+			@BeforeEach
+			void givenXtaClientNotConfigured() {
+				xtaService = spy(new XtaService(Optional.empty()));
+			}
+
+			@Test
+			void shouldThrowTechnicalException() {
+				assertThrows(TechnicalException.class, () -> getXtaClient());
+			}
+		}
+
+		private XtaClient getXtaClient() {
+			return xtaService.getXtaClient();
+		}
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java
index fdb7e30c7fa8a9f216817307d148ed912f8d62b2..f31301a2b63230bcbc807b08606340d4f9bc0656 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportGrpcServiceITCase.java
@@ -17,7 +17,6 @@ import java.util.zip.ZipInputStream;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -42,7 +41,7 @@ import de.ozgcloud.archive.kommentar.KommentarsExportData;
 import de.ozgcloud.archive.kommentar.KommentarsExportDataTestFactory;
 import de.ozgcloud.archive.postfach.ExportNachrichtService;
 import de.ozgcloud.archive.postfach.PostfachMailExportData;
-import de.ozgcloud.archive.vorgang.ExportVorgangService;
+import de.ozgcloud.archive.vorgang.VorgangService;
 import de.ozgcloud.archive.vorgang.VorgangTypeTestFactory;
 import de.ozgcloud.archive.vorgang.VorgangWithEingang;
 import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
@@ -54,7 +53,6 @@ import net.devh.boot.grpc.client.inject.GrpcClient;
 		"grpc.server.inProcessName=GrpcExportService-test",
 		"grpc.client.inProcess.address=in-process:GrpcExportService-test"
 })
-// @SpringJUnitConfig(classes = { GrpcIntegrationTestConfiguration.class })
 @ITCase
 @DirtiesContext
 class ExportGrpcServiceITCase {
@@ -65,7 +63,7 @@ class ExportGrpcServiceITCase {
 	@MockBean
 	private ExportFileService exportFileService;
 	@MockBean
-	private ExportVorgangService exportVorgangService;
+	private VorgangService vorgangService;
 	@MockBean
 	private ExportHistorieService exportHistorieService;
 	@MockBean
@@ -87,20 +85,20 @@ class ExportGrpcServiceITCase {
 
 		@BeforeEach
 		void setUpCommonMocks() {
-			when(exportVorgangService.getVorgang(VorgangWithEingangTestFactory.ID)).thenReturn(vorgang);
+			when(vorgangService.getVorgang(VorgangWithEingangTestFactory.ID)).thenReturn(vorgang);
 			when(exportNachrichtService.createExportData(vorgang)).thenReturn(PostfachMailExportData.builder().build());
 			when(exportBescheidService.createExportData(vorgang)).thenReturn(BescheidExportData.builder().build());
 			when(exportFileService.getRepresentations(vorgang)).thenReturn(Stream.empty());
 			when(exportFileService.getAttachments(vorgang)).thenReturn(Stream.empty());
 
-			when(exportVorgangService.createKopf(vorgang)).thenReturn(NkAbgabeTypeTestFactory.create());
-			when(exportVorgangService.createVorgangType(vorgang)).thenReturn(VorgangTypeTestFactory.create());
-			when(exportVorgangService.createAkteType(vorgang)).thenReturn(AkteTypeTestFactory.create());
+			when(vorgangService.createKopf(vorgang)).thenReturn(NkAbgabeTypeTestFactory.create());
+			when(vorgangService.createVorgangType(vorgang)).thenReturn(VorgangTypeTestFactory.create());
+			when(vorgangService.createAkteType(vorgang)).thenReturn(AkteTypeTestFactory.create());
 
 		}
 
 		@Nested
-		class OnMinimalVorgang {
+		class TestOnMinimalVorgang {
 
 			@BeforeEach
 			void setUpMock() {
@@ -121,7 +119,6 @@ class ExportGrpcServiceITCase {
 				assertThat(numEntry).isEqualTo(1);
 			}
 
-			@Disabled("FIXME: Führt man die ganze Klasse aus bleibt er beim zweiten Test hängen. Führt man die Tests einzelnd aus funktionieren sie.")
 			@Test
 			@SneakyThrows
 			void shouldContainVorgangKopfDataInXml() {
@@ -137,9 +134,8 @@ class ExportGrpcServiceITCase {
 			}
 		}
 
-		@Disabled("FIXME: Führt man die ganze Klasse aus bleibt er beim zweiten Test hängen. Führt man die Tests einzelnd aus funktionieren sie.")
 		@Nested
-		class OnVorgangWithKommentarAndAttachment {
+		class TestOnVorgangWithKommentarAndAttachment {
 			private final String attachmentContent = LoremIpsum.getInstance().getWords(5);
 
 			@BeforeEach
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceITCase.java
index d085f3d41f19d41bcaa323dbe984f95cebb739f0..74b813c3d8ecb10ffd58e0dde14d1f25e818f977 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceITCase.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceITCase.java
@@ -30,7 +30,7 @@ import de.ozgcloud.archive.postfach.ExportNachrichtService;
 import de.ozgcloud.archive.postfach.PostfachMail;
 import de.ozgcloud.archive.postfach.PostfachMailExportDataTestFactory;
 import de.ozgcloud.archive.postfach.PostfachMailTestFactory;
-import de.ozgcloud.archive.vorgang.ExportVorgangService;
+import de.ozgcloud.archive.vorgang.VorgangService;
 import de.ozgcloud.archive.vorgang.VorgangWithEingang;
 import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
 import de.ozgcloud.common.test.ITCase;
@@ -41,7 +41,7 @@ class ExportServiceITCase {
 	@SpyBean
 	private ExportFileService exportFileService;
 	@SpyBean
-	private ExportVorgangService exportVorgangService;
+	private VorgangService vorgangService;
 	@MockBean
 	private ExportHistorieService exportHistorieService;
 	@MockBean
@@ -66,7 +66,7 @@ class ExportServiceITCase {
 
 		@BeforeEach
 		void setup() {
-			doReturn(vorgang).when(exportVorgangService).getVorgang(VorgangWithEingangTestFactory.ID);
+			doReturn(vorgang).when(vorgangService).getVorgang(VorgangWithEingangTestFactory.ID);
 			doReturn(Stream.of(OzgFileTestFactory.createWithUniqueId())).when(exportFileService).getRepresentations(vorgang);
 			doReturn(Stream.of(OzgFileTestFactory.createWithUniqueId())).when(exportFileService).getAttachments(vorgang);
 			doReturn(Stream.of(OzgFileTestFactory.createWithUniqueId())).when(binaryFileService).getFiles(postfachMail.getAttachments());
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java
index 66e566632917007778f2eebe719f019f7b9971dd..128073afea1917cf3b050fd3cff99ce6e1e5fb3e 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/ExportServiceTest.java
@@ -2,9 +2,11 @@ package de.ozgcloud.archive.export;
 
 import static de.ozgcloud.archive.common.XDomeaTestUtils.*;
 import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
@@ -13,6 +15,9 @@ import java.util.UUID;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+import jakarta.activation.DataHandler;
+import jakarta.activation.FileDataSource;
+
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -22,6 +27,7 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.MockedConstruction;
 import org.mockito.MockedStatic;
 import org.mockito.Spy;
 
@@ -31,6 +37,7 @@ import de.ozgcloud.archive.bescheid.ExportBescheidService;
 import de.ozgcloud.archive.common.ExportFilenameGenerator;
 import de.ozgcloud.archive.common.HistorienProtokollInformationTypeTestFactory;
 import de.ozgcloud.archive.common.XDomeaTestUtils;
+import de.ozgcloud.archive.common.xta.XtaService;
 import de.ozgcloud.archive.file.ExportFileService;
 import de.ozgcloud.archive.file.OzgFile;
 import de.ozgcloud.archive.file.OzgFileTestFactory;
@@ -43,11 +50,15 @@ import de.ozgcloud.archive.postfach.PostfachMailExportData;
 import de.ozgcloud.archive.postfach.PostfachMailExportDataTestFactory;
 import de.ozgcloud.archive.vorgang.EingangHeaderTestFactory;
 import de.ozgcloud.archive.vorgang.EingangTestFactory;
-import de.ozgcloud.archive.vorgang.ExportVorgangService;
+import de.ozgcloud.archive.vorgang.VorgangService;
 import de.ozgcloud.archive.vorgang.VorgangTypeTestFactory;
 import de.ozgcloud.archive.vorgang.VorgangWithEingang;
 import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
+import de.ozgcloud.archive.vorgang.XdomeaXtaFileTestFactory;
+import de.ozgcloud.command.Command;
+import de.ozgcloud.command.CommandTestFactory;
 import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.xta.client.model.XtaFile;
 import de.xoev.xdomea.AbgabeAbgabe0401;
 import de.xoev.xdomea.AkteType;
 import de.xoev.xdomea.DokumentType;
@@ -68,7 +79,7 @@ class ExportServiceTest {
 	@Mock
 	private ExportFileService exportFileService;
 	@Mock
-	private ExportVorgangService exportVorgangService;
+	private VorgangService vorgangService;
 	@Mock
 	private ExportHistorieService exportHistorieService;
 	@Mock
@@ -77,6 +88,8 @@ class ExportServiceTest {
 	private ExportNachrichtService exportNachrichtService;
 	@Mock
 	private ExportBescheidService exportBescheidService;
+	@Mock
+	private XtaService xtaService;
 
 	@DisplayName("Write Xdomea File")
 	@Nested
@@ -155,10 +168,10 @@ class ExportServiceTest {
 		}
 
 		private void setUpVorgangService() {
-			when(exportVorgangService.getVorgang(VorgangWithEingangTestFactory.ID)).thenReturn(vorgang);
-			when(exportVorgangService.createVorgangType(vorgang)).thenReturn(vorgangType);
-			when(exportVorgangService.createKopf(vorgang)).thenReturn(kopfType);
-			when(exportVorgangService.createAkteType(vorgang)).thenReturn(akteType);
+			when(vorgangService.getVorgang(VorgangWithEingangTestFactory.ID)).thenReturn(vorgang);
+			when(vorgangService.createVorgangType(vorgang)).thenReturn(vorgangType);
+			when(vorgangService.createKopf(vorgang)).thenReturn(kopfType);
+			when(vorgangService.createAkteType(vorgang)).thenReturn(akteType);
 		}
 
 		private void setUpXdomeaNachrichtBuilder() {
@@ -213,7 +226,7 @@ class ExportServiceTest {
 		void shouldLoadVorgang() {
 			callService();
 
-			verify(exportVorgangService).getVorgang(VorgangWithEingangTestFactory.ID);
+			verify(vorgangService).getVorgang(VorgangWithEingangTestFactory.ID);
 		}
 
 		@Test
@@ -241,14 +254,14 @@ class ExportServiceTest {
 		void shouldCreateKopf() {
 			callService();
 
-			verify(exportVorgangService).createKopf(vorgang);
+			verify(vorgangService).createKopf(vorgang);
 		}
 
 		@Test
 		void shouldCreateVorgangType() {
 			callService();
 
-			verify(exportVorgangService).createVorgangType(vorgang);
+			verify(vorgangService).createVorgangType(vorgang);
 		}
 
 		@Test
@@ -276,7 +289,7 @@ class ExportServiceTest {
 		void shouldCreateAkteType() {
 			callService();
 
-			verify(exportVorgangService).createAkteType(vorgang);
+			verify(vorgangService).createAkteType(vorgang);
 		}
 
 		@Test
@@ -655,4 +668,216 @@ class ExportServiceTest {
 			assertThat(fileName).isEqualTo(id + "_Abgabe.Abgabe.0401.xdomea");
 		}
 	}
+
+	@Nested
+	class TestArchiveVorgang {
+
+		private final Command command = CommandTestFactory.create();
+		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			doReturn(xdomeaFile).when(service).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID);
+		}
+
+		@Test
+		void shouldCallBuildXdomeaXtaFile() {
+			archiveVorgang();
+
+			verify(service).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID);
+		}
+
+		@Test
+		void shouldCallSendXdomeaFile() {
+			archiveVorgang();
+
+			verify(xtaService).sendXdomeaFile(xdomeaFile);
+		}
+
+		private void archiveVorgang() {
+			service.archiveVorgang(command);
+		}
+	}
+
+	@Nested
+	class TestBuildXdomeaXtaFile {
+
+		private final String fileNameId = UUID.randomUUID().toString();
+
+		@BeforeEach
+		void mock() {
+			doReturn(fileNameId).when(service).createFileNameId();
+			doReturn(XdomeaXtaFileTestFactory.FILE_NAME).when(service).buildXdomeaFileName(any());
+			doReturn(XdomeaXtaFileTestFactory.DATA_HANDLER).when(service).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
+		}
+
+		@Test
+		void shouldCallCreateFileNameId() {
+			buildXdomeaXtaFile();
+
+			verify(service).createFileNameId();
+		}
+
+		@Test
+		void shouldCallBuildXdomeaFileName() {
+			buildXdomeaXtaFile();
+
+			verify(service).buildXdomeaFileName(fileNameId);
+		}
+
+		@Test
+		void shouldCallCreateFileContent() {
+			buildXdomeaXtaFile();
+
+			verify(service).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
+		}
+
+		@Test
+		void shouldReturnXdomeaFile() {
+			var xdomeaFile = buildXdomeaXtaFile();
+
+			assertThat(xdomeaFile).usingRecursiveComparison().isEqualTo(XdomeaXtaFileTestFactory.create());
+		}
+
+		private XtaFile buildXdomeaXtaFile() {
+			return service.buildXdomeaXtaFile(VorgangWithEingangTestFactory.ID);
+		}
+	}
+
+	@Nested
+	class TestCreateFileNameId {
+
+		private final UUID uuid = UUID.randomUUID();
+
+		@Test
+		void shouldReturnRandomUUID() {
+			try (var mockedStaticUUID = mockStatic(UUID.class)) {
+				mockedStaticUUID.when(UUID::randomUUID).thenReturn(uuid);
+
+				var returnedFileNameId = service.createFileNameId();
+
+				assertThat(returnedFileNameId).isEqualTo(uuid.toString());
+			}
+		}
+	}
+
+	@Nested
+	class TestCreateFileContent {
+
+		private final String fileNameId = UUID.randomUUID().toString();
+
+		@Nested
+		class TestOnNoExceptionThrown {
+			private MockedConstruction<FileDataSource> fileDataSourceConstruction;
+			private FileDataSource fileDataSource;
+			private File dataSourceFile;
+
+			private MockedConstruction<DataHandler> dataHandlerConstruction;
+			private DataHandler dataHandler;
+			private FileDataSource dataHandlerSource;
+
+			@Mock
+			private File tempFile;
+			@Mock
+			private OutputStream outputStream;
+
+			@BeforeEach
+			@SneakyThrows
+			void setUpMock() {
+				doReturn(tempFile).when(service).createTempFile(fileNameId);
+				fileDataSourceConstruction = mockConstruction(FileDataSource.class,
+						(fileDataSource, context) -> {
+							dataSourceFile = (File) context.arguments().get(0);
+							this.fileDataSource = fileDataSource;
+							when(fileDataSource.getOutputStream()).thenReturn(outputStream);
+						});
+				dataHandlerConstruction = mockConstruction(DataHandler.class, (dataHandler, context) -> {
+					this.dataHandler = dataHandler;
+					dataHandlerSource = (FileDataSource) context.arguments().get(0);
+				});
+				doNothing().when(service).writeXdomeaFileContent(any(), any(), any());
+			}
+
+			@AfterEach
+			void cleanUp() {
+				fileDataSourceConstruction.close();
+				dataHandlerConstruction.close();
+			}
+
+			@Test
+			@SneakyThrows
+			void shouldCallCreateTempFile() {
+				createFileContent();
+
+				verify(service).createTempFile(fileNameId);
+			}
+
+			@Test
+			void shouldCreateFileDataSourceWithTempFile() {
+				createFileContent();
+
+				assertThat(dataSourceFile).isEqualTo(tempFile);
+			}
+
+			@Test
+			@SneakyThrows
+			void shouldGetOutputStreamOfFileDataSource() {
+				createFileContent();
+
+				verify(fileDataSource).getOutputStream();
+			}
+
+			@Test
+			void shouldWriteXdomeaContentToOutputStream() {
+				createFileContent();
+
+				verify(service).writeXdomeaFileContent(VorgangWithEingangTestFactory.ID, fileNameId, outputStream);
+			}
+
+			@Test
+			void shouldConstructDataHandlerFromFileDataSource() {
+				createFileContent();
+
+				assertThat(dataHandlerConstruction.constructed()).hasSize(1);
+				assertThat(dataHandlerSource).isEqualTo(fileDataSource);
+			}
+
+			@Test
+			void shouldReturnDataHandler() {
+				var resultDataHandler = createFileContent();
+
+				assertThat(resultDataHandler).isEqualTo(dataHandler);
+			}
+		}
+
+		@Nested
+		class TestOnIOExceptionThrown {
+			@Test
+			@SneakyThrows
+			void shouldThrowTechnicalExcpetion() {
+				doThrow(IOException.class).when(service).createTempFile(any());
+
+				assertThrows(TechnicalException.class, () -> createFileContent());
+			}
+		}
+
+		private DataHandler createFileContent() {
+			return service.createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
+		}
+	}
+
+	@Nested
+	class TestCreateTempFile {
+
+		private final String fileNameId = UUID.randomUUID().toString();
+
+		@Test
+		@SneakyThrows
+		void shouldReturnFile() {
+			var file = service.createTempFile(fileNameId);
+
+			assertThat(file).isNotNull().isInstanceOf(File.class);
+		}
+	}
+
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java
index d8db5aefb82097daee33e8f0178763e30f4deee6..f68a18eaf38ccbb1f9b7f90821f03000da54652d 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/export/XdomeaPropertiesValidatorTest.java
@@ -48,7 +48,7 @@ class XdomeaPropertiesValidatorTest {
 		}
 
 		@Nested
-		class OnUriNotSet {
+		class TestOnUriNotSet {
 
 			private static final String PROPERTY_NAME = "behoerdenschluesselUri";
 			public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME;
@@ -90,7 +90,7 @@ class XdomeaPropertiesValidatorTest {
 		}
 
 		@Nested
-		class OnVersionNotSet {
+		class TestOnVersionNotSet {
 
 			public static final String PROPERTY_NAME = "behoerdenschluesselVersion";
 			public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME;
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/postfach/PostfachMailMapperTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/postfach/PostfachMailMapperTest.java
index 4abe1b673302a6398edd3a4af254e09c39f0c00b..3896fce98519be071d6695e0df8ff4f389e68b79 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/postfach/PostfachMailMapperTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/postfach/PostfachMailMapperTest.java
@@ -26,6 +26,7 @@ package de.ozgcloud.archive.postfach;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
+import org.apache.commons.lang3.StringUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -73,6 +74,13 @@ class PostfachMailMapperTest {
 			assertThat(postfachMail).usingRecursiveComparison().isEqualTo(PostfachMailTestFactory.create());
 		}
 
+		@Test
+		void shouldMapEmptyCreatedByToNull() {
+			var postfachMail = mapper.toPostfachMail(GrpcPostfachMailTestFactory.createBuilder().setCreatedBy(StringUtils.EMPTY).build());
+
+			assertThat(postfachMail.getCreatedBy()).isNull();
+		}
+
 		private PostfachMail toPostfachMail() {
 			return mapper.toPostfachMail(GrpcPostfachMailTestFactory.create());
 		}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java
index 10e044811390c0f84e272c069aea7a4718ccf1bd..e72c6347f66a6c5e27cf33583a37198bcb84a71a 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerITCase.java
@@ -50,12 +50,11 @@ class ArchiveEventListenerITCase {
 	@Nested
 	class TestOnArchiveVorgang {
 
-		private static final Command command = CommandTestFactory.createBuilder().order(ArchiveEventListener.ARCHIVE_VORGANG_ORDER)
-				.build();
+		private static final Command COMMAND = CommandTestFactory.createBuilder().order(ArchiveEventListener.ARCHIVE_VORGANG_ORDER).build();
 
 		@Test
 		void shouldReactOnOrder() {
-			var event = CommandCreatedEventTestFactory.withCommand(command);
+			var event = CommandCreatedEventTestFactory.withCommand(COMMAND);
 
 			publisher.publishEvent(event);
 
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java
index b25f1abd967ffbdd254a84f7b0c934c9081281cc..8f0318b145df6c6ea3b7fafbb73a5bafb74ae6dc 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ArchiveEventListenerTest.java
@@ -24,32 +24,23 @@
 package de.ozgcloud.archive.vorgang;
 
 import static org.assertj.core.api.Assertions.*;
-import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Optional;
-import java.util.UUID;
 import java.util.function.Consumer;
 
-import jakarta.activation.DataHandler;
-import jakarta.activation.FileDataSource;
-
-import org.junit.jupiter.api.AfterEach;
 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.MockedConstruction;
-import org.mockito.MockedStatic;
+import org.mockito.Spy;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.security.core.context.SecurityContext;
 
+import de.ozgcloud.archive.attributes.ClientAttributeService;
 import de.ozgcloud.archive.common.callcontext.CurrentUserService;
 import de.ozgcloud.archive.common.command.CommandService;
 import de.ozgcloud.archive.common.errorhandling.TimeoutException;
@@ -59,84 +50,76 @@ import de.ozgcloud.command.CommandCreatedEventTestFactory;
 import de.ozgcloud.command.CommandFailedEvent;
 import de.ozgcloud.command.CommandTestFactory;
 import de.ozgcloud.command.VorgangLockedEvent;
-import de.ozgcloud.common.errorhandling.TechnicalException;
-import de.ozgcloud.xta.client.XtaClient;
-import de.ozgcloud.xta.client.exception.XtaClientException;
-import de.ozgcloud.xta.client.model.XtaFile;
-import de.ozgcloud.xta.client.model.XtaMessage;
-import de.ozgcloud.xta.client.xdomea.XdomeaXtaMessageCreator;
-import lombok.SneakyThrows;
 
 class ArchiveEventListenerTest {
 
+	private static final Command COMMAND = CommandTestFactory.create();
+
+	@Spy
+	@InjectMocks
 	private ArchiveEventListener eventListener;
 
 	@Mock
 	private CurrentUserService currentUserService;
 	@Mock
-	private ApplicationEventPublisher eventPublisher;
+	private ClientAttributeService clientAttributeService;
 	@Mock
-	private ExportService exportService;
+	private VorgangService vorgangService;
 	@Mock
-	private XtaClient xtaClient;
+	private ApplicationEventPublisher eventPublisher;
 	@Mock
 	private CommandService commandService;
+	@Mock
+	private ExportService exportService;
 
 	@Captor
 	private ArgumentCaptor<Consumer<Command>> commandExecutorCapture;
 
-	@BeforeEach
-	void setUp() {
-		eventListener = spy(new ArchiveEventListener(currentUserService, eventPublisher, exportService, Optional.of(xtaClient), commandService));
-	}
-
 	@Nested
 	class TestOnArchiveEvent {
 
-		private static final Command COMMAND = CommandTestFactory.create();
-
 		@BeforeEach
 		void init() {
-			doNothing().when(eventListener).doArchiveVorgang(any());
+			doNothing().when(eventListener).doLockVorgang(any());
 		}
 
 		@Test
 		void shouldCallRunWithSecurityContext() {
-			eventListener.onArchiveVorgangEvent(CommandCreatedEventTestFactory.withCommand(COMMAND));
+			doNothing().when(eventListener).runWithSecurityContext(any(), any());
 
-			verify(eventListener).runWithSecurityContext(eq(COMMAND), any());
-		}
-
-		@Test
-		void shouldCallDoArchiveVorgang() {
 			eventListener.onArchiveVorgangEvent(CommandCreatedEventTestFactory.withCommand(COMMAND));
 
-			verify(eventListener).doArchiveVorgang(COMMAND);
+			verify(eventListener).runWithSecurityContext(eq(COMMAND), commandExecutorCapture.capture());
+			commandExecutorCapture.getValue().accept(COMMAND);
+			verify(eventListener).doLockVorgang(COMMAND);
 		}
 	}
 
 	@Nested
-	class TestDoArchiveVorgang {
+	class TestDoLockVorgang {
 
-		private static final Command COMMAND = CommandTestFactory.create();
+		@Test
+		void shouldCallSetVorgangArchiving() {
+			doLockVorgang();
+
+			verify(clientAttributeService).setVorgangArchiving(CommandTestFactory.VORGANG_ID);
+		}
 
 		@Test
-		void shouldLogArchivingVorgang() {
-			doArchiveVorgang();
+		void shouldCallLockVorgang() {
+			doLockVorgang();
 
-			verify(eventListener).doArchiveVorgang(COMMAND);
+			verify(vorgangService).lockVorgang(COMMAND);
 		}
 
-		private void doArchiveVorgang() {
-			eventListener.doArchiveVorgang(COMMAND);
+		private void doLockVorgang() {
+			eventListener.doLockVorgang(COMMAND);
 		}
 	}
 
 	@Nested
 	class TestRunWithSecurityContext {
 
-		private final Command command = CommandTestFactory.createBuilder().build();
-
 		@Mock
 		private Consumer<Command> commandExecutor;
 		@Mock
@@ -146,26 +129,26 @@ class ArchiveEventListenerTest {
 
 		@BeforeEach
 		void init() {
-			when(currentUserService.startSecurityContext(any())).thenReturn(secContext);
+			when(currentUserService.startAndReturnPreviousSecurityContext(any(Command.class))).thenReturn(secContext);
 		}
 
 		@Test
 		void shouldStartSecurityContext() {
-			eventListener.runWithSecurityContext(command, commandExecutor);
+			eventListener.runWithSecurityContext(COMMAND, commandExecutor);
 
-			verify(currentUserService).startSecurityContext(command);
+			verify(currentUserService).startAndReturnPreviousSecurityContext(COMMAND);
 		}
 
 		@Test
 		void shouldExecuteCommand() {
-			eventListener.runWithSecurityContext(command, commandExecutor);
+			eventListener.runWithSecurityContext(COMMAND, commandExecutor);
 
-			verify(commandExecutor).accept(command);
+			verify(commandExecutor).accept(COMMAND);
 		}
 
 		@Test
 		void shouldResetSecurityContext() {
-			eventListener.runWithSecurityContext(command, commandExecutor);
+			eventListener.runWithSecurityContext(COMMAND, commandExecutor);
 
 			verify(currentUserService).resetSecurityContext(secContext);
 		}
@@ -174,7 +157,7 @@ class ArchiveEventListenerTest {
 		void shouldResetSecurityContextAfterException() {
 			doThrow(new RuntimeException("ups")).when(commandExecutor).accept(any());
 
-			eventListener.runWithSecurityContext(command, commandExecutor);
+			eventListener.runWithSecurityContext(COMMAND, commandExecutor);
 
 			verify(currentUserService).resetSecurityContext(secContext);
 		}
@@ -183,10 +166,10 @@ class ArchiveEventListenerTest {
 		void shouldPublishCommandFailedEvent() {
 			doThrow(new RuntimeException("ups")).when(commandExecutor).accept(any());
 
-			eventListener.runWithSecurityContext(command, commandExecutor);
+			eventListener.runWithSecurityContext(COMMAND, commandExecutor);
 
 			verify(eventPublisher).publishEvent(commandFailedEventCaptor.capture());
-			assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(command.getId());
+			assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID);
 			assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isNotEmpty();
 		}
 	}
@@ -196,7 +179,6 @@ class ArchiveEventListenerTest {
 
 		private final Command command = CommandTestFactory.create();
 		private final VorgangLockedEvent event = new VorgangLockedEvent(command);
-		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
 
 		@BeforeEach
 		void mock() {
@@ -223,30 +205,18 @@ class ArchiveEventListenerTest {
 			@BeforeEach
 			void mock() {
 				doNothing().when(eventListener).runWithSecurityContext(any(), any());
-				doNothing().when(eventListener).sendXdomeaFile(any());
 			}
 
 			@Test
-			void shouldCallBuildXdomeaXtaFile() {
+			void shouldCallRunWithSecurityContext() {
 				onVorgangLockedEvent();
 
 				verify(eventListener).runWithSecurityContext(eq(command), commandExecutorCapture.capture());
 				commandExecutorCapture.getValue().accept(command);
 
-				verify(eventListener).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID);
-			}
-
-			@Test
-			void shouldCallSendXdomeaFile() {
-				doReturn(xdomeaFile).when(eventListener).buildXdomeaXtaFile(CommandTestFactory.VORGANG_ID);
-				onVorgangLockedEvent();
+				verify(exportService).archiveVorgang(command);
 
-				verify(eventListener).runWithSecurityContext(eq(command), commandExecutorCapture.capture());
-				commandExecutorCapture.getValue().accept(command);
-
-				verify(eventListener).sendXdomeaFile(xdomeaFile);
 			}
-
 		}
 
 		private void onVorgangLockedEvent() {
@@ -259,30 +229,32 @@ class ArchiveEventListenerTest {
 
 		@Test
 		void shouldCallCommandServiceForPendingCommandsOnce() {
-			when(commandService.hasPendingCommands(any())).thenReturn(false);
+			when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(false);
 
 			waitForPendingCommandsToFinish();
 
-			verify(commandService).hasPendingCommands(VorgangWithEingangTestFactory.ID);
+			verify(commandService).hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, ArchiveEventListener.ARCHIVE_VORGANG_ORDER);
 		}
 
 		@Test
 		void shouldCallCommandServiceForPendingCommandsTwice() {
-			when(commandService.hasPendingCommands(any())).thenReturn(true)
+			when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(true)
 					.thenReturn(false);
 
 			waitForPendingCommandsToFinish();
 
-			verify(commandService, times(2)).hasPendingCommands(VorgangWithEingangTestFactory.ID);
+			verify(commandService, times(2)).hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID,
+					ArchiveEventListener.ARCHIVE_VORGANG_ORDER);
 		}
 
 		@Test
-		void shouldCallAbortWaitingAfterThreeAttempts() {
-			when(commandService.hasPendingCommands(any())).thenReturn(true);
+		void shouldCallAbortWaitingAfterMaxAttempts() {
+			when(commandService.hasPendingCommandsExceptWithOrder(any(), any())).thenReturn(true);
 
 			var timeoutExceptionThrown = waitForPendingCommandsToFinishAndCatchException();
 
-			verify(commandService, times(3)).hasPendingCommands(VorgangWithEingangTestFactory.ID);
+			verify(commandService, times(ArchiveEventListener.MAXIMUM_CHECKS_FOR_PENDING_COMMANDS))
+					.hasPendingCommandsExceptWithOrder(VorgangWithEingangTestFactory.ID, ArchiveEventListener.ARCHIVE_VORGANG_ORDER);
 			assertThat(timeoutExceptionThrown).isTrue();
 		}
 
@@ -300,287 +272,4 @@ class ArchiveEventListenerTest {
 		}
 	}
 
-	@Nested
-	class TestBuildXdomeaXtaFile {
-
-		private final String fileNameId = UUID.randomUUID().toString();
-
-		@BeforeEach
-		void mock() {
-			doReturn(fileNameId).when(eventListener).createFileNameId();
-			when(exportService.buildXdomeaFileName(fileNameId)).thenReturn(XdomeaXtaFileTestFactory.FILE_NAME);
-		}
-
-		@Test
-		void shouldCallCreateFileNameId() {
-			buildXdomeaXtaFile();
-
-			verify(eventListener).createFileNameId();
-		}
-
-		@Test
-		void shouldCallBuildXdomeaFileName() {
-			buildXdomeaXtaFile();
-
-			verify(exportService).buildXdomeaFileName(fileNameId);
-		}
-
-		@Test
-		void shouldCallCreateFileContent() {
-			buildXdomeaXtaFile();
-
-			verify(eventListener).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
-		}
-
-		@Test
-		void shouldReturnXdomeaFile() {
-			doReturn(XdomeaXtaFileTestFactory.DATA_HANDLER).when(eventListener).createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
-
-			var xdomeaFile = buildXdomeaXtaFile();
-
-			assertThat(xdomeaFile).usingRecursiveComparison().isEqualTo(XdomeaXtaFileTestFactory.create());
-		}
-
-		private XtaFile buildXdomeaXtaFile() {
-			return eventListener.buildXdomeaXtaFile(VorgangWithEingangTestFactory.ID);
-		}
-	}
-
-	@Nested
-	class TestCreateFileNameId {
-
-		private final UUID uuid = UUID.randomUUID();
-
-		@Test
-		void shouldReturnRandomUUID() {
-			try (var mockedStaticUUID = mockStatic(UUID.class)) {
-				mockedStaticUUID.when(UUID::randomUUID).thenReturn(uuid);
-
-				var returnedFileNameId = eventListener.createFileNameId();
-
-				assertThat(returnedFileNameId).isEqualTo(uuid.toString());
-			}
-		}
-	}
-
-	@Nested
-	class TestCreateFileContent {
-
-		private final String fileNameId = UUID.randomUUID().toString();
-
-		@Nested
-		class OnNoExceptionThrown {
-			private MockedConstruction<FileDataSource> fileDataSourceConstruction;
-			private FileDataSource fileDataSource;
-			private File dataSourceFile;
-
-			private MockedConstruction<DataHandler> dataHandlerConstruction;
-			private DataHandler dataHandler;
-			private FileDataSource dataHandlerSource;
-
-			@Mock
-			private File tempFile;
-			@Mock
-			private OutputStream outputStream;
-
-			@BeforeEach
-			@SneakyThrows
-			void setUpMock() {
-				doReturn(tempFile).when(eventListener).createTempFile(fileNameId);
-				fileDataSourceConstruction = mockConstruction(FileDataSource.class,
-						(fileDataSource, context) -> {
-							dataSourceFile = (File) context.arguments().get(0);
-							this.fileDataSource = fileDataSource;
-							when(fileDataSource.getOutputStream()).thenReturn(outputStream);
-						});
-				dataHandlerConstruction = mockConstruction(DataHandler.class, (dataHandler, context) -> {
-					this.dataHandler = dataHandler;
-					dataHandlerSource = (FileDataSource) context.arguments().get(0);
-				});
-			}
-
-			@AfterEach
-			void cleanUp() {
-				fileDataSourceConstruction.close();
-				dataHandlerConstruction.close();
-			}
-
-			@Test
-			@SneakyThrows
-			void shouldCallCreateTempFile() {
-				createFileContent();
-
-				verify(eventListener).createTempFile(fileNameId);
-			}
-
-			@Test
-			void shouldCreateFileDataSourceWithTempFile() {
-				createFileContent();
-
-				assertThat(dataSourceFile).isEqualTo(tempFile);
-			}
-
-			@Test
-			@SneakyThrows
-			void shouldGetOutputStreamOfFileDataSource() {
-				createFileContent();
-
-				verify(fileDataSource).getOutputStream();
-			}
-
-			@Test
-			void shouldWriteXdomeaContentToOutputStream() {
-				createFileContent();
-
-				verify(exportService).writeXdomeaFileContent(VorgangWithEingangTestFactory.ID, fileNameId, outputStream);
-			}
-
-			@Test
-			void shouldConstructDataHandlerFromFileDataSource() {
-				createFileContent();
-
-				assertThat(dataHandlerConstruction.constructed()).hasSize(1);
-				assertThat(dataHandlerSource).isEqualTo(fileDataSource);
-			}
-
-			@Test
-			void shouldReturnDataHandler() {
-				var resultDataHandler = createFileContent();
-
-				assertThat(resultDataHandler).isEqualTo(dataHandler);
-			}
-		}
-
-		@Nested
-		class OnIOExceptionThrown {
-			@Test
-			@SneakyThrows
-			void shouldThrowTechnicalExcpetion() {
-				doThrow(IOException.class).when(eventListener).createTempFile(any());
-
-				assertThrows(TechnicalException.class, () -> createFileContent());
-			}
-		}
-
-		private DataHandler createFileContent() {
-			return eventListener.createFileContent(VorgangWithEingangTestFactory.ID, fileNameId);
-		}
-	}
-
-	@Nested
-	class TestCreateTempFile {
-
-		private final String fileNameId = UUID.randomUUID().toString();
-
-		@Test
-		@SneakyThrows
-		void shouldReturnFile() {
-			var file = eventListener.createTempFile(fileNameId);
-
-			assertThat(file).isNotNull().isInstanceOf(File.class);
-		}
-	}
-
-	@Nested
-	class TestSendXdomeaFile {
-
-		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
-
-		@Mock
-		private XtaMessage xtaMessage;
-
-		@BeforeEach
-		void mock() {
-			doReturn(xtaMessage).when(eventListener).createMessage(xdomeaFile);
-		}
-
-		@Test
-		@SneakyThrows
-		void shouldCallCreateMessage() {
-			sendXdomeaFile();
-
-			verify(eventListener).createMessage(xdomeaFile);
-		}
-
-		@Test
-		@SneakyThrows
-		void shouldSendMessage() {
-			sendXdomeaFile();
-
-			verify(xtaClient).sendMessage(xtaMessage);
-		}
-
-		@Test
-		@SneakyThrows
-		void shouldThrowTechnicalException() {
-			when(xtaClient.sendMessage(any())).thenThrow(XtaClientException.class);
-
-			assertThrows(TechnicalException.class, () -> sendXdomeaFile());
-		}
-
-		private void sendXdomeaFile() {
-			eventListener.sendXdomeaFile(xdomeaFile);
-		}
-	}
-
-	@Nested
-	class TestCreateMessage {
-		private final XtaFile xdomeaFile = XdomeaXtaFileTestFactory.create();
-
-		private MockedStatic<XdomeaXtaMessageCreator> mockedStaticXdomeaXtaMessageCreator;
-
-		@Mock
-		private XdomeaXtaMessageCreator xdomeaXtaMessageCreator;
-		@Mock
-		private XtaMessage xtaMessage;
-
-		@BeforeEach
-		void setUpMock() {
-			mockedStaticXdomeaXtaMessageCreator = mockStatic(XdomeaXtaMessageCreator.class);
-			mockedStaticXdomeaXtaMessageCreator.when(XdomeaXtaMessageCreator::createInstance).thenReturn(xdomeaXtaMessageCreator);
-		}
-
-		@AfterEach
-		void cleanUp() {
-			mockedStaticXdomeaXtaMessageCreator.close();
-		}
-
-		@Test
-		void shouldCreateXdomeaXtaMessageCreator() {
-			createMessage();
-
-			mockedStaticXdomeaXtaMessageCreator.verify(XdomeaXtaMessageCreator::createInstance);
-		}
-
-		@Test
-		@SneakyThrows
-		void shouldCallCreateMessage() {
-			createMessage();
-
-			verify(xdomeaXtaMessageCreator).createMessage(xdomeaFile);
-		}
-
-		@Test
-		@SneakyThrows
-		void shouldReturnMessage() {
-			when(xdomeaXtaMessageCreator.createMessage(any())).thenReturn(xtaMessage);
-
-			var message = createMessage();
-
-			assertThat(message).isEqualTo(xtaMessage);
-		}
-
-		@Test
-		@SneakyThrows
-		void shouldThrowTechnicalException() {
-			when(xdomeaXtaMessageCreator.createMessage(any())).thenThrow(XtaClientException.class);
-
-			assertThrows(TechnicalException.class, () -> createMessage());
-		}
-
-		private XtaMessage createMessage() {
-			return eventListener.createMessage(xdomeaFile);
-		}
-
-	}
 }
\ No newline at end of file
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ExportVorgangServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ExportVorgangServiceTest.java
deleted file mode 100644
index f5e4f059002b028ce6d91d9ef823132ab6fe0c7e..0000000000000000000000000000000000000000
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ExportVorgangServiceTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package de.ozgcloud.archive.vorgang;
-
-import static org.assertj.core.api.Assertions.*;
-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 de.ozgcloud.archive.export.AllgemeineMetadatenTypeTestFactory;
-import de.ozgcloud.archive.export.IdentifikationObjektTypeTestFactory;
-
-public class ExportVorgangServiceTest {
-
-	private final static String VORGANG_ID = VorgangWithEingangTestFactory.ID;
-	private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create();
-
-	@Spy
-	@InjectMocks
-	private ExportVorgangService exportVorgangService;
-
-	@Mock
-	private VorgangRemoteService vorgangRemoteService;
-
-	@Nested
-	class TestGetVorgang {
-
-		@BeforeEach
-		void init() {
-			when(vorgangRemoteService.findVorgangWithEingang(VORGANG_ID)).thenReturn(vorgang);
-		}
-
-		@Test
-		void shouldCallVorgangRemoteService() {
-			callService();
-
-			verify(vorgangRemoteService).findVorgangWithEingang(VORGANG_ID);
-		}
-
-		@Test
-		void shouldReturnVorgangWithEingang() {
-			var vorgangWithEingang = callService();
-
-			assertThat(vorgangWithEingang).isEqualTo(vorgang);
-		}
-
-		private VorgangWithEingang callService() {
-			return exportVorgangService.getVorgang(VORGANG_ID);
-		}
-	}
-
-	@Nested
-	class TestCreateAkteType {
-
-		@Test
-		void shouldCallCreateIdentifikationObjektType() {
-			exportVorgangService.createAkteType(vorgang);
-
-			verify(exportVorgangService).createIdentifikationObjektType();
-		}
-
-		@Test
-		void shouldSetIdentifikationObjektType() {
-			var identifikationObjektType = IdentifikationObjektTypeTestFactory.create();
-			doReturn(identifikationObjektType).when(exportVorgangService).createIdentifikationObjektType();
-
-			var akteType = exportVorgangService.createAkteType(vorgang);
-
-			assertThat(akteType.getIdentifikation()).isEqualTo(identifikationObjektType);
-		}
-
-		@Test
-		void shouldCallCreateAllgemeineMetadatenType() {
-			exportVorgangService.createAkteType(vorgang);
-
-			verify(exportVorgangService).createAllgemeineMetadatenType(vorgang);
-		}
-
-		@Test
-		void shouldSetAllgemeineMetadatenType() {
-			var allgemeineMetadatenType = AllgemeineMetadatenTypeTestFactory.create();
-			doReturn(allgemeineMetadatenType).when(exportVorgangService).createAllgemeineMetadatenType(vorgang);
-
-			var akteType = exportVorgangService.createAkteType(vorgang);
-
-			assertThat(akteType.getAllgemeineMetadaten()).isEqualTo(allgemeineMetadatenType);
-		}
-	}
-
-	@Nested
-	class TestCreateIdentifikationObjektType {
-
-		@Test
-		void shouldSetID() {
-			var identifikationObjektType = exportVorgangService.createIdentifikationObjektType();
-
-			assertThat(identifikationObjektType.getID()).isNotBlank();
-		}
-	}
-
-	@Nested
-	class TestCreateAllgemeineMetadatenType {
-
-		@Test
-		void shouldSetKennzeichen() {
-			var allgemeineMetadatenType = exportVorgangService.createAllgemeineMetadatenType(vorgang);
-
-			assertThat(allgemeineMetadatenType.getKennzeichen()).isEqualTo(VorgangWithEingangTestFactory.AKTENZEICHEN);
-		}
-
-		@Test
-		void shouldSetEmptyKennzeichen() {
-			var akteType = exportVorgangService.createAkteType(VorgangWithEingangTestFactory.createBuilder().aktenzeichen(null).build());
-
-			assertThat(akteType.getAllgemeineMetadaten().getKennzeichen()).isEmpty();
-		}
-	}
-}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java
index 1bfd73805170223678faa0ba163ee83baa4ebec1..f85bdeaeb3753d73df4c193540f70f4d104a64e0 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/KopfCreatorTest.java
@@ -193,7 +193,7 @@ class KopfCreatorTest {
 	class TestCreateKontaktType {
 
 		@Nested
-		class OnBehoerdenschluesselNotSet {
+		class TestOnBehoerdenschluesselNotSet {
 
 			@ParameterizedTest
 			@NullAndEmptySource
@@ -217,7 +217,7 @@ class KopfCreatorTest {
 		}
 
 		@Nested
-		class OnBehoerdenschluesselSet {
+		class TestOnBehoerdenschluesselSet {
 
 			private static final BehoerdenkennungType expectedValue = new BehoerdenkennungType();
 
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ExportVorgangServiceITCase.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceITCase.java
similarity index 92%
rename from archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ExportVorgangServiceITCase.java
rename to archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceITCase.java
index 67dd7e23b03f61bc7cc68eff597e4110c85d4dfb..9bca539cd8db32349881da4186e00aa73cbe0799 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/ExportVorgangServiceITCase.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceITCase.java
@@ -17,10 +17,10 @@ import de.xoev.xdomea.AntragsdatenItemType;
 import de.xoev.xdomea.AntragsdatenSingleValueFieldType;
 
 @ITCase
-class ExportVorgangServiceITCase {
+class VorgangServiceITCase {
 
 	@Autowired
-	private ExportVorgangService exportVorgangService;
+	private VorgangService vorgangService;
 
 	@Nested
 	class TestMapVorgang {
@@ -38,7 +38,7 @@ class ExportVorgangServiceITCase {
 
 			@Test
 			void shouldContainSingleAntragsdatenElement() {
-				var vorgangType = exportVorgangService.createVorgangType(VorgangWithEingangTestFactory.create());
+				var vorgangType = vorgangService.createVorgangType(VorgangWithEingangTestFactory.create());
 
 				assertThat(vorgangType.getAnwendungsspezifischeErweiterungXML().getAny()).hasSize(1).first().isInstanceOf(Antragsdaten.class);
 			}
@@ -91,7 +91,7 @@ class ExportVorgangServiceITCase {
 						.antragsteller(AntragstellerTestFactory.createBuilder().otherData(OTHER_DATA).build())
 						.build();
 				var vorgangWithEingang = VorgangWithEingangTestFactory.createBuilder().eingang(eingang).build();
-				var vorgangType = exportVorgangService.createVorgangType(vorgangWithEingang);
+				var vorgangType = vorgangService.createVorgangType(vorgangWithEingang);
 				return (Antragsdaten) vorgangType.getAnwendungsspezifischeErweiterungXML().getAny().get(0);
 			}
 		}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..98f5ffd07a64fba795c90595cddcb5e13defebc0
--- /dev/null
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/vorgang/VorgangServiceTest.java
@@ -0,0 +1,358 @@
+package de.ozgcloud.archive.vorgang;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Map;
+import java.util.Optional;
+
+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 de.ozgcloud.apilib.common.command.OzgCloudCommand;
+import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
+import de.ozgcloud.apilib.common.command.OzgCloudCreateSubCommandsRequest;
+import de.ozgcloud.apilib.common.command.OzgCloudCreateSubCommandsRequestTestFactory;
+import de.ozgcloud.apilib.common.command.grpc.CommandMapper;
+import de.ozgcloud.apilib.common.command.grpc.OzgCloudCommandTestFactory;
+import de.ozgcloud.apilib.common.datatypes.GenericId;
+import de.ozgcloud.apilib.user.OzgCloudUserId;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper;
+import de.ozgcloud.archive.common.callcontext.CallContextUser;
+import de.ozgcloud.archive.common.callcontext.CallContextUserTestFactory;
+import de.ozgcloud.archive.common.callcontext.CurrentUserService;
+import de.ozgcloud.archive.export.AllgemeineMetadatenTypeTestFactory;
+import de.ozgcloud.archive.export.IdentifikationObjektTypeTestFactory;
+import de.ozgcloud.command.Command;
+import de.ozgcloud.command.CommandTestFactory;
+
+public class VorgangServiceTest {
+
+	private static final String VORGANG_ID = VorgangWithEingangTestFactory.ID;
+	private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create();
+
+	@Spy
+	@InjectMocks
+	private VorgangService vorgangService;
+
+	@Mock
+	private VorgangRemoteService vorgangRemoteService;
+	@Mock
+	private OzgCloudCommandService ozgCloudCommandService;
+	@Mock
+	private CurrentUserService currentUserService;
+	@Mock
+	private OzgCloudVorgangIdMapper ozgCloudVorgangIdMapper;
+	@Mock
+	private CommandMapper commandMapper;
+
+	@Nested
+	class TestGetVorgang {
+
+		@BeforeEach
+		void init() {
+			when(vorgangRemoteService.findVorgangWithEingang(VORGANG_ID)).thenReturn(vorgang);
+		}
+
+		@Test
+		void shouldCallVorgangRemoteService() {
+			callService();
+
+			verify(vorgangRemoteService).findVorgangWithEingang(VORGANG_ID);
+		}
+
+		@Test
+		void shouldReturnVorgangWithEingang() {
+			var vorgangWithEingang = callService();
+
+			assertThat(vorgangWithEingang).isEqualTo(vorgang);
+		}
+
+		private VorgangWithEingang callService() {
+			return vorgangService.getVorgang(VORGANG_ID);
+		}
+	}
+
+	@Nested
+	class TestCreateAkteType {
+
+		@Test
+		void shouldCallCreateIdentifikationObjektType() {
+			vorgangService.createAkteType(vorgang);
+
+			verify(vorgangService).createIdentifikationObjektType();
+		}
+
+		@Test
+		void shouldSetIdentifikationObjektType() {
+			var identifikationObjektType = IdentifikationObjektTypeTestFactory.create();
+			doReturn(identifikationObjektType).when(vorgangService).createIdentifikationObjektType();
+
+			var akteType = vorgangService.createAkteType(vorgang);
+
+			assertThat(akteType.getIdentifikation()).isEqualTo(identifikationObjektType);
+		}
+
+		@Test
+		void shouldCallCreateAllgemeineMetadatenType() {
+			vorgangService.createAkteType(vorgang);
+
+			verify(vorgangService).createAllgemeineMetadatenType(vorgang);
+		}
+
+		@Test
+		void shouldSetAllgemeineMetadatenType() {
+			var allgemeineMetadatenType = AllgemeineMetadatenTypeTestFactory.create();
+			doReturn(allgemeineMetadatenType).when(vorgangService).createAllgemeineMetadatenType(vorgang);
+
+			var akteType = vorgangService.createAkteType(vorgang);
+
+			assertThat(akteType.getAllgemeineMetadaten()).isEqualTo(allgemeineMetadatenType);
+		}
+	}
+
+	@Nested
+	class TestCreateIdentifikationObjektType {
+
+		@Test
+		void shouldSetID() {
+			var identifikationObjektType = vorgangService.createIdentifikationObjektType();
+
+			assertThat(identifikationObjektType.getID()).isNotBlank();
+		}
+	}
+
+	@Nested
+	class TestCreateAllgemeineMetadatenType {
+
+		@Test
+		void shouldSetKennzeichen() {
+			var allgemeineMetadatenType = vorgangService.createAllgemeineMetadatenType(vorgang);
+
+			assertThat(allgemeineMetadatenType.getKennzeichen()).isEqualTo(VorgangWithEingangTestFactory.AKTENZEICHEN);
+		}
+
+		@Test
+		void shouldSetEmptyKennzeichen() {
+			var akteType = vorgangService.createAkteType(VorgangWithEingangTestFactory.createBuilder().aktenzeichen(null).build());
+
+			assertThat(akteType.getAllgemeineMetadaten().getKennzeichen()).isEmpty();
+		}
+	}
+
+	@Nested
+	class TestLockVorgang {
+
+		private static final Command COMMAND = CommandTestFactory.create();
+		private static final OzgCloudCommand SUB_COMMAND = OzgCloudCommandTestFactory.create();
+		private static final OzgCloudCreateSubCommandsRequest CREATE_SUB_COMMANDS_REQUEST = OzgCloudCreateSubCommandsRequestTestFactory.create();
+
+		@BeforeEach
+		void init() {
+			doReturn(SUB_COMMAND).when(vorgangService).buildLockVorgangSubCommand(any());
+			doReturn(CREATE_SUB_COMMANDS_REQUEST).when(vorgangService).buildCreateSubCommandsRequest(any(), any());
+		}
+
+		@Test
+		void shouldCallBuildLockVorgangSubCommand() {
+			vorgangService.lockVorgang(COMMAND);
+
+			verify(vorgangService).buildLockVorgangSubCommand(COMMAND);
+		}
+
+		@Test
+		void shouldCallBuildCreateSubCommandsRequest() {
+			vorgangService.lockVorgang(COMMAND);
+
+			verify(vorgangService).buildCreateSubCommandsRequest(CommandTestFactory.ID, SUB_COMMAND);
+		}
+
+		@Test
+		void shouldCallAddSubCommands() {
+			vorgangService.lockVorgang(COMMAND);
+
+			verify(ozgCloudCommandService).addSubCommands(CREATE_SUB_COMMANDS_REQUEST);
+		}
+	}
+
+	@Nested
+	class TestBuildLockVorgangSubCommand {
+
+		private static final long RELATION_VERSION = 10;
+		private static final Command COMMAND = CommandTestFactory.createBuilder().relationVersion(RELATION_VERSION).build();
+
+		@BeforeEach
+		void init() {
+			doReturn(Optional.of(OzgCloudCommandTestFactory.CREATED_BY)).when(vorgangService).getUserId();
+		}
+
+		@Test
+		void shouldSetOrder() {
+			var result = vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			assertThat(result.getOrder()).isEqualTo(VorgangService.LOCK_VORGANG_ORDER);
+		}
+
+		@Test
+		void shouldSetVorgangId() {
+			when(commandMapper.toOzgCloudVorgangId(anyString())).thenReturn(OzgCloudVorgangId.from(CommandTestFactory.VORGANG_ID));
+
+			var result = vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			verify(commandMapper).toOzgCloudVorgangId(CommandTestFactory.VORGANG_ID);
+			assertThat(result.getVorgangId()).hasToString(CommandTestFactory.VORGANG_ID);
+		}
+
+		@Test
+		void shouldSetRelationId() {
+			when(commandMapper.mapRelationId(anyString())).thenReturn(GenericId.from(CommandTestFactory.VORGANG_ID));
+
+			var result = vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			verify(commandMapper).mapRelationId(CommandTestFactory.VORGANG_ID);
+			assertThat(result.getRelationId()).hasToString(CommandTestFactory.VORGANG_ID);
+		}
+
+		@Test
+		void shouldSetRelationVersion() {
+			var result = vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			assertThat(result.getRelationVersion()).isEqualTo(RELATION_VERSION);
+		}
+
+		@Test
+		void shouldCallBuildObjectBody() {
+			vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			verify(vorgangService).buildObjectBody();
+		}
+
+		@Test
+		void shouldSetBodyObject() {
+			var bodyObject = Map.<String, Object>of("key", "value");
+			doReturn(bodyObject).when(vorgangService).buildObjectBody();
+
+			var result = vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			assertThat(result.getBodyObject()).containsExactlyEntriesOf(bodyObject);
+		}
+
+		@Test
+		void shouldCallGetUserId() {
+			vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			verify(vorgangService).getUserId();
+		}
+
+		@Test
+		void shouldSetCreatedBy() {
+			var result = vorgangService.buildLockVorgangSubCommand(COMMAND);
+
+			assertThat(result.getCreatedBy()).isEqualTo(OzgCloudCommandTestFactory.CREATED_BY);
+		}
+	}
+
+	@Nested
+	class TestBuildObjectBody {
+
+		@Test
+		void shouldReturnBodyObject() {
+			var result = vorgangService.buildObjectBody();
+
+			assertThat(result).containsExactly(Map.entry(VorgangService.KEY_LOCK_VORGANG_REASON, VorgangService.LOCK_VORGANG_REASON));
+		}
+	}
+
+	@Nested
+	class TestGetUserId {
+
+		@Nested
+		class TestWithUser {
+
+			private static final CallContextUser CALL_CONTEXT_USER = CallContextUserTestFactory.create();
+
+			@BeforeEach
+			void init() {
+				when(currentUserService.findUser()).thenReturn(Optional.of(CALL_CONTEXT_USER));
+			}
+
+			@Test
+			void shouldCallFindUserId() {
+				vorgangService.getUserId();
+
+				verify(currentUserService).findUser();
+			}
+
+			@Test
+			void shouldReturnUserId() {
+				when(commandMapper.toOzgCloudUserId(anyString())).thenReturn(OzgCloudUserId.from(CallContextUserTestFactory.USER_ID));
+
+				var result = vorgangService.getUserId();
+
+				verify(commandMapper).toOzgCloudUserId(CallContextUserTestFactory.USER_ID);
+				assertThat(result).get().hasToString(CallContextUserTestFactory.USER_ID);
+			}
+		}
+
+		@Nested
+		class TestMissingUser {
+
+			@Test
+			void shouldHandleMissingUser() {
+				var result = vorgangService.getUserId();
+
+				assertThat(result).isEmpty();
+			}
+
+			@Test
+			void shouldHandleMissingUserId() {
+				when(currentUserService.findUser()).thenReturn(
+						Optional.of(CallContextUserTestFactory.createBuilder().userId(Optional.empty()).build()));
+
+				var result = vorgangService.getUserId();
+
+				assertThat(result).isEmpty();
+			}
+		}
+	}
+
+	@Nested
+	class TestBuildCreateSubCommandsRequest {
+
+		@Test
+		void shouldSetParentId() {
+			var result = vorgangService.buildCreateSubCommandsRequest(CommandTestFactory.ID, OzgCloudCommandTestFactory.create());
+
+			assertThat(result.getParentId()).isEqualTo(CommandTestFactory.ID);
+		}
+
+		@Test
+		void shouldSetSubCommand() {
+			var subCommand = OzgCloudCommandTestFactory.create();
+
+			var result = vorgangService.buildCreateSubCommandsRequest(CommandTestFactory.ID, subCommand);
+
+			assertThat(result.getSubCommands()).containsExactly(subCommand);
+		}
+
+		@Test
+		void shouldSetCompletedIfSubsCompleted() {
+			var result = vorgangService.buildCreateSubCommandsRequest(CommandTestFactory.ID, OzgCloudCommandTestFactory.create());
+
+			assertThat(result.isCompletedIfSubsCompleted()).isFalse();
+		}
+
+		@Test
+		void shouldSetExecutionMode() {
+			var result = vorgangService.buildCreateSubCommandsRequest(CommandTestFactory.ID, OzgCloudCommandTestFactory.create());
+
+			assertThat(result.getExecutionMode()).isEqualTo(VorgangService.SUB_COMMAND_EXECUTION_MODE);
+		}
+	}
+}
diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/xta/XtaServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/xta/XtaServiceTest.java
index ab324d996b94fb8220a680de855bbeb57a6dc323..eca8e2904fa8840c4f730e55c21e0c72883026e0 100644
--- a/archive-manager-server/src/test/java/de/ozgcloud/archive/xta/XtaServiceTest.java
+++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/xta/XtaServiceTest.java
@@ -24,7 +24,6 @@ import de.ozgcloud.archive.common.command.CommandService;
 import de.ozgcloud.archive.common.command.CommandTestFactory;
 import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory;
 import de.ozgcloud.archive.xta.XtaImportConfirmationHandler.XtaAbgabeHandler;
-import de.ozgcloud.command.Command;
 import de.ozgcloud.command.CommandExecutedEvent;
 import de.ozgcloud.command.CommandFailedEvent;
 import de.ozgcloud.common.errorhandling.TechnicalException;
@@ -158,8 +157,8 @@ class XtaServiceTest {
 		@Nested
 		class TestOnExistingPendingCommands {
 
-			private final Command command = CommandTestFactory.create();
-			private final List<Command> commands = List.of(command);
+			private final ArchiveManagerCommand command = CommandTestFactory.create();
+			private final List<ArchiveManagerCommand> commands = List.of(command);
 
 			@BeforeEach
 			void mock() {
@@ -194,8 +193,8 @@ class XtaServiceTest {
 		@Mock
 		private XtaAbgabeHandler abgabeHandler;
 
-		private final Command command = CommandTestFactory.create();
-		private final List<Command> commands = List.of(command, command);
+		private final ArchiveManagerCommand command = CommandTestFactory.create();
+		private final List<ArchiveManagerCommand> commands = List.of(command, command);
 
 		@Test
 		void shouldCallIsSuccessfullyDone() {
diff --git a/archive-manager-server/src/test/resources/application-itcase.yaml b/archive-manager-server/src/test/resources/application-itcase.yaml
index f2a8a5d0796d5ec6483ce121ae70e06afe5b7686..9bd1a3bb14e6dac750aca9251cb49cad90684702 100644
--- a/archive-manager-server/src/test/resources/application-itcase.yaml
+++ b/archive-manager-server/src/test/resources/application-itcase.yaml
@@ -11,10 +11,7 @@ ozgcloud:
     keystore:
       file: classpath:xtaTestStore.p12
       password: changeit
-    clientIdentifiers:
-      - name:
-        category: Generischer Antragsempfänger
-        value: gae:dev-environment@ozg-cloud.de
+    clientIdentifiers: '[{"category":"Generischer Antragsempfänger","name":"ozg-cloud dev","value":"gae:dev-environment@ozg-cloud.de"}]'
 
 grpc:
   server:
diff --git a/lombok.config b/lombok.config
index a0e918012b6da2b2cd06374cf7ac35d085bfa3e0..8e315e3261a9b09aaf535702db799d3991736230 100644
--- a/lombok.config
+++ b/lombok.config
@@ -28,4 +28,5 @@ lombok.log.log4j.flagUsage = ERROR
 lombok.data.flagUsage = ERROR
 lombok.nonNull.exceptionType = IllegalArgumentException
 lombok.addLombokGeneratedAnnotation = true
-lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
\ No newline at end of file
+lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
+lombok.copyableAnnotations += net.devh.boot.grpc.client.inject.GrpcClient
diff --git a/pom.xml b/pom.xml
index 92543877d7685411887e7fd18ef06f64204237e4..5c31ba4d403d7254f6296eb87f85967f385b6157 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,12 +7,12 @@
 	<parent>
 		<groupId>de.ozgcloud.common</groupId>
 		<artifactId>ozgcloud-common-parent</artifactId>
-		<version>4.6.0-SNAPSHOT</version>
+		<version>4.7.0</version>
 	</parent>
 
 	<groupId>de.ozgcloud.archive</groupId>
 	<artifactId>archive-manager</artifactId>
-	<version>0.1.0-SNAPSHOT</version>
+	<version>0.2.0-SNAPSHOT</version>
 	<packaging>pom</packaging>
 
 	<modules>
@@ -25,13 +25,13 @@
 		<maven.compiler.target>${java.version}</maven.compiler.target>
 		<jaxb2-maven-plugin.version>3.1.0</jaxb2-maven-plugin.version>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-		<vorgang-manager.version>2.18.0-SNAPSHOT</vorgang-manager.version>
-		<nachrichten-manager.version>2.15.0-SNAPSHOT</nachrichten-manager.version>
-		<api-lib.version>0.13.0</api-lib.version>
+		<vorgang-manager.version>2.18.0</vorgang-manager.version>
+		<nachrichten-manager.version>2.15.0</nachrichten-manager.version>
+		<api-lib.version>0.16.0-PR-38-SNAPSHOT</api-lib.version>
 		<find-and-replace-maven-plugin.version>1.2.0</find-and-replace-maven-plugin.version>
 		<protoc-jar-plugin.version>3.11.4</protoc-jar-plugin.version>
-		<ozgcloud-common.version>4.6.0-SNAPSHOT</ozgcloud-common.version>
-		<document-manager.version>1.1.0-SNAPSHOT</document-manager.version>
+		<ozgcloud-common.version>4.7.0</ozgcloud-common.version>
+		<document-manager.version>1.1.0</document-manager.version>
 		<xta-client-lib.version>0.1.0</xta-client-lib.version>
 	</properties>
 	<dependencyManagement>