diff --git a/Makefile b/Makefile
index b6a203169d6e3e44903d5178e4ce8e49a2354fa3..2229c2993727a3b08657dabeaa8b07093da5a1d0 100644
--- a/Makefile
+++ b/Makefile
@@ -102,7 +102,7 @@ test-backend: test-metadata-service test-analyse-service test-search-sync-agent
 test-search-sync-agent: build-search-sync-agent
 	mvn -f ./dbrepo-search-sync-agent/pom.xml clean test verify
 
-test-metadata-service: build-metadata-service
+test-metadata-service: build-metadata-service teardown
 	mvn -f ./dbrepo-metadata-service/pom.xml clean test verify
 
 test-analyse-service: build-analyse-service
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostCreationException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostCreationException.java
deleted file mode 100644
index bb3b2690dc7c1348cb33ac0f147d6be320aa7267..0000000000000000000000000000000000000000
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostCreationException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package at.tuwien.exception;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(code = HttpStatus.NOT_ACCEPTABLE)
-public class BrokerVirtualHostCreationException extends Exception {
-
-    public BrokerVirtualHostCreationException(String msg) {
-        super(msg);
-    }
-
-    public BrokerVirtualHostCreationException(String msg, Throwable thr) {
-        super(msg, thr);
-    }
-
-    public BrokerVirtualHostCreationException(Throwable thr) {
-        super(thr);
-    }
-}
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostModificationException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostModificationException.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9fda0c9d43ffc61ff5205c5f4eabf0ebadd32f0
--- /dev/null
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostModificationException.java
@@ -0,0 +1,20 @@
+package at.tuwien.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(code = HttpStatus.NOT_ACCEPTABLE)
+public class BrokerVirtualHostModificationException extends Exception {
+
+    public BrokerVirtualHostModificationException(String msg) {
+        super(msg);
+    }
+
+    public BrokerVirtualHostModificationException(String msg, Throwable thr) {
+        super(msg, thr);
+    }
+
+    public BrokerVirtualHostModificationException(Throwable thr) {
+        super(thr);
+    }
+}
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
index 2bad13e644869b64b0a24eee67b2abaee7732c0f..c114506501c05e943bb78298dd0a93d0e72d2533 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
@@ -2,7 +2,6 @@ package at.tuwien.endpoints;
 
 import at.tuwien.api.database.*;
 import at.tuwien.api.error.ApiErrorDto;
-import at.tuwien.api.user.UserDto;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.DatabaseAccess;
 import at.tuwien.entities.user.User;
@@ -140,7 +139,7 @@ public class DatabaseEndpoint {
             throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException,
             AmqpException, ContainerConnectionException, UserNotFoundException,
             DatabaseNotFoundException, DatabaseNameExistsException, DatabaseConnectionException,
-            QueryMalformedException, NotAllowedException, BrokerVirtualHostCreationException, QueryStoreException,
+            QueryMalformedException, NotAllowedException, BrokerVirtualHostModificationException, QueryStoreException,
             BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
         log.debug("endpoint create database, createDto={}, principal={}", createDto,
                 principal);
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
index ecd68ec53e613be9739ebbf80b20958aafb4cf28..e2c6b94814aa6eed26b282fd5c8e8d45281322d6 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
@@ -6,6 +6,7 @@ import at.tuwien.api.user.*;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.mapper.UserMapper;
+import at.tuwien.service.AuthenticationService;
 import at.tuwien.service.DatabaseService;
 import at.tuwien.service.MessageQueueService;
 import at.tuwien.service.UserService;
@@ -42,15 +43,16 @@ public class UserEndpoint {
     private final UserService userService;
     private final DatabaseService databaseService;
     private final MessageQueueService messageQueueService;
-
+    private final AuthenticationService authenticationService;
 
     @Autowired
     public UserEndpoint(UserMapper userMapper, UserService userService, DatabaseService databaseService,
-                        MessageQueueService messageQueueService) {
+                        MessageQueueService messageQueueService, AuthenticationService authenticationService) {
         this.userMapper = userMapper;
         this.userService = userService;
         this.databaseService = databaseService;
         this.messageQueueService = messageQueueService;
+        this.authenticationService = authenticationService;
     }
 
     @GetMapping
@@ -106,14 +108,34 @@ public class UserEndpoint {
     })
     public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody SignupRequestDto data)
             throws UserAlreadyExistsException, UserEmailAlreadyExistsException, UserNotFoundException,
