diff --git a/vorgang-manager-server/pom.xml b/vorgang-manager-server/pom.xml
index c50d1b2301e66944d8a5bc355c11786a2a3921ab..0c6f535369777e48782044894c76fc00eb140673 100644
--- a/vorgang-manager-server/pom.xml
+++ b/vorgang-manager-server/pom.xml
@@ -32,7 +32,7 @@
 	<parent>
 		<groupId>de.ozgcloud.common</groupId>
 		<artifactId>ozgcloud-common-parent</artifactId>
-		<version>4.3.1</version>
+		<version>4.3.2</version>
 		<relativePath />
 	</parent>
 
@@ -60,7 +60,7 @@
 		<notification-manager.version>2.12.0-SNAPSHOT</notification-manager.version>
 		<collaboration-manager.version>0.4.0-OZG-6944-resolve-bean-conflict-SNAPSHOT</collaboration-manager.version>
 
-		<zip.version>2.11.1</zip.version>
+		<zip.version>2.11.5</zip.version>
 		<jsoup.version>1.15.3</jsoup.version>
 		<mongock.version>5.3.4</mongock.version>
 		<testcontainer.version>1.17.3</testcontainer.version>
diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java
index d32ceb17e036e0a53256725a3551aada94097afd..51f3cdcefce8386b38119051129a0b6e11148b90 100644
--- a/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java
+++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java
@@ -21,9 +21,13 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.gridfs.GridFsTemplate;
+import org.springframework.security.saml2.core.Saml2Error;
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.annotation.DirtiesContext;
 
+import com.google.protobuf.ByteString;
+
 import de.ozgcloud.apilib.common.errorhandling.NotFoundException;
 import de.ozgcloud.common.test.DataITCase;
 import de.ozgcloud.common.test.TestUtils;
@@ -33,7 +37,10 @@ import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory;
 import de.ozgcloud.nachrichten.postfach.osi.ReplyOption;
 import de.ozgcloud.vorgang.VorgangManagerServerApplication;
 import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem;
+import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem.VorgangAttachedItemBuilder;
 import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory;
+import de.ozgcloud.vorgang.files.GridFsTestFactory;
+import de.ozgcloud.vorgang.files.OzgFileTestFactory;
 import de.ozgcloud.vorgang.servicekonto.PostfachAddressTestFactory;
 import de.ozgcloud.vorgang.servicekonto.ServiceKonto;
 import de.ozgcloud.vorgang.servicekonto.ServiceKontoTestFactory;
@@ -64,6 +71,8 @@ class AntragraumITCase {
 	private AntragraumGrpcService grpcService;
 	@Autowired
 	private MongoOperations mongoOperations;
+	@Autowired
+	private GridFsTemplate gridFsTemplate;
 
 	@MockBean
 	private Saml2Decrypter decrypter;
@@ -74,6 +83,8 @@ class AntragraumITCase {
 	void prepareDatabase() {
 		mongoOperations.dropCollection(Vorgang.COLLECTION_NAME);
 		mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME);
+		mongoOperations.dropCollection("fs.files");
+		mongoOperations.dropCollection("fs.chunks");
 	}
 
 	@DisplayName("Find rueckfragen")
@@ -188,7 +199,7 @@ class AntragraumITCase {
 		}
 	}
 
-	@DisplayName("Ger rueckfrage")
+	@DisplayName("Get rueckfrage")
 	@Nested
 	class TestGetRueckfrage {
 
@@ -208,7 +219,7 @@ class AntragraumITCase {
 					VorgangAttachedItem.COLLECTION_NAME);
 
 			when(verifier.verify(any())).thenReturn(Collections.emptyList());
-			when(decrypter.decryptTrustLevel(any())).thenReturn("STORK-QAA-Level-1");
+			when(decrypter.decryptTrustLevel(any())).thenReturn(ServiceKontoTestFactory.TRUST_LEVEL);
 		}
 
 		@Test
@@ -240,6 +251,167 @@ class AntragraumITCase {
 		}
 	}
 
