diff --git a/vorgang-manager-command/src/main/java/de/ozgcloud/command/Command.java b/vorgang-manager-command/src/main/java/de/ozgcloud/command/Command.java
index 61876bd402f13ce74003c41efe440aca9fa4165b..03beadfa1d78503796ab49ce66050226de991ee9 100644
--- a/vorgang-manager-command/src/main/java/de/ozgcloud/command/Command.java
+++ b/vorgang-manager-command/src/main/java/de/ozgcloud/command/Command.java
@@ -44,6 +44,7 @@ public interface Command {
 	public String getCreatedBy();
 	public String getCreatedByName();
 	public CommandStatus getStatus();
+	String getCreatedByClient();
 
 	public Map<String, Object> getBodyObject();
 	public Map<String, String> getBody();
diff --git a/vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java b/vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java
index 3ebddf936e18f8c1576ca81400a5a93cd1f7ec07..3d2c5d8263bd630782c6b968d50c265e15c0597c 100644
--- a/vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java
+++ b/vorgang-manager-command/src/test/java/de/ozgcloud/command/TestCommand.java
@@ -21,6 +21,7 @@ public class TestCommand implements Command {
 	private ZonedDateTime finishedAt;
 	private String createdBy;
 	private String createdByName;
+	private String createdByClient;
 
 	private CommandStatus status;
 
diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistedCommand.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistedCommand.java
index 71964af4d27968376adf98bb011157c544c41e37..0973a39797c8235f7d02f1ee9a3bb363ae235817 100644
--- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistedCommand.java
+++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/command/PersistedCommand.java
@@ -63,6 +63,7 @@ public class PersistedCommand implements Command {
 
 	private String createdBy;
 	private String createdByName;
+	private String createdByClient;
 
 	@Setter
 	private CommandStatus status;
diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Vorgang.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Vorgang.java
index 88557e44c95e469d95f17dbd1f413c3e941b19fc..979de7347065ba922cf5b41c2eb4151bfc293013 100644
--- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Vorgang.java
+++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/Vorgang.java
@@ -50,6 +50,7 @@ public class Vorgang {
 	static final String MONGODB_FIELDNAME_CREATED_AT = "createdAt";
 	public static final String MONGODB_FIELDNAME_ASSIGNED_TO = "assignedTo";
 	public static final String MONGODB_FIELDNAME_IN_CREATION = "inCreation";
+	public static final String MONGODB_FIELDNAME_HEADER = "header";
 
 	public static final String FIELD_EINGANGSKENNZ = "eingangs.header.requestId";
 	public static final String FIELD_AKTENZEICHEN = "aktenzeichen";
diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.java
index ee5dc6b922cdaaf267c7c69d49234ac2628751b6..2f3cb7ddde140b25b2e624da26d1594735bddaf7 100644
--- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.java
+++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangHead.java
@@ -11,6 +11,8 @@ import lombok.Getter;
 @TypeAlias("VorgangHeader")
 public class VorgangHead {
 
+	public static final String FIELD_LOCK = "lock";
+
 	private ServiceKonto serviceKonto;
 
 	private String organisationsEinheitId;
diff --git a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java
index 274e1945c40d174731604e4ab38dd291417d1e93..801685f1f65300819e724da8b4811399b75a6a49 100644
--- a/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java
+++ b/vorgang-manager-server/src/main/java/de/ozgcloud/vorgang/vorgang/VorgangService.java
@@ -23,10 +23,13 @@
  */
 package de.ozgcloud.vorgang.vorgang;
 
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -45,6 +48,7 @@ import de.ozgcloud.command.Command;
 import de.ozgcloud.command.VorgangAssignedEvent;
 import de.ozgcloud.command.VorgangCreatedEvent;
 import de.ozgcloud.command.VorgangLockedEvent;
+import de.ozgcloud.common.errorhandling.TechnicalException;
 import de.ozgcloud.vorgang.clientattribute.ClientAttributeMap;
 import de.ozgcloud.vorgang.clientattribute.ClientAttributeReadPermitted;
 import de.ozgcloud.vorgang.clientattribute.ClientAttributesMap;
@@ -58,6 +62,7 @@ public class VorgangService {
 
 	private static final String BODY_ASSIGNED_TO_FIELD = "assignedTo";
 	public static final String BODY_OBJECT_AKTENZEICHEN = "aktenzeichen";
+	static final String KEY_HEADER_LOCK = "%s.%s".formatted(Vorgang.MONGODB_FIELDNAME_HEADER, VorgangHead.FIELD_LOCK);
 
 	@Autowired
 	private VorgangAuthorizationService vorgangAuthenticationService;
@@ -226,9 +231,31 @@ public class VorgangService {
 	}
 
 	public void lockVorgang(Command command) {
+		validateLockCommand(command);
+		repository.patch(command.getVorgangId(), command.getRelationVersion(), buildLockPatch(command));
 		publisher.publishEvent(new VorgangLockedEvent(command));
 	}
 
+	void validateLockCommand(Command command) {
+		if (Objects.isNull(command.getCreatedByClient())) {
+			throw new TechnicalException("Missing client name in lock command");
+		}
+		if (Objects.isNull(getReason(command.getBodyObject()))) {
+			throw new TechnicalException("Missing reason in lock command");
+		}
+	}
+
+	Map<String, Object> buildLockPatch(Command command) {
+		return Map.of(KEY_HEADER_LOCK, Map.of(
+				Lock.FIELD_CLIENT_NAME, command.getCreatedByClient(),
+				Lock.FIELD_LOCKED_SINCE, ZonedDateTime.now(ZoneId.of("UTC")),
+				Lock.FIELD_REASON, getReason(command.getBodyObject())));
+	}
+
+	String getReason(Map<String, Object> commandBody) {
+		return StringUtils.trimToNull(MapUtils.getString(commandBody, Lock.FIELD_REASON));
+	}
+
 	public void unlockVorgang(Command command) {
 		// TODO wird implementiert in OZG-6992
 		// publisher.publishEvent(new CommandRevokedEvent(command));
diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandTestFactory.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandTestFactory.java
index ff3e080efe5ba9eaa41c46b74820bcda8427dd5c..47f9149c3e6ccb74edeb5add3842b81b02cd7646 100644
--- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandTestFactory.java
+++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/command/CommandTestFactory.java
@@ -29,6 +29,7 @@ import java.util.UUID;
 
 import de.ozgcloud.command.CommandStatus;
 import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory;
+import de.ozgcloud.vorgang.callcontext.CallContextTestFactory;
 import de.ozgcloud.vorgang.callcontext.UserTestFactory;
 import de.ozgcloud.vorgang.vorgang.VorgangTestFactory;
 
@@ -39,6 +40,7 @@ public class CommandTestFactory {
 	public static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(CREATED_AT_STR);
 	public static final String CREATED_BY = UserTestFactory.ID;
 	public static final String CREATED_BY_NAME = UserTestFactory.NAME;
+	public static final String CREATED_BY_CLIENT = CallContextTestFactory.CLIENT;
 	public static final CommandStatus STATUS = CommandStatus.PENDING;
 
 	public static final String RELATION_ID = VorgangAttachedItemTestFactory.ID;
@@ -59,6 +61,7 @@ public class CommandTestFactory {
 				.createdAt(CREATED_AT)
 				.createdBy(CREATED_BY)
 				.createdByName(CREATED_BY_NAME)
+				.createdByClient(CREATED_BY_CLIENT)
 				.status(STATUS)
 				.relationId(RELATION_ID)
 				.relationVersion(RELATION_VERSION)
diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java
index c6a8daf26e2d1696cad785c5cb1c66cf1d73f33a..db34a67ab574fbeb28cf458ef75766e20714943c 100644
--- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java
+++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/vorgang/VorgangServiceTest.java
@@ -28,10 +28,13 @@ import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.time.ZonedDateTime;
+import java.time.temporal.ChronoUnit;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
+import org.assertj.core.api.InstanceOfAssertFactories;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
@@ -49,6 +52,8 @@ import org.springframework.security.access.AccessDeniedException;
 import de.ozgcloud.command.Command;
 import de.ozgcloud.command.VorgangAssignedEvent;
 import de.ozgcloud.command.VorgangCreatedEvent;
+import de.ozgcloud.command.VorgangLockedEvent;
+import de.ozgcloud.common.errorhandling.TechnicalException;
 import de.ozgcloud.vorgang.clientattribute.ClientAttributeReadPermitted;
 import de.ozgcloud.vorgang.command.CommandTestFactory;
 import de.ozgcloud.vorgang.common.errorhandling.NotFoundException;
@@ -507,4 +512,108 @@ class VorgangServiceTest {
 			verify(repository).setAktenzeichen(VorgangTestFactory.ID, CommandTestFactory.RELATION_VERSION, null);
 		}
 	}
+
+	@Nested
+	class TestLockVorgang {
+
+		private static final Command LOCK_COMMAND = CommandTestFactory.create();
+		private static final Map<String, Object> LOCK_PATCH = Map.of("key", "value");
+
+		@Captor
+		private ArgumentCaptor<VorgangLockedEvent> eventCaptor;
+
+		@BeforeEach
+		void init() {
+			doNothing().when(service).validateLockCommand(any());
+			doReturn(LOCK_PATCH).when(service).buildLockPatch(any());
+		}
+
+		@Test
+		void shouldCallValidateLockCommand() {
+			service.lockVorgang(LOCK_COMMAND);
+
+			verify(service).validateLockCommand(LOCK_COMMAND);
+		}
+
+		@Test
+		void shouldCallBuildLockPatch() {
+			service.lockVorgang(LOCK_COMMAND);
+
+			verify(service).buildLockPatch(LOCK_COMMAND);
+		}
+
+		@Test
+		void shouldCallRepository() {
+			service.lockVorgang(LOCK_COMMAND);
+
+			verify(repository).patch(VorgangTestFactory.ID, CommandTestFactory.RELATION_VERSION, LOCK_PATCH);
+		}
+
+		@Test
+		void shouldCallPublishEvent() {
+			service.lockVorgang(LOCK_COMMAND);
+
+			verify(publisher).publishEvent(eventCaptor.capture());
+			assertThat(eventCaptor.getValue().getCommand()).isSameAs(LOCK_COMMAND);
+		}
+	}
+
+	@Nested
+	class TestValidateLockCommand {
+
+		@Test
+		void shouldThrowExceptionOnMissingClient() {
+			var command = CommandTestFactory.createBuilder().createdByClient(null).build();
+
+			assertThrows(TechnicalException.class, () -> service.validateLockCommand(command));
+		}
+
+		@Test
+		void shouldThrowExceptionOnMissingReason() {
+			var command = CommandTestFactory.createBuilder().bodyObject(Map.of()).build();
+
+			assertThrows(TechnicalException.class, () -> service.validateLockCommand(command));
+		}
+
+		@Test
+		void shouldAcceptValidCommand() {
+			var command = CommandTestFactory.createBuilder().bodyObject(Map.of(Lock.FIELD_REASON, LockTestFactory.REASON)).build();
+
+			assertDoesNotThrow(() -> service.validateLockCommand(command));
+		}
+	}
+
+	@Nested
+	class TestBuildLockPatch {
+
+		@Test
+		void shouldSetClientName() {
+			var command = CommandTestFactory.createBuilder().bodyObject(Map.of(Lock.FIELD_REASON, LockTestFactory.REASON)).build();
+
+			var result = service.buildLockPatch(command);
+
+			assertThat(result).extractingByKey(VorgangService.KEY_HEADER_LOCK, MAP)
+					.containsEntry(Lock.FIELD_CLIENT_NAME, CommandTestFactory.CREATED_BY_CLIENT);
+		}
+
+		@Test
+		void shouldSetLockedSince() {
+			var command = CommandTestFactory.createBuilder().bodyObject(Map.of(Lock.FIELD_REASON, LockTestFactory.REASON)).build();
+
+			var result = service.buildLockPatch(command);
+
+			assertThat(result).extractingByKey(VorgangService.KEY_HEADER_LOCK, MAP)
+					.extractingByKey(Lock.FIELD_LOCKED_SINCE, InstanceOfAssertFactories.ZONED_DATE_TIME)
+					.isCloseTo(ZonedDateTime.now(), within(1, ChronoUnit.SECONDS));
+		}
+
+		@Test
+		void shouldSetReason() {
+			var command = CommandTestFactory.createBuilder().bodyObject(Map.of(Lock.FIELD_REASON, LockTestFactory.REASON)).build();
+
+			var result = service.buildLockPatch(command);
+
+			assertThat(result).extractingByKey(VorgangService.KEY_HEADER_LOCK, MAP).containsEntry(Lock.FIELD_REASON, LockTestFactory.REASON);
+		}
+	}
 }
\ No newline at end of file