-            KeycloakRemoteException, AccessDeniedException, BrokerRemoteException, BrokerVirtualHostCreationException {
+            KeycloakRemoteException, AccessDeniedException, BrokerRemoteException,
+            BrokerVirtualHostModificationException {
         log.debug("endpoint create a user, data={}", data);
         /* check */
         userService.validateUsernameNotExists(data.getUsername());
         userService.validateEmailNotExists(data.getEmail());
         /* create */
-        final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data));
-        messageQueueService.createUser(dto.getUsername());
+        authenticationService.create(data);
+        final at.tuwien.api.keycloak.UserDto keycloakUserDto = authenticationService.findByUsername(data.getUsername());
+        try {
+            messageQueueService.createUser(data.getUsername());
+        } catch (BrokerRemoteException e) {
+            try {
+                authenticationService.delete(keycloakUserDto.getId());
+            } catch (UserNotFoundException e2) {
+                /* ignore */
+            }
+            throw new BrokerRemoteException(e);
+        } catch (BrokerVirtualHostModificationException e) {
+            try {
+                authenticationService.delete(keycloakUserDto.getId());
+            } catch (UserNotFoundException e2) {
+                /* ignore */
+            }
+            throw new BrokerVirtualHostModificationException(e);
+        }
+        final User user = userService.create(data, keycloakUserDto.getId());
+        final UserBriefDto dto = userMapper.userToUserBriefDto(user);
         log.trace("create user resulted in dto {}", dto);
         return ResponseEntity.status(HttpStatus.CREATED)
                 .body(dto);
@@ -278,6 +300,7 @@ public class UserEndpoint {
         }
         /* modify password */
         userService.updatePassword(id, data);
+        authenticationService.updatePassword(id, data);
         return ResponseEntity.accepted()
                 .build();
     }
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java
index 27663c461e14d4eca46a24f1a9476d8f9d4bffc1..0e10da264304a879b6dcf72b2716e16b4fbaba09 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java
@@ -245,8 +245,8 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
 
     @Hidden
     @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