+	@Nested
+	class TestGetAttachmentMetadata {
+
+		private static final String SAML_TOKEN = TestUtils.loadTextFile("SamlResponse.xml");
+
+		@Mock
+		private StreamObserver<GrpcGetAttachmentMetadataResponse> responseObserver;
+
+		@Captor
+		private ArgumentCaptor<GrpcGetAttachmentMetadataResponse> captor;
+
+		private Vorgang savedVorgang;
+		private VorgangAttachedItem vorgangAttachedItem;
+		private VorgangAttachedItem vorgangAttachedItemOtherAttachment;
+		private String fileId;
+
+		@BeforeEach
+		void prepareDatabase() {
+			fileId = gridFsTemplate.store(GridFsTestFactory.createUpload()).toString();
+			savedVorgang = mongoOperations.save(createVorgang(TrustLevel.LEVEL_3), Vorgang.COLLECTION_NAME);
+			vorgangAttachedItem = mongoOperations.save(createPostfachNachrichtVorgangAttachedItem(savedVorgang.getId(), fileId),
+					VorgangAttachedItem.COLLECTION_NAME);
+			vorgangAttachedItemOtherAttachment = mongoOperations.save(createPostfachNachrichtVorgangAttachedItem(savedVorgang.getId()),
+					VorgangAttachedItem.COLLECTION_NAME);
+		}
+
+		@Test
+		void shouldSendMetadata() {
+			when(verifier.verify(any())).thenReturn(Collections.emptyList());
+			when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue());
+			when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE);
+			var request = GrpcGetAttachmentMetadataRequest.newBuilder()
+					.setSamlToken(SAML_TOKEN)
+					.setNachrichtId(vorgangAttachedItem.getId())
+					.setFileId(fileId)
+					.build();
+			var expectedMetadata = GrpcFileMetadata.newBuilder()
+					.setContentType(OzgFileTestFactory.CONTENT_TYPE)
+					.setName(OzgFileTestFactory.NAME)
+					.setSize(OzgFileTestFactory.CONTENT.length)
+					.build();
+
+			grpcService.getAttachmentMetadata(request, responseObserver);
+
+			verify(responseObserver, timeout(30000)).onNext(captor.capture());
+			assertThat(captor.getValue().getFileMetadata()).isEqualTo(expectedMetadata);
+		}
+
+		@Test
+		void shouldFailDueToInvalidToken() {
+			when(verifier.verify(any())).thenReturn(List.of(new Saml2Error("invalid_signature", "Signature missing")));
+			when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue());
+			when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE);
+			var request = GrpcGetAttachmentMetadataRequest.newBuilder()
+					.setSamlToken(SAML_TOKEN)
+					.setNachrichtId(vorgangAttachedItem.getId())
+					.setFileId(fileId)
+					.build();
+
+			assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver))
+					.isInstanceOf(SecurityException.class)
+					.hasMessageContaining("Signature missing")
+					.hasMessageContaining("invalid_signature");
+
+		}
+
+		@Test
+		void shouldFailDueIncorrectPostfachId() {
+			when(verifier.verify(any())).thenReturn(Collections.emptyList());
+			when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue());
+			when(decrypter.decryptPostfachId(any())).thenReturn("wrong ID");
+			var request = GrpcGetAttachmentMetadataRequest.newBuilder()
+					.setSamlToken(SAML_TOKEN)
+					.setNachrichtId(vorgangAttachedItem.getId())
+					.setFileId(fileId)
+					.build();
+
+			assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver))
+					.isInstanceOf(NotFoundException.class)
+					.hasMessageContaining("PostfachNachricht")
+					.hasMessageContaining(vorgangAttachedItem.getId());
+		}
+
+		@Test
+		void shouldFailDueToTrustLevelTooLow() {
+			when(verifier.verify(any())).thenReturn(Collections.emptyList());
+			when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_2.getValue());
+			when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE);
+			var request = GrpcGetAttachmentMetadataRequest.newBuilder()
+					.setSamlToken(SAML_TOKEN)
+					.setNachrichtId(vorgangAttachedItem.getId())
+					.setFileId(fileId)
+					.build();
+
+			assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver))
+					.isInstanceOf(NotFoundException.class)
+					.hasMessageContaining("PostfachNachricht")
+					.hasMessageContaining(vorgangAttachedItem.getId());
+		}
+
+		@Test
+		void shouldFailDueToFileIdNotInPostfachNachricht() {
+			when(verifier.verify(any())).thenReturn(Collections.emptyList());
+			when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue());
+			when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE);
+			var request = GrpcGetAttachmentMetadataRequest.newBuilder()
+					.setSamlToken(SAML_TOKEN)
+					.setNachrichtId(vorgangAttachedItemOtherAttachment.getId())
+					.setFileId(fileId)
+					.build();
+
+			assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver))
+					.isInstanceOf(NotFoundException.class)
+					.hasMessageContaining("PostfachNachricht")
+					.hasMessageContaining(vorgangAttachedItemOtherAttachment.getId());
+		}
+
+	}
+
+	@Nested
+	class TestGetAttachmentContent {
+
+		private static final String SAML_TOKEN = TestUtils.loadTextFile("SamlResponse.xml");
+
+		@Mock
+		private StreamObserver<GrpcGetAttachmentContentResponse> responseObserver;
+
+		@Captor
+		private ArgumentCaptor<GrpcGetAttachmentContentResponse> captor;
+
+		private Vorgang savedVorgang;
+		private VorgangAttachedItem vorgangAttachedItem;
+		private String fileId;
+
+		@BeforeEach
+		void prepareDatabase() {
+			fileId = gridFsTemplate.store(GridFsTestFactory.createUpload()).toString();
+			savedVorgang = mongoOperations.save(createVorgang(TrustLevel.LEVEL_3), Vorgang.COLLECTION_NAME);
+			vorgangAttachedItem = mongoOperations.save(createPostfachNachrichtVorgangAttachedItem(savedVorgang.getId(), fileId),
+					VorgangAttachedItem.COLLECTION_NAME);
+		}
+
+		@Test
+		void shouldSendContent() {
+			when(verifier.verify(any())).thenReturn(Collections.emptyList());
+			when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue());
+			when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE);
+			var request = GrpcGetAttachmentContentRequest.newBuilder()
+					.setSamlToken(SAML_TOKEN)
+					.setNachrichtId(vorgangAttachedItem.getId())
+					.setFileId(fileId)
+					.build();
+			var expectedContent = ByteString.copyFrom(OzgFileTestFactory.CONTENT);
+
+			grpcService.getAttachmentContent(request, responseObserver);
+
+			verify(responseObserver, timeout(30000)).onNext(captor.capture());
+			assertThat(captor.getValue().getFileContent()).isEqualTo(expectedContent);
+		}
+	}
+
 	private Vorgang createVorgang(TrustLevel trustLevel) {
 		return VorgangTestFactory.createBuilder()
 				.id(null)
@@ -252,15 +424,30 @@ class AntragraumITCase {
 		return ServiceKontoTestFactory.createBuilder().type("BAYERN_ID").trustLevel(trustLevel.getValue()).build();
 	}
 
+	private VorgangAttachedItem createPostfachNachrichtVorgangAttachedItem(String vorgangId, String fileId) {
+		return createPostfachNachrichtVorgangAttachedItemBuilder(vorgangId)
+				.item(createBayernIdPostfachNachrichtItem(vorgangId, fileId))
+				.build();
+	}
+
 	private VorgangAttachedItem createPostfachNachrichtVorgangAttachedItem(String vorgangId) {
+		return createPostfachNachrichtVorgangAttachedItemBuilder(vorgangId).build();
+	}
+
+	private VorgangAttachedItemBuilder createPostfachNachrichtVorgangAttachedItemBuilder(String vorgangId) {
 		return VorgangAttachedItemTestFactory.createBuilder()
 				.id(null)
 				.version(0)
 				.vorgangId(vorgangId)
 				.itemName("PostfachMail")
 				.client("OzgCloud_NachrichtenManager")
-				.item(createBayernIdPostfachNachrichtItem(vorgangId))
-				.build();
+				.item(createBayernIdPostfachNachrichtItem(vorgangId));
+	}
+
+	private Map<String, Object> createBayernIdPostfachNachrichtItem(String vorgangId, String fileId) {
+		var nachrichtItem = createBayernIdPostfachNachrichtItem(vorgangId);
+		nachrichtItem.put("attachments", List.of(fileId));
+		return nachrichtItem;
 	}
 
 	private Map<String, Object> createBayernIdPostfachNachrichtItem(String vorgangId) {