-    @ExceptionHandler(BrokerVirtualHostCreationException.class)
-    public ResponseEntity<ApiErrorDto> handle(BrokerVirtualHostCreationException e, WebRequest request) {
+    @ExceptionHandler(BrokerVirtualHostModificationException.class)
+    public ResponseEntity<ApiErrorDto> handle(BrokerVirtualHostModificationException e, WebRequest request) {
         final ApiErrorDto response = ApiErrorDto.builder()
                 .status(HttpStatus.NOT_ACCEPTABLE)
                 .message(e.getLocalizedMessage())
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java
index 42e1d3b2bc700df0962a5864c5d6aac99c1a8c3a..1d61a1108d8ceba8c2eaabaee35a6f1efcfd98d3 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java
@@ -32,7 +32,7 @@ public class MariaDbContainerConfig {
         private boolean started = false;
 
         public static synchronized CustomMariaDBContainer getInstance() {
-            if(instance == null) {
+            if (instance == null) {
                 instance = new CustomMariaDBContainer(BaseTest.IMAGE_1_NAME + ":" + BaseTest.IMAGE_1_VERSION);
                 instance.withImagePullPolicy(PullPolicy.alwaysPull());
                 instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT);
@@ -56,7 +56,8 @@ public class MariaDbContainerConfig {
 
         @Override
         public synchronized void start() {
-            if(!started) {
+            if (!started) {
+                super.stop();
                 super.start();
                 started = true;
             }
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java
index 66aa04b7fbb20344d4cc1d25cd0108814ff062e6..c13d6ed419a8a72ec078fb0c8da92a32a77ed620 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java
@@ -4,7 +4,6 @@ import at.tuwien.BaseUnitTest;
 import at.tuwien.annotations.MockAmqp;
 import at.tuwien.annotations.MockOpensearch;
 import at.tuwien.api.database.*;
-import at.tuwien.api.user.UserDto;
 import at.tuwien.entities.container.Container;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.DatabaseAccess;
@@ -116,7 +115,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest {
     public void create_succeeds() throws UserNotFoundException, BrokerVirtualHostGrantException,
             DatabaseNameExistsException, NotAllowedException, ContainerConnectionException, DatabaseMalformedException,
             QueryStoreException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException,
-            ImageNotSupportedException, AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException,
+            ImageNotSupportedException, AmqpException, BrokerVirtualHostModificationException, ContainerNotFoundException,
             KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
         final DatabaseCreateDto request = DatabaseCreateDto.builder()
                 .cid(CONTAINER_1_ID)
@@ -429,7 +428,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest {
                                Principal principal) throws UserNotFoundException, DatabaseNameExistsException,
             NotAllowedException, ContainerConnectionException, DatabaseMalformedException, QueryStoreException,
             DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
-            AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException,
+            AmqpException, BrokerVirtualHostModificationException, ContainerNotFoundException,
             BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
 
         /* mock */
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java
index 030f8e3c446fd9bd02aa1cc604803c651bc9207f..a7ed7c0c77bf08bceb36bf6f59b0e49a69212e2f 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java
@@ -7,6 +7,7 @@ import at.tuwien.api.auth.SignupRequestDto;
 import at.tuwien.api.user.*;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
+import at.tuwien.service.AuthenticationService;
 import at.tuwien.service.MessageQueueService;
 import at.tuwien.service.UserService;
 import lombok.extern.log4j.Log4j2;
@@ -44,6 +45,9 @@ public class UserEndpointUnitTest extends BaseUnitTest {
     @MockBean
     private MessageQueueService messageQueueService;
 
+    @MockBean
+    private AuthenticationService authenticationService;
+
     @Autowired
     private UserEndpoint userEndpoint;
 
@@ -66,8 +70,8 @@ public class UserEndpointUnitTest extends BaseUnitTest {
     @Test
     @WithAnonymousUser
     public void create_anonymous_succeeds() throws UserNotFoundException, UserEmailAlreadyExistsException,
-            RealmNotFoundException, UserAlreadyExistsException, KeycloakRemoteException,
-            at.tuwien.exception.AccessDeniedException, BrokerRemoteException, BrokerVirtualHostCreationException {
+            UserAlreadyExistsException, KeycloakRemoteException,
+            at.tuwien.exception.AccessDeniedException, BrokerRemoteException, BrokerVirtualHostModificationException {
         final SignupRequestDto request = SignupRequestDto.builder()
                 .email(USER_1_EMAIL)
                 .username(USER_1_USERNAME)
@@ -75,7 +79,7 @@ public class UserEndpointUnitTest extends BaseUnitTest {
                 .build();
 
         /* test */
-        create_generic(request, USER_1);
+        create_generic(request, USER_1, USER_1_KEYCLOAK_DTO, USER_1_ID);
     }
 
     @Test
@@ -89,7 +93,7 @@ public class UserEndpointUnitTest extends BaseUnitTest {
 
         /* test */
         assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> {
-            create_generic(request, null);
+            create_generic(request, null, null, null);
         });
     }
 
@@ -302,16 +306,22 @@ public class UserEndpointUnitTest extends BaseUnitTest {
         assertEquals(2, body.size());
     }
 
-    protected void create_generic(SignupRequestDto data, User user) throws UserEmailAlreadyExistsException,
-            RealmNotFoundException, UserAlreadyExistsException, UserNotFoundException, KeycloakRemoteException,
-            AccessDeniedException, BrokerRemoteException, BrokerVirtualHostCreationException {
+    protected void create_generic(SignupRequestDto data, User user, at.tuwien.api.keycloak.UserDto userDto, UUID id)
+            throws UserEmailAlreadyExistsException, UserAlreadyExistsException, UserNotFoundException,
+            KeycloakRemoteException, AccessDeniedException, BrokerRemoteException,
+            BrokerVirtualHostModificationException {
 
         /* mock */
-        when(userService.create(data))
+        when(userService.create(data, id))
                 .thenReturn(user);
         doNothing()
                 .when(messageQueueService)
                 .createUser(anyString());
+        when(authenticationService.findByUsername(data.getUsername()))
+                .thenReturn(userDto);
+        doNothing()
+                .when(authenticationService)
+                .create(any(SignupRequestDto.class));
 
         /* test */
         final ResponseEntity<UserBriefDto> response = userEndpoint.create(data);
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java
index 567e9cbbc7d3fb9b1b4f953d8f57352cad636e9b..7e1fd0accb8827f49ba149a62e8d653467c14be8 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java
@@ -4,7 +4,7 @@ import at.tuwien.BaseUnitTest;
 import at.tuwien.annotations.MockAmqp;
 import at.tuwien.annotations.MockOpensearch;
 import at.tuwien.exception.BrokerRemoteException;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.Test;
@@ -38,7 +38,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
     private BrokerServiceGateway brokerServiceGateway;
 
     @Test
-    public void createVirtualHost_succeeds() throws BrokerVirtualHostCreationException, BrokerRemoteException {
+    public void createVirtualHost_succeeds() throws BrokerVirtualHostModificationException, BrokerRemoteException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.CREATED)
                 .build();
 
@@ -60,7 +60,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
                 .thenReturn(mock);
 
         /* test */
-        assertThrows(BrokerVirtualHostCreationException.class, () -> {
+        assertThrows(BrokerVirtualHostModificationException.class, () -> {
             brokerServiceGateway.createVirtualHost(VIRTUAL_HOST_CREATE_DTO);
         });
     }
@@ -148,7 +148,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
     }
 
     @Test
-    public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostCreationException {
+    public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostModificationException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.NO_CONTENT)
                 .build();
 
@@ -170,7 +170,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
                 .thenReturn(mock);
 
         /* test */
-        assertThrows(BrokerVirtualHostCreationException.class, () -> {
+        assertThrows(BrokerVirtualHostModificationException.class, () -> {
             brokerServiceGateway.createUser(USER_1_USERNAME);
         });
     }
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f4240a8647e00668c77220a93b155622e4c6fa8
--- /dev/null
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java
@@ -0,0 +1,87 @@
+package at.tuwien.service;
+
+import at.tuwien.BaseUnitTest;
+import at.tuwien.annotations.MockAmqp;
+import at.tuwien.annotations.MockOpensearch;
+import at.tuwien.entities.user.User;
+import at.tuwien.exception.*;
+import at.tuwien.gateway.KeycloakGateway;
+import dasniko.testcontainers.keycloak.KeycloakContainer;
+import lombok.extern.log4j.Log4j2;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.testcontainers.images.PullPolicy;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@Log4j2
+@Testcontainers
+@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
+@SpringBootTest
+@ExtendWith(SpringExtension.class)
+@MockAmqp
+@MockOpensearch
+public class AuthenticationServiceIntegrationTest extends BaseUnitTest {
+
+    @Autowired
+    private AuthenticationService authenticationService;
+
+    @Autowired
+    private KeycloakGateway keycloakGateway;
+
+    @Container
+    private static KeycloakContainer keycloakContainer = new KeycloakContainer("quay.io/keycloak/keycloak:21.0")
+            .withImagePullPolicy(PullPolicy.alwaysPull())
+            .withAdminUsername("fda")
+            .withAdminPassword("fda")
+            .withRealmImportFile("./dbrepo-realm.json")
+            .withEnv("KC_HOSTNAME_STRICT_HTTPS", "false");
+
+    @DynamicPropertySource
+    static void keycloakProperties(DynamicPropertyRegistry registry) {
+        registry.add("fda.keycloak.endpoint", () -> "http://localhost:" + keycloakContainer.getMappedPort(8080));
+    }
+
+    @Test
+    public void delete_succeeds() throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException,
+            UserEmailAlreadyExistsException, UserAlreadyExistsException {
+
+        /* mock */
+        try {
+            keycloakGateway.deleteUser(keycloakGateway.findByUsername(USER_1_USERNAME).getId());
+        } catch (Exception e) {
+            /* ignore */
+        }
+        keycloakGateway.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST);
+
+        /* test */
+        authenticationService.delete(keycloakGateway.findByUsername(USER_1_USERNAME).getId());
+    }
+
+    @Test
+    public void create_succeeds() throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException,
+            UserEmailAlreadyExistsException, UserAlreadyExistsException {
+
+        /* mock */
+        try {
+            keycloakGateway.deleteUser(keycloakGateway.findByUsername(USER_1_USERNAME).getId());
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        authenticationService.create(USER_1_SIGNUP_REQUEST_DTO);
+    }
+
+}
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java
index 7c0c8c5b5cafa57a37a87ffa2b498dbeb6093bf5..8e9c2cb7b9609238afdbf9dd0c05b2a301c0d050 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java
@@ -5,7 +5,7 @@ import at.tuwien.annotations.MockOpensearch;
 import at.tuwien.api.amqp.PermissionDto;
 import at.tuwien.exception.AmqpException;
 import at.tuwien.exception.BrokerRemoteException;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import at.tuwien.repository.mdb.DatabaseRepository;
 import at.tuwien.repository.mdb.TableRepository;
@@ -86,7 +86,7 @@ public class MessageQueueServiceIntegrationTest extends BaseUnitTest {
     }
 
     @Test
-    public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostCreationException {
+    public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostModificationException {
 
         /* test */
         messageQueueService.createUser(USER_1_USERNAME);
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java
index 5628f041c988611bb0cdf0a2bda9f3cb16dfe68f..07fa1e92b65492df0e267077430297d6f82f77ab 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java
@@ -23,6 +23,8 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.testcontainers.containers.MariaDBContainer;
 import org.testcontainers.junit.jupiter.Container;
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java
index ad229d6aa39d0d6eb4e6d9c8bf8515f8dd2f571d..ba29bea0102b62422c9f725799cf6ec00f21999c 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java
@@ -8,7 +8,6 @@ import at.tuwien.api.user.*;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.repository.mdb.UserRepository;
-import dasniko.testcontainers.keycloak.KeycloakContainer;
 import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -18,12 +17,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.transaction.annotation.Transactional;
-import org.testcontainers.images.PullPolicy;
-import org.testcontainers.junit.jupiter.Container;
 import org.testcontainers.junit.jupiter.Testcontainers;
 
 import java.util.List;
@@ -46,19 +41,6 @@ public class UserServiceIntegrationTest extends BaseUnitTest {
     @Autowired
     private UserService userService;
 
-    @Container
-    private static KeycloakContainer keycloakContainer = new KeycloakContainer("quay.io/keycloak/keycloak:21.0")
-            .withImagePullPolicy(PullPolicy.alwaysPull())
-            .withAdminUsername("fda")
-            .withAdminPassword("fda")
-            .withRealmImportFile("./dbrepo-realm.json")
-            .withEnv("KC_HOSTNAME_STRICT_HTTPS", "false");
-
-    @DynamicPropertySource
-    static void elasticsearchProperties(DynamicPropertyRegistry registry) {
-        registry.add("fda.keycloak.endpoint", () -> "http://localhost:" + keycloakContainer.getMappedPort(8080));
-    }
-
     @BeforeEach
     public void beforeEach() {
         userRepository.save(USER_1);
@@ -100,38 +82,10 @@ public class UserServiceIntegrationTest extends BaseUnitTest {
                 .build();
 
         /* test */
-        final User response = userService.create(request);
+        final User response = userService.create(request, USER_2_ID);
         assertEquals(USER_2_USERNAME, response.getUsername());
     }
 
-    @Test
-    public void create_nonUniqueUsername_fails() {
-        final SignupRequestDto request = SignupRequestDto.builder()
-                .username(USER_1_USERNAME)
-                .password(USER_2_PASSWORD)
-                .email(USER_2_EMAIL)
-                .build();
-
-        /* test */
-        assertThrows(UserEmailAlreadyExistsException.class, () -> {
-            userService.create(request);
-        });
-    }
-
-    @Test
-    public void create_nonUniqueEmail_fails() {
-        final SignupRequestDto request = SignupRequestDto.builder()
-                .username(USER_2_USERNAME)
-                .password(USER_2_PASSWORD)
-                .email(USER_1_EMAIL)
-                .build();
-
-        /* test */
-        assertThrows(UserAlreadyExistsException.class, () -> {
-            userService.create(request);
-        });
-    }
-
     @Test
     @Transactional
     public void modify_succeeds() throws UserNotFoundException {
@@ -178,7 +132,7 @@ public class UserServiceIntegrationTest extends BaseUnitTest {
                 .username(USER_3_USERNAME)
                 .password(USER_3_PASSWORD)
                 .email(USER_3_EMAIL)
-                .build());
+                .build(), USER_3_ID);
 
         /* test */
         userService.updatePassword(user.getId(), request);
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java
index 35fc49b369dd59cff21217a05d54bcf8a07f7096..c5660860ded2c91c65ff500e3a912c1b7d588724 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java
@@ -92,7 +92,7 @@ public class UserServiceUnitTest extends BaseUnitTest {
                 .thenReturn(USER_1_KEYCLOAK_DTO);
 
         /* test */
-        final User response = userService.create(USER_1_SIGNUP_REQUEST_DTO);
+        final User response = userService.create(USER_1_SIGNUP_REQUEST_DTO, USER_1_ID);
         assertEquals(USER_1_ID, response.getId());
         assertEquals(USER_1_USERNAME, response.getUsername());
     }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java
index 0484e1c29a30970f2a003b485c33a34ece164bb5..7e55074f7e1197aaa1e60c1e83ee31e8e5905531 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java
@@ -5,7 +5,7 @@ import at.tuwien.api.amqp.CreateVirtualHostDto;
 import at.tuwien.api.amqp.GrantVirtualHostPermissionsDto;
 import at.tuwien.api.user.ExchangeUpdatePermissionsDto;
 import at.tuwien.exception.BrokerRemoteException;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 
 import java.util.List;
@@ -24,10 +24,10 @@ public interface BrokerServiceGateway {
      * Create virtual host at the queue service.
      *
      * @param data The virtual host.
-     * @throws BrokerVirtualHostCreationException The virtual host could not be created.
-     * @throws BrokerRemoteException              The Broker Service did not respond within the 3s timeout.
+     * @throws BrokerVirtualHostModificationException The virtual host could not be created.
+     * @throws BrokerRemoteException                  The Broker Service did not respond within the 3s timeout.
      */
-    void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostCreationException, BrokerRemoteException;
+    void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostModificationException, BrokerRemoteException;
 
     /**
      * Grants a user permission at a virtual host in the queue service.
@@ -40,13 +40,22 @@ public interface BrokerServiceGateway {
     void grantPermission(String username, ExchangeUpdatePermissionsDto data) throws BrokerVirtualHostGrantException, BrokerRemoteException;
 
     /**
-     * Create user on the broker service
+     * Create user on the broker service with given username.
      *
-     * @param username The new username.
-     * @throws BrokerRemoteException              The Broker Service did not respond within the 3s timeout.
-     * @throws BrokerVirtualHostCreationException The user could not be created.
+     * @param username The username.
+     * @throws BrokerRemoteException                  The Broker Service did not respond within the 3s timeout.
+     * @throws BrokerVirtualHostModificationException The user could not be created.
      */
-    void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException;
+    void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException;
+
+    /**
+     * Deletes a user on the broker service with given username.
+     *
+     * @param username The username.
+     * @throws BrokerRemoteException                  The Broker Service did not respond within the 3s timeout.
+     * @throws BrokerVirtualHostModificationException The user could not be deleted.
+     */
+    void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException;
 
     /**
      * Grants a user permission at a virtual host in the queue service.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java
index 17e779f918ac5788262e7bb58cc7cd6b27a6acb3..3614e43fcbbbc21c8f9808974355b97b0d6750a4 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java
@@ -20,6 +20,16 @@ public interface KeycloakGateway {
      */
     void createUser(UserCreateDto data) throws AccessDeniedException, KeycloakRemoteException, UserAlreadyExistsException, UserEmailAlreadyExistsException;
 
+    /**
+     * Deletes a user at the Authentication Service with given user id.
+     *
+     * @param id The user id.
+     * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout.
+     * @throws AccessDeniedException   The admin token could not be obtained.
+     * @throws UserNotFoundException   The user was not found at the Authentication Service.
+     */
+    void deleteUser(UUID id) throws KeycloakRemoteException, AccessDeniedException, UserNotFoundException;
+
     /**
      * Update the credentials for a given user.
      *
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java
index 23ab2985a1db6482a7c37fa1f07431d0ca13fa52..a13de9f29ccc761a16aaa4dd5cf18ab11283acf1 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java
@@ -5,21 +5,16 @@ import at.tuwien.api.amqp.CreateUserDto;
 import at.tuwien.api.amqp.CreateVirtualHostDto;
 import at.tuwien.api.amqp.GrantVirtualHostPermissionsDto;
 import at.tuwien.api.user.ExchangeUpdatePermissionsDto;
-import at.tuwien.config.AmqpConfig;
 import at.tuwien.config.GatewayConfig;
 import at.tuwien.exception.BrokerRemoteException;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
-import at.tuwien.exception.KeycloakRemoteException;
 import at.tuwien.gateway.BrokerServiceGateway;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.codec.binary.Base64;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.core.env.Environment;
 import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -27,8 +22,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
 import java.net.URI;
-import java.nio.charset.Charset;
-import java.util.Arrays;
 import java.util.List;
 
 @Slf4j
@@ -48,7 +41,7 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway {
     }
 
     @Override
-    public void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostCreationException, BrokerRemoteException {
+    public void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostModificationException, BrokerRemoteException {
         final String url = "/api/vhost";
         log.trace("POST {}{}", gatewayConfig.getBrokerEndpoint(), url);
         final ResponseEntity<Void> response;
@@ -60,7 +53,7 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway {
         }
         if (!response.getStatusCode().equals(HttpStatus.CREATED)) {
             log.error("Failed to create virtual host: {}", response.getStatusCode());
-            throw new BrokerVirtualHostCreationException("Failed to create virtual host");
+            throw new BrokerVirtualHostModificationException("Failed to create virtual host");
         }
         log.info("Create virtual host with name {}", data.getName());
     }
@@ -85,7 +78,7 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway {
     }
 
     @Override
-    public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException {
+    public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException {
         final CreateUserDto data = CreateUserDto.builder()
                 .passwordHash("")
                 .tags("")
@@ -101,11 +94,29 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway {
         }
         if (!response.getStatusCode().equals(HttpStatus.CREATED) && !response.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
             log.error("Failed to create user: {}", response.getStatusCode());
-            throw new BrokerVirtualHostCreationException("Failed to create user");
+            throw new BrokerVirtualHostModificationException("Failed to create user");
         }
         log.info("Created user with username {}", username);
     }
 
+    @Override
+    public void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException {
+        final String url = "/api/users/" + username;
+        log.trace("DELETE {}{}", gatewayConfig.getBrokerEndpoint(), url);
+        final ResponseEntity<Void> response;
+        try {
+            response = restTemplate.exchange(url, HttpMethod.DELETE, new HttpEntity<>(null), Void.class);
+        } catch (Exception e) {
+            log.error("Failed to delete user: remote host answered unexpected: {}", e.getMessage());
+            throw new BrokerRemoteException("Failed to delete user: remote host answered unexpected", e);
+        }
+        if (!response.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
+            log.error("Failed to delete user: {}", response.getStatusCode());
+            throw new BrokerVirtualHostModificationException("Failed to create user");
+        }
+        log.info("Deleted user with username {}", username);
+    }
+
     @Override
     public void grantPermission(String username, GrantVirtualHostPermissionsDto data) throws BrokerRemoteException,
             BrokerVirtualHostGrantException {
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java
index d887fd8eb27c918dfb7c2889885fe689d84263bd..6f29d138ffb858c526e1e18b0f76c0d27cb5d99c 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java
@@ -87,6 +87,35 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
             log.error("Failed to create user: status {} was not expected", response.getStatusCode().value());
             throw new KeycloakRemoteException("Failed to create user: status " + response.getStatusCode().value() + "was not expected");
         }
+        log.info("Created user {} at authentication service", data.getUsername());
+    }
+
+    @Override
+    public void deleteUser(UUID id) throws KeycloakRemoteException, AccessDeniedException, UserNotFoundException {
+        /* obtain admin token */
+        final HttpHeaders headers = new HttpHeaders();
+        headers.set("Accept", "application/json");
+        headers.set("Authorization", "Bearer " + obtainToken().getAccessToken());
+        final String url = keycloakConfig.getKeycloakEndpoint() + "/admin/realms/dbrepo/users/" + id;
+        log.debug("delete user at url {}", url);
+        final ResponseEntity<Void> response;
+        try {
+            response = restTemplate.exchange(url, HttpMethod.DELETE, new HttpEntity<>(null, headers), Void.class);
+        } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) {
+            log.error("Failed to delete user: {}", e.getMessage());
+            throw new KeycloakRemoteException("Failed to delete user: " + e.getMessage());
+        } catch (HttpClientErrorException.NotFound e) {
+            log.error("User does not exist: {}", e.getMessage());
+            throw new UserNotFoundException("User does not exist: " + e.getMessage());
+        } catch (Exception e) {
+            log.error("Failed to delete user: remote host answered unexpected: {}", e.getMessage());
+            throw new KeycloakRemoteException("Failed to delete user: remote host answered unexpected", e);
+        }
+        if (!response.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
+            log.error("Failed to delete user: status {} was not expected", response.getStatusCode().value());
+            throw new KeycloakRemoteException("Failed to delete user: status " + response.getStatusCode().value() + "was not expected");
+        }
+        log.info("Deleted user {} at authentication service", id);
     }
 
     @Override
@@ -113,6 +142,7 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
             log.error("Failed to update user credentials: status {} was not expected", response.getStatusCode().value());
             throw new KeycloakRemoteException("Failed to update user credentials: status " + response.getStatusCode().value() + "was not expected");
         }
+        log.info("Updated user {} password at authentication service", id);
     }
 
     @Override
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java
new file mode 100644
index 0000000000000000000000000000000000000000..a39e0d66c20348a35d5d2fcafbbd7ab1a364fd85
--- /dev/null
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java
@@ -0,0 +1,47 @@
+package at.tuwien.service;
+
+import at.tuwien.api.auth.SignupRequestDto;
+import at.tuwien.api.keycloak.UserDto;
+import at.tuwien.api.user.UserPasswordDto;
+import at.tuwien.exception.*;
+
+import java.util.UUID;
+
+public interface AuthenticationService {
+
+    /**
+     * Create a user at the Authentication Service with given credentials.
+     *
+     * @param data The credentials.
+     * @throws AccessDeniedException           The admin token could not be obtained.
+     * @throws KeycloakRemoteException         The Authentication Service was not able to respond within the 3s timeout.
+     * @throws UserAlreadyExistsException      The user already exists at the Authentication Service.
+     * @throws UserEmailAlreadyExistsException The user email already exists in the metadata database.
+     */
+    void create(SignupRequestDto data) throws KeycloakRemoteException, AccessDeniedException,
+            UserEmailAlreadyExistsException, UserAlreadyExistsException;
+
+    /**
+     * Deletes a user at the Authentication Service with given user id.
+     *
+     * @param userId The user id.
+     * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout.
+     * @throws AccessDeniedException   The admin token could not be obtained.
+     * @throws UserNotFoundException   The user was not found at the Authentication Service.
+     */
+    void delete(UUID userId) throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException;
+
+    /**
+     * Finds a user with given username.
+     *
+     * @param username The username.
+     * @return The user, if successful.
+     * @throws UserNotFoundException   The user was not found at the Authentication Service.
+     * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout.
+     * @throws AccessDeniedException   The admin token could not be obtained.
+     */
+    UserDto findByUsername(String username) throws UserNotFoundException, KeycloakRemoteException,
+            AccessDeniedException;
+
+    void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException;
+}
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java
index 50fe5233773cff80774be54bb3c09f7ceb68ef74..3d21c91a521e6e581f1ac7886f5d98bd44fdfc82 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java
@@ -1,12 +1,11 @@
 package at.tuwien.service;
 
-import at.tuwien.api.user.UserDto;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.table.Table;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.AmqpException;
 import at.tuwien.exception.BrokerRemoteException;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import jakarta.annotation.PostConstruct;
 
@@ -44,13 +43,22 @@ public interface MessageQueueService {
     void create(Table table) throws AmqpException;
 
     /**
-     * Create user on the broker service
+     * Create user on the broker service with given username.
      *
      * @param username The username.
-     * @throws BrokerRemoteException The user could not be created.
+     * @throws BrokerRemoteException                  The user could not be created.
+     * @throws BrokerVirtualHostModificationException The Broker Service did not respond within the 3s timeout.
      */
-    void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException;
+    void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException;
 
+    /**
+     * Delete a user on the broker service with given username.
+     *
+     * @param username The username.
+     * @throws BrokerRemoteException                  The user could not be deleted.
+     * @throws BrokerVirtualHostModificationException The Broker Service did not respond within the 3s timeout.
+     */
+    void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException;
 
     /**
      * Updates the virtual host permissions in the Broker Service for a user with given principal.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
index 3b94ad5d903eb52a0d17a5c869c2af897f205a3f..a5edcc519c9643afc2915217eaebd14df20550ac 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
@@ -42,7 +42,7 @@ public interface UserService {
      * @return The user, if successful. False otherwise.
      * @throws UserAlreadyExistsException The user already exists in the metadata database.
      */
-    User create(SignupRequestDto data) throws UserAlreadyExistsException, AccessDeniedException,
+    User create(SignupRequestDto data, UUID id) throws UserAlreadyExistsException, AccessDeniedException,
             KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException;
 
     /**
@@ -61,7 +61,7 @@ public interface UserService {
      * @param id   The user id.
      * @param data The new password.
      */
-    void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException, UserNotFoundException;
+    void updatePassword(UUID id, UserPasswordDto data) throws UserNotFoundException;
 
     /**
      * Updates the user theme for a user with given id.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a8a6c7fb3e9a195c83fe60c512e2af2ba69a413
--- /dev/null
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java
@@ -0,0 +1,51 @@
+package at.tuwien.service.impl;
+
+import at.tuwien.api.auth.SignupRequestDto;
+import at.tuwien.api.keycloak.UserDto;
+import at.tuwien.api.user.UserPasswordDto;
+import at.tuwien.exception.*;
+import at.tuwien.gateway.KeycloakGateway;
+import at.tuwien.mapper.UserMapper;
+import at.tuwien.service.AuthenticationService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.UUID;
+
+@Log4j2
+@Service
+public class AuthenticationServiceImpl implements AuthenticationService {
+
+    private final UserMapper userMapper;
+    private final KeycloakGateway keycloakGateway;
+
+    @Autowired
+    public AuthenticationServiceImpl(UserMapper userMapper, KeycloakGateway keycloakGateway) {
+        this.userMapper = userMapper;
+        this.keycloakGateway = keycloakGateway;
+    }
+
+    @Override
+    public void create(SignupRequestDto data) throws KeycloakRemoteException, AccessDeniedException,
+            UserEmailAlreadyExistsException, UserAlreadyExistsException {
+        keycloakGateway.createUser(userMapper.signupRequestDtoToUserCreateDto(data));
+    }
+
+    @Override
+    public void delete(UUID userId) throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException {
+        keycloakGateway.deleteUser(userId);
+    }
+
+    @Override
+    public UserDto findByUsername(String username) throws UserNotFoundException, KeycloakRemoteException,
+            AccessDeniedException {
+        return keycloakGateway.findByUsername(username);
+    }
+
+    @Override
+    public void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException {
+        keycloakGateway.updateUserCredentials(id, data);
+    }
+
+}
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java
index 56c102131aa3a79b72f8b9c18f9f233902bac584..3c7758a8f715ad2d76130108a52b1f36d972ae59 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java
@@ -9,7 +9,7 @@ import at.tuwien.entities.database.table.Table;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.AmqpException;
 import at.tuwien.exception.BrokerRemoteException;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import at.tuwien.gateway.BrokerServiceGateway;
 import at.tuwien.mapper.AmqpMapper;
@@ -104,10 +104,15 @@ public class RabbitMqServiceImpl implements MessageQueueService {
     }
 
     @Override
-    public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException {
+    public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException {
         brokerServiceGateway.createUser(username);
     }
 
+    @Override
+    public void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException {
+        brokerServiceGateway.deleteUser(username);
+    }
+
     @Override
     public void updatePermissions(User user) throws BrokerRemoteException, BrokerVirtualHostGrantException {
         final GrantVirtualHostPermissionsDto permissions = GrantVirtualHostPermissionsDto.builder()
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
index d6862071b92172c548cbecf2650bb5b663ade17c..1baf6ff415e5c5b47c81974bd9d42a2588300a48 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
@@ -63,18 +63,17 @@ public class UserServiceImpl implements UserService {
     }
 
     @Override
-    public User create(SignupRequestDto data) throws UserAlreadyExistsException, AccessDeniedException,
+    public User create(SignupRequestDto data, UUID id) throws UserAlreadyExistsException, AccessDeniedException,
             KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException {
         /* create at authentication service */
         final User entity = User.builder()
+                .id(id)
                 .username(data.getUsername())
                 .email(data.getEmail())
                 .themeDark(false)
                 .mariadbPassword(getMariaDbPassword(data.getPassword()))
                 .build();
-        keycloakGateway.createUser(userMapper.signupRequestDtoToUserCreateDto(data));
         /* create at metadata database */
-        entity.setId(keycloakGateway.findByUsername(data.getUsername()).getId());
         final User user = userRepository.save(entity);
         log.info("Created user with id {} in metadata database", user.getId());
         /* save in open search database */
@@ -96,14 +95,10 @@ public class UserServiceImpl implements UserService {
     }
 
     @Override
-    public void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException,
-            UserNotFoundException {
+    public void updatePassword(UUID id, UserPasswordDto data) throws UserNotFoundException {
         final User user = find(id);
         user.setMariadbPassword(getMariaDbPassword(data.getPassword()));
         userRepository.save(user);
-        log.debug("updated password in metadata database");
-        keycloakGateway.updateUserCredentials(id, data);
-        log.debug("updated password in keycloak");
         log.info("Updated user password with id {}", id);
     }
 
diff --git a/docker-compose.yml b/docker-compose.yml
index 6d7771334b20b2b65c99ddda0a19c6ea35385536..c6e753c4d44122f8cfd38b3f17f28b76454288cb 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -157,7 +157,7 @@ services:
       BASE_URL: "${BASE_URL:-http://localhost}"
       GRANT_PRIVILEGES: "${GRANT_PRIVILEGES:-SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE}"
       BROKER_CONSUMERS: "${BROKER_CONSUMERS:-2}"
-      BROKER_ENDPOINT: "${BROKER_ENDPOINT:-http://broker-service:15672}"
+      BROKER_ENDPOINT: "${BROKER_ENDPOINT:-http://broker-service:15672/admin/broker}"
       BROKER_USERNAME: "${BROKER_USERNAME:-fda}"
       BROKER_PASSWORD: "${BROKER_PASSWORD:-fda}"
       DELETED_RECORD: "${DELETED_RECORD:-persistent}"