diff --git a/.env.unix.example b/.env.unix.example
index b0ad6ff0532fd9d5d74c99b95cee0ea66122cfcd..54986336db71fa576456e6638245f6a36574a34b 100644
--- a/.env.unix.example
+++ b/.env.unix.example
@@ -12,6 +12,7 @@ METADATA_PASSWORD=dbrepo
 AUTH_DB=keycloak
 AUTH_USERNAME=root
 AUTH_PASSWORD=dbrepo
+BROKER_ENDPOINT=http://broker-service:15672/admin/broker
 BROKER_USERNAME=fda
 BROKER_PASSWORD=fda
 KEYCLOAK_ADMIN=fda
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index dc68ed7dbc884ebfa1215fc3fdb9207790d1b1f5..60880514a97c759997bf1023a715a8b157498544 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -124,20 +124,26 @@ test-frontend:
 
 test-default-deployment:
   stage: test-deployment
+  timeout: 5m
   needs:
     - test-frontend
   script:
+    - "make teardown"
     - "rm -f .env"
-    - "docker compose up -d || docker compose down"
+    - "docker compose up -d && make teardown"
+    - "make teardown"
   coverage: '/TOTAL.*?([0-9]{1,3})%/'
 
 test-env-deployment:
   stage: test-deployment
+  timeout: 5m
   needs:
     - test-frontend
   script:
+    - "make teardown"
     - "cp .env.unix.example .env"
-    - "docker compose up -d || docker compose down"
+    - "docker compose up -d && make teardown"
+    - "make teardown"
 
 scan-analyse-service:
   stage: scan-docker
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-broker-service/Dockerfile b/dbrepo-broker-service/Dockerfile
index caef7401ec51119dd66b94c4ae0a3cf184021fed..78bc9bb462d61dda0def30fbd5ac70b45cde95f1 100644
--- a/dbrepo-broker-service/Dockerfile
+++ b/dbrepo-broker-service/Dockerfile
@@ -13,5 +13,3 @@ RUN rabbitmq-plugins enable --offline rabbitmq_prometheus rabbitmq_mqtt rabbitmq
 
 EXPOSE 5672
 EXPOSE 15672
-
-HEALTHCHECK --interval=10s --timeout=5s --retries=12 CMD wget --spider http://localhost:15672/broker/
diff --git a/dbrepo-broker-service/rabbitmq.conf b/dbrepo-broker-service/rabbitmq.conf
index 23942bcede8a6ab13812d91beea5aac8583c956b..e1883b4b825a9f9a6aa79a050fc01d8f8a1efdf0 100644
--- a/dbrepo-broker-service/rabbitmq.conf
+++ b/dbrepo-broker-service/rabbitmq.conf
@@ -10,8 +10,8 @@ default_permissions.write = .*
 # enable http outside localhost
 listeners.tcp.1 = 0.0.0.0:5672
 
-# management ui (https://www.rabbitmq.com/management.html#path-prefix)
-management.path_prefix = /broker
+# management prefix (https://www.rabbitmq.com/management.html#path-prefix)
+management.path_prefix = /admin/broker
 
 # logging
 log.console = true
diff --git a/dbrepo-gateway-service/dbrepo.conf b/dbrepo-gateway-service/dbrepo.conf
index b5f706fced78f9438ef7d9de98f2c321f92bfed2..68abcdeb0fbaaf2ebeadca382e60c2aad6b96056 100644
--- a/dbrepo-gateway-service/dbrepo.conf
+++ b/dbrepo-gateway-service/dbrepo.conf
@@ -34,8 +34,7 @@ server {
     listen 80 default_server;
     server_name _;
 
-    location /api/broker {
-        rewrite /api/broker/(.*) /api/$1 break;
+    location /admin/broker {
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -44,22 +43,22 @@ server {
         proxy_read_timeout      90;
     }
 
-    location /api/analyse {
+    location /api/broker {
+        rewrite /api/broker/(.*) /admin/broker/api/$1 break;
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header        X-Forwarded-Proto $scheme;
-        proxy_pass              http://analyse;
+        proxy_pass              http://broker;
         proxy_read_timeout      90;
     }
 
-    location /pid {
-        rewrite /pid/(.*) /api/pid/$1 break;
+    location /api/analyse {
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header        X-Forwarded-Proto $scheme;
-        proxy_pass              http://metadata;
+        proxy_pass              http://analyse;
         proxy_read_timeout      90;
     }
 
@@ -91,17 +90,17 @@ server {
         proxy_read_timeout      90;
     }
 
-    location /retrieve {
-        rewrite /retrieve/(.*) /$1 break;
+    location /api {
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header        X-Forwarded-Proto $scheme;
-        proxy_pass              http://search;
+        proxy_pass              http://metadata;
         proxy_read_timeout      90;
     }
 
-    location /api {
+    location /pid {
+        rewrite /pid/(.*) /api/pid/$1 break;
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -110,6 +109,16 @@ server {
         proxy_read_timeout      90;
     }
 
+    location /retrieve {
+        rewrite /retrieve/(.*) /$1 break;
+        proxy_set_header        Host $host;
+        proxy_set_header        X-Real-IP $remote_addr;
+        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header        X-Forwarded-Proto $scheme;
+        proxy_pass              http://search;
+        proxy_read_timeout      90;
+    }
+
     location / {
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
diff --git a/dbrepo-metadata-service/Dockerfile b/dbrepo-metadata-service/Dockerfile
index e9587b40feac829f8b1b7d0676779a758c7f29da..f88b37c5ec15bad047103c445298aa48569c4078 100644
--- a/dbrepo-metadata-service/Dockerfile
+++ b/dbrepo-metadata-service/Dockerfile
@@ -36,7 +36,7 @@ ENV ADMIN_MAIL="noreply@localhost"
 ENV BASE_URL="http://localhost"
 ENV GRANT_PRIVILEGES="SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE"
 ENV BROKER_CONSUMERS=2
-ENV BROKER_ENDPOINT="http://broker-service:15672"
+ENV BROKER_ENDPOINT="http://broker-service:15672/admin/broker"
 ENV BROKER_USERNAME=fda
 ENV BROKER_PASSWORD=fda
 ENV DELETED_RECORD=persistent
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerRemoteException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerRemoteException.java
new file mode 100644
index 0000000000000000000000000000000000000000..922462d2ee95b4cfea228b64cab7f80e40fa7661
--- /dev/null
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerRemoteException.java
@@ -0,0 +1,21 @@
+package at.tuwien.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE)
+public class BrokerRemoteException extends Exception {
+
+    public BrokerRemoteException(String msg) {
+        super(msg);
+    }
+
+    public BrokerRemoteException(String msg, Throwable thr) {
+        super(msg, thr);
+    }
+
+    public BrokerRemoteException(Throwable thr) {
+        super(thr);
+    }
+
+}
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/repositories/src/main/java/at/tuwien/exception/KeycloakRemoteException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/KeycloakRemoteException.java
index 594d70340303f18a3504324d75a445d1457158de..6616739278b0b02b8160d09e94c87f304f809628 100644
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/KeycloakRemoteException.java
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/KeycloakRemoteException.java
@@ -3,7 +3,7 @@ package at.tuwien.exception;
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.ResponseStatus;
 
-@ResponseStatus(code = HttpStatus.LOCKED)
+@ResponseStatus(code = HttpStatus.SERVICE_UNAVAILABLE)
 public class KeycloakRemoteException extends Exception {
 
     public KeycloakRemoteException(String msg) {
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/DatabaseMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/DatabaseMapper.java
index a889b2ee10a01328a477e4acf247f7fcc079bd84..5890c1b0193d7808e82cfa25943e908c771b9d6d 100644
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/DatabaseMapper.java
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/DatabaseMapper.java
@@ -163,9 +163,9 @@ public interface DatabaseMapper {
     }
 
     default PreparedStatement rawGrantCreatorAccessQuery(Connection connection, String databaseName, String username,
-                                                         String priviliges) throws QueryMalformedException {
+                                                         String privileges) throws QueryMalformedException {
         final StringBuilder statement = new StringBuilder("GRANT ")
-                .append(priviliges)
+                .append(privileges)
                 .append(" ON ")
                 .append(databaseName)
                 .append(".* TO `")
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 4c77a4ac257500f57fb03c03819e6a1c0c14d858..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;
@@ -84,7 +83,7 @@ public class DatabaseEndpoint {
     }
 
     @PostMapping
-    @Transactional
+    @Transactional(rollbackFor = Exception.class)
     @PreAuthorize("hasAuthority('create-database')")
     @Timed(value = "database.create", description = "Time needed to create a database")
     @Operation(summary = "Create database", security = @SecurityRequirement(name = "bearerAuth"))
@@ -140,8 +139,8 @@ public class DatabaseEndpoint {
             throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException,
             AmqpException, ContainerConnectionException, UserNotFoundException,
             DatabaseNotFoundException, DatabaseNameExistsException, DatabaseConnectionException,
-            QueryMalformedException, NotAllowedException, BrokerVirtualHostCreationException, QueryStoreException,
-            BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException {
+            QueryMalformedException, NotAllowedException, BrokerVirtualHostModificationException, QueryStoreException,
+            BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
         log.debug("endpoint create database, createDto={}, principal={}", createDto,
                 principal);
         final User user = userService.findByUsername(principal.getName());
@@ -272,7 +271,7 @@ public class DatabaseEndpoint {
     }
 
     @DeleteMapping("/{id}")
-    @Transactional
+    @Transactional(rollbackFor = Exception.class)
     @PreAuthorize("hasAuthority('delete-database')")
     @Timed(value = "database.delete", description = "Time needed to delete a database")
     @Operation(summary = "Delete some database", security = @SecurityRequirement(name = "bearerAuth"))
@@ -321,7 +320,7 @@ public class DatabaseEndpoint {
     public ResponseEntity<?> delete(@NotNull @PathVariable Long id, Principal principal)
             throws DatabaseNotFoundException, ImageNotSupportedException, DatabaseMalformedException, AmqpException,
             QueryMalformedException, UserNotFoundException, BrokerVirtualHostGrantException,
-            DatabaseConnectionException, KeycloakRemoteException, AccessDeniedException {
+            DatabaseConnectionException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
         log.debug("endpoint delete database, id={}, principal={}", id,
                 principal);
         final Database database = databaseService.findById(id);
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 c4d587c99ca7cb153d5ebf3617aae58d62806348..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
@@ -75,7 +77,7 @@ public class UserEndpoint {
     }
 
     @PostMapping
-    @Transactional
+    @Transactional(rollbackFor = Exception.class)
     @PreAuthorize("!isAuthenticated()")
     @Timed(value = "user.create", description = "Time needed to create a user in the metadata database")
     @Operation(summary = "Create user")
@@ -85,8 +87,11 @@ public class UserEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = UserBriefDto.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Parameters are not well-formed (likely email)",
+                    content = {@Content(mediaType = "application/json")}),
             @ApiResponse(responseCode = "404",
-                    description = "Realm or default role not found",
+                    description = "default role not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -102,15 +107,35 @@ public class UserEndpoint {
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody SignupRequestDto data)
-            throws RealmNotFoundException, UserAlreadyExistsException, UserEmailAlreadyExistsException,
-            UserNotFoundException, KeycloakRemoteException, AccessDeniedException, BrokerVirtualHostCreationException {
+            throws UserAlreadyExistsException, UserEmailAlreadyExistsException, UserNotFoundException,
+            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);
@@ -275,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 b792981dfc61eea5763f456f51d0fd3749454b43..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
@@ -40,17 +40,29 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
     }
 
     @Hidden
-    @ResponseStatus(HttpStatus.LOCKED)
+    @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
     @ExceptionHandler(KeycloakRemoteException.class)
     public ResponseEntity<ApiErrorDto> handle(KeycloakRemoteException e, WebRequest request) {
         final ApiErrorDto response = ApiErrorDto.builder()
-                .status(HttpStatus.LOCKED)
+                .status(HttpStatus.SERVICE_UNAVAILABLE)
                 .message(e.getLocalizedMessage())
                 .code("error.metadata.keycloak")
                 .build();
         return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
     }
 
+    @Hidden
+    @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
+    @ExceptionHandler(BrokerRemoteException.class)
+    public ResponseEntity<ApiErrorDto> handle(BrokerRemoteException e, WebRequest request) {
+        final ApiErrorDto response = ApiErrorDto.builder()
+                .status(HttpStatus.SERVICE_UNAVAILABLE)
+                .message(e.getLocalizedMessage())
+                .code("error.metadata.broker")
+                .build();
+        return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
+    }
+
     @Hidden
     @ResponseStatus(HttpStatus.CONFLICT)
     @ExceptionHandler(ContainerAlreadyExistsException.class)
@@ -233,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 d9ae17223957d0014fb074fac4c20784bb53d4dc..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,8 +115,8 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest {
     public void create_succeeds() throws UserNotFoundException, BrokerVirtualHostGrantException,
             DatabaseNameExistsException, NotAllowedException, ContainerConnectionException, DatabaseMalformedException,
             QueryStoreException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException,
-            ImageNotSupportedException, AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException,
-            KeycloakRemoteException, AccessDeniedException {
+            ImageNotSupportedException, AmqpException, BrokerVirtualHostModificationException, ContainerNotFoundException,
+            KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
         final DatabaseCreateDto request = DatabaseCreateDto.builder()
                 .cid(CONTAINER_1_ID)
                 .name(DATABASE_1_NAME)
@@ -399,7 +398,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest {
     @WithMockUser(username = USER_2_USERNAME, authorities = {"delete-database"})
     public void delete_hasRole_succeeds() throws UserNotFoundException, BrokerVirtualHostGrantException,
             DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
-            AmqpException, DatabaseMalformedException, KeycloakRemoteException, AccessDeniedException {
+            AmqpException, DatabaseMalformedException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
 
         /* test */
         delete_generic(DATABASE_2_ID, DATABASE_2, USER_2_PRINCIPAL);
@@ -429,8 +428,8 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest {
                                Principal principal) throws UserNotFoundException, DatabaseNameExistsException,
             NotAllowedException, ContainerConnectionException, DatabaseMalformedException, QueryStoreException,
             DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
-            AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException,
-            BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException {
+            AmqpException, BrokerVirtualHostModificationException, ContainerNotFoundException,
+            BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
 
         /* mock */
         doNothing()
@@ -499,7 +498,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest {
     public void delete_generic(Long databaseId, Database database, Principal principal)
             throws DatabaseNotFoundException, UserNotFoundException, DatabaseConnectionException,
             QueryMalformedException, ImageNotSupportedException, AmqpException, DatabaseMalformedException,
-            BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException {
+            BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
 
         /* mock */
         if (database != null) {
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 21b81f10e9ee1e4d095b7eba00b6ebae3d4b0470..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, 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, 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 ef9682a26d73a567883962dcc285cbb32fb88de3..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
@@ -3,7 +3,8 @@ package at.tuwien.gateway;
 import at.tuwien.BaseUnitTest;
 import at.tuwien.annotations.MockAmqp;
 import at.tuwien.annotations.MockOpensearch;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerRemoteException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.Test;
@@ -37,7 +38,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
     private BrokerServiceGateway brokerServiceGateway;
 
     @Test
-    public void createVirtualHost_succeeds() throws BrokerVirtualHostCreationException {
+    public void createVirtualHost_succeeds() throws BrokerVirtualHostModificationException, BrokerRemoteException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.CREATED)
                 .build();
 
@@ -59,13 +60,13 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
                 .thenReturn(mock);
 
         /* test */
-        assertThrows(BrokerVirtualHostCreationException.class, () -> {
+        assertThrows(BrokerVirtualHostModificationException.class, () -> {
             brokerServiceGateway.createVirtualHost(VIRTUAL_HOST_CREATE_DTO);
         });
     }
 
     @Test
-    public void grantPermission_exchangeNoRightsBefore_succeeds() throws BrokerVirtualHostGrantException {
+    public void grantPermission_exchangeNoRightsBefore_succeeds() throws BrokerVirtualHostGrantException, BrokerRemoteException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.CREATED)
                 .build();
 
@@ -78,7 +79,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
     }
 
     @Test
-    public void grantPermission_exchangeRightsSame_succeeds() throws BrokerVirtualHostGrantException {
+    public void grantPermission_exchangeRightsSame_succeeds() throws BrokerVirtualHostGrantException, BrokerRemoteException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.NO_CONTENT)
                 .build();
 
@@ -106,7 +107,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
     }
 
     @Test
-    public void grantPermission_virtualHostNoRightsBefore_succeeds() throws BrokerVirtualHostGrantException {
+    public void grantPermission_virtualHostNoRightsBefore_succeeds() throws BrokerRemoteException, BrokerVirtualHostGrantException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.CREATED)
                 .build();
 
@@ -119,7 +120,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
     }
 
     @Test
-    public void grantPermission_virtualHostRightsSame_succeeds() throws BrokerVirtualHostGrantException {
+    public void grantPermission_virtualHostRightsSame_succeeds() throws BrokerRemoteException, BrokerVirtualHostGrantException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.NO_CONTENT)
                 .build();
 
@@ -147,7 +148,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest {
     }
 
     @Test
-    public void createUser_succeeds() throws BrokerVirtualHostCreationException {
+    public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostModificationException {
         final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.NO_CONTENT)
                 .build();
 
@@ -169,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/endpoints/SwaggerComponentTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/SwaggerEndpointMvcTest.java
similarity index 85%
rename from dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/SwaggerComponentTest.java
rename to dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/SwaggerEndpointMvcTest.java
index c19bd4bc018cb102665690188d3ab575bff44cfb..c07446eee592ebdb8d2b7d7e631fdc9f10eca927 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/SwaggerComponentTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/SwaggerEndpointMvcTest.java
@@ -1,16 +1,14 @@
-package at.tuwien.endpoints;
+package at.tuwien.mvc;
 
 import at.tuwien.BaseUnitTest;
 import at.tuwien.annotations.MockAmqp;
 import at.tuwien.annotations.MockOpensearch;
-import at.tuwien.repository.sdb.DatabaseIdxRepository;
 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.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.test.web.servlet.MockMvc;
 
@@ -24,7 +22,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 @SpringBootTest
 @MockAmqp
 @MockOpensearch
-public class SwaggerComponentTest extends BaseUnitTest {
+public class SwaggerEndpointMvcTest extends BaseUnitTest {
 
     @Autowired
     private MockMvc mockMvc;
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/UserEndpointMvcTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/UserEndpointMvcTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..44e4c35fcc3cbfa133a258f440a0fa0ef8b604f6
--- /dev/null
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/UserEndpointMvcTest.java
@@ -0,0 +1,109 @@
+package at.tuwien.mvc;
+
+import at.tuwien.BaseUnitTest;
+import at.tuwien.annotations.MockAmqp;
+import at.tuwien.annotations.MockOpensearch;
+import at.tuwien.api.auth.CreateUserDto;
+import at.tuwien.api.auth.SignupRequestDto;
+import at.tuwien.api.keycloak.UserCreateDto;
+import at.tuwien.exception.BrokerRemoteException;
+import at.tuwien.exception.KeycloakRemoteException;
+import at.tuwien.gateway.BrokerServiceGateway;
+import at.tuwien.gateway.KeycloakGateway;
+import at.tuwien.gateway.impl.KeycloakGatewayImpl;
+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.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static at.tuwien.test.utils.ObjectUtil.asJsonString;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@Log4j2
+@ExtendWith(SpringExtension.class)
+@AutoConfigureMockMvc
+@SpringBootTest
+@MockAmqp
+@MockOpensearch
+public class UserEndpointMvcTest extends BaseUnitTest {
+
+    @MockBean
+    private BrokerServiceGateway brokerServiceGateway;
+
+    @MockBean
+    private KeycloakGatewayImpl keycloakGateway;
+
+    @Autowired
+    private MockMvc mockMvc;
+
+    @Test
+    public void createUser_malformed_fails() throws Exception {
+        final SignupRequestDto request = SignupRequestDto.builder()
+                .username(USER_1_USERNAME)
+                .password(USER_1_PASSWORD)
+                .email("invalid_email")
+                .build();
+
+        /* mock */
+        doNothing()
+                .when(brokerServiceGateway)
+                .createUser(USER_1_USERNAME);
+
+        /* test */
+        this.mockMvc.perform(post("/api/user")
+                        .content(asJsonString(request))
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .accept(MediaType.APPLICATION_JSON))
+                .andDo(print())
+                .andExpect(status().is(400));
+    }
+
+    @Test
+    public void createUser_keycloakOffline_503_fails() throws Exception {
+
+        /* mock */
+        doThrow(KeycloakRemoteException.class)
+                .when(keycloakGateway)
+                .createUser(any(UserCreateDto.class));
+
+        /* test */
+        this.mockMvc.perform(post("/api/user")
+                        .content(asJsonString(USER_1_SIGNUP_REQUEST_DTO))
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .accept(MediaType.APPLICATION_JSON))
+                .andDo(print())
+                .andExpect(status().is(503));
+    }
+
+    @Test
+    public void createUser_brokerOffline_503_fails() throws Exception {
+
+        /* mock */
+        doNothing()
+                .when(keycloakGateway)
+                .createUser(any(UserCreateDto.class));
+        when(keycloakGateway.findByUsername(USER_1_USERNAME))
+                .thenReturn(USER_1_KEYCLOAK_DTO);
+        doThrow(BrokerRemoteException.class)
+                .when(brokerServiceGateway)
+                .createUser(USER_1_USERNAME);
+
+        /* test */
+        this.mockMvc.perform(post("/api/user")
+                        .content(asJsonString(USER_1_SIGNUP_REQUEST_DTO))
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .accept(MediaType.APPLICATION_JSON))
+                .andDo(print())
+                .andExpect(status().is(503));
+    }
+
+}
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/DatabaseServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
index 67de4364b64bc0dcc5d5f32612a89bbcb5945f03..5fd4fdf02b04b37fe8f913c7e2fa85a7b34fcef2 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
@@ -6,10 +6,12 @@ import at.tuwien.annotations.MockOpensearch;
 import at.tuwien.api.database.*;
 import at.tuwien.config.MariaDbConfig;
 import at.tuwien.config.MariaDbContainerConfig;
+import at.tuwien.config.QueryConfig;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.gateway.KeycloakGateway;
+import at.tuwien.mapper.DatabaseMapper;
 import at.tuwien.repository.mdb.*;
 import at.tuwien.repository.sdb.DatabaseIdxRepository;
 import at.tuwien.service.impl.MariaDbServiceImpl;
@@ -17,6 +19,7 @@ import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Answers;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
@@ -26,13 +29,14 @@ import org.testcontainers.containers.MariaDBContainer;
 import org.testcontainers.junit.jupiter.Container;
 import org.testcontainers.junit.jupiter.Testcontainers;
 
+import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.SQLInvalidAuthorizationSpecException;
 import java.util.List;
 
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
 
 @Log4j2
 @Testcontainers
@@ -46,6 +50,9 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
     @MockBean
     private DatabaseIdxRepository databaseIdxRepository;
 
+    @MockBean
+    private QueryConfig queryConfig;
+
     @Autowired
     private UserRepository userRepository;
 
@@ -109,6 +116,8 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
                 .thenReturn(DATABASE_1_DTO);
         when(databaseIdxRepository.save(any(DatabaseDto.class)))
                 .thenReturn(DATABASE_1_DTO);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
 
         /* test */
         generic_create(DATABASE_1_CREATE, DATABASE_1);
@@ -123,6 +132,8 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
                 .thenReturn(DATABASE_1_DTO);
         when(databaseIdxRepository.save(any(DatabaseDto.class)))
                 .thenReturn(DATABASE_1_DTO);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
 
         /* test */
         generic_create(DATABASE_1_CREATE, DATABASE_1);
@@ -139,6 +150,8 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
         when(databaseIdxRepository.save(any(DatabaseDto.class)))
                 .thenReturn(DATABASE_2_DTO)
                 .thenReturn(DATABASE_3_DTO);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
 
         /* test */
         generic_create(DATABASE_2_CREATE, DATABASE_2);
@@ -155,6 +168,8 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
         when(databaseIdxRepository.save(any(DatabaseDto.class)))
                 .thenReturn(DATABASE_3_DTO)
                 .thenReturn(DATABASE_2_DTO);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
 
         /* test */
         generic_create(DATABASE_3_CREATE, DATABASE_3);
@@ -169,11 +184,31 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
         databaseRepository.deleteAll();
         when(databaseIdxRepository.save(any(DatabaseDto.class)))
                 .thenReturn(DATABASE_1_DTO);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
         final Database database = generic_create(DATABASE_1_CREATE, DATABASE_1);
 
 
         /* test */
-        MariaDbConfig.getPrivileges(mariaDBContainer.getHost(), mariaDBContainer.getMappedPort(3306), database.getInternalName(), USER_1_USERNAME, USER_1_PASSWORD);
+        MariaDbConfig.getPrivileges(mariaDBContainer.getHost(), 3308, database.getInternalName(), USER_1_USERNAME, USER_1_PASSWORD);
+    }
+
+    @Test
+    public void create_existsRollbackSucceeds_fails() throws Exception {
+
+        /* mock */
+        MariaDbConfig.dropDatabase(CONTAINER_1, DATABASE_1_INTERNALNAME);
+        databaseRepository.deleteAll();
+        when(databaseIdxRepository.save(any(DatabaseDto.class)))
+                .thenReturn(DATABASE_1_DTO);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("" /* (1) */, "SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE"/* (2) */);
+
+        /* test */
+        assertThrows(DatabaseMalformedException.class, () -> {
+            databaseService.create(DATABASE_1_CREATE, USER_1_PRINCIPAL); // (1)
+        });
+        generic_create(DATABASE_1_CREATE, DATABASE_1); // (2)
     }
 
     @Test
@@ -184,22 +219,28 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
         databaseAccessRepository.save(DATABASE_1_USER_3_READ_ACCESS);
         when(databaseIdxRepository.save(any(DatabaseDto.class)))
                 .thenReturn(DATABASE_1_DTO);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
 
         /* test */
         assertThrows(SQLInvalidAuthorizationSpecException.class, () -> {
-            MariaDbConfig.getPrivileges(mariaDBContainer.getHost(), mariaDBContainer.getMappedPort(3306), USER_3_USERNAME, USER_4_PASSWORD);
+            MariaDbConfig.getPrivileges(mariaDBContainer.getHost(), 3308, USER_3_USERNAME, USER_4_PASSWORD);
         });
         databaseService.updatePassword(User.builder()
-                        .id(USER_3_ID)
-                        .username(USER_3_USERNAME)
-                        .mariadbPassword(USER_4_DATABASE_PASSWORD)
+                .id(USER_3_ID)
+                .username(USER_3_USERNAME)
+                .mariadbPassword(USER_4_DATABASE_PASSWORD)
                 .build());
-        MariaDbConfig.getPrivileges(mariaDBContainer.getHost(), mariaDBContainer.getMappedPort(3306), USER_3_USERNAME, USER_4_PASSWORD);
+        MariaDbConfig.getPrivileges(mariaDBContainer.getHost(), 3308, USER_3_USERNAME, USER_4_PASSWORD);
     }
 
     @Test
     public void create_queryStore_succeeds() throws Exception {
 
+        /* mock */
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
+
         /* test */
         generic_insert(QUERY_4_STATEMENT, 1L);
     }
@@ -207,6 +248,10 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
     @Test
     public void create_queryStoreSameQueryHash_succeeds() throws Exception {
 
+        /* mock */
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
+
         /* test */
         generic_insert(QUERY_4_STATEMENT, 1L);
         generic_insert(QUERY_5_STATEMENT, 2L);
@@ -216,6 +261,10 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
     @Test
     public void create_systemProcedure_succeeds() throws Exception {
 
+        /* mock */
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
+
         /* test */
         generic_system_insert(CONTAINER_1_PRIVILEGED_USERNAME, CONTAINER_1_PRIVILEGED_PASSWORD);
     }
@@ -223,6 +272,10 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
     @Test
     public void create_systemProcedure_fails() {
 
+        /* mock */
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
+
         /* test */
         assertThrows(SQLException.class, () -> {
             generic_system_insert("junit1", "junit1");
@@ -232,6 +285,10 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
     @Test
     public void create_userProcedureRoot_succeeds() throws SQLException, QueryMalformedException {
 
+        /* mock */
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
+
         /* test */
         generic_user_insert(CONTAINER_1_PRIVILEGED_USERNAME, CONTAINER_1_PRIVILEGED_PASSWORD);
     }
@@ -244,6 +301,8 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
         MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_3);
         mariaDbConfig.grantUserPermissions(CONTAINER_1, DATABASE_3, "junit1");
         databaseAccessRepository.save(DATABASE_3_USER_1_WRITE_ALL_ACCESS);
+        when(queryConfig.getGrantPrivileges())
+                .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
 
         /* test */
         generic_user_insert("junit1", "junit1");
@@ -275,7 +334,7 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
     }
 
     @Test
-    public void transfer_succeeds() throws DatabaseNotFoundException, UserNotFoundException{
+    public void transfer_succeeds() throws DatabaseNotFoundException, UserNotFoundException {
         final DatabaseTransferDto request = DatabaseTransferDto.builder()
                 .username(USER_2_USERNAME)
                 .build();
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java
index 73429969253b1e2ea7761d20d995c4ba95a52716..92236fbb31b2c70db18906792c5c5a0068ef0b1d 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java
@@ -100,7 +100,7 @@ public class DatabaseServiceUnitTest extends BaseUnitTest {
     }
 
     @Test
-    public void create_notFound_fails() throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException {
+    public void create_notFound_fails() throws UserNotFoundException {
         final DatabaseCreateDto request = DatabaseCreateDto.builder()
                 .cid(CONTAINER_1_ID)
                 .name(DATABASE_1_NAME)
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 b68d07b0df8de1599b9c0918b304b26cf72787cb..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
@@ -4,7 +4,8 @@ import at.tuwien.BaseUnitTest;
 import at.tuwien.annotations.MockOpensearch;
 import at.tuwien.api.amqp.PermissionDto;
 import at.tuwien.exception.AmqpException;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerRemoteException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import at.tuwien.repository.mdb.DatabaseRepository;
 import at.tuwien.repository.mdb.TableRepository;
@@ -85,14 +86,14 @@ public class MessageQueueServiceIntegrationTest extends BaseUnitTest {
     }
 
     @Test
-    public void createUser_succeeds() throws BrokerVirtualHostCreationException {
+    public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostModificationException {
 
         /* test */
         messageQueueService.createUser(USER_1_USERNAME);
     }
 
     @Test
-    public void updatePermissions_empty_succeeds() throws BrokerVirtualHostGrantException {
+    public void updatePermissions_empty_succeeds() throws BrokerRemoteException, BrokerVirtualHostGrantException {
 
         /* test */
         final PermissionDto permissions = updatePermissions_generic();
@@ -104,7 +105,7 @@ public class MessageQueueServiceIntegrationTest extends BaseUnitTest {
     }
 
     @Test
-    public void updatePermissions_owner_succeeds() throws BrokerVirtualHostGrantException {
+    public void updatePermissions_owner_succeeds() throws BrokerRemoteException, BrokerVirtualHostGrantException {
 
         /* mock */
         when(databaseRepository.findConfigureAccess(USER_1_ID))
@@ -124,7 +125,7 @@ public class MessageQueueServiceIntegrationTest extends BaseUnitTest {
     }
 
     @Test
-    public void updatePermissions_ownerNoAccess_succeeds() throws BrokerVirtualHostGrantException {
+    public void updatePermissions_ownerNoAccess_succeeds() throws BrokerRemoteException, BrokerVirtualHostGrantException {
 
         /* mock */
         when(databaseRepository.findConfigureAccess(USER_1_ID))
@@ -163,7 +164,7 @@ public class MessageQueueServiceIntegrationTest extends BaseUnitTest {
     /* ## GENERIC TEST CASES                                                                            ## */
     /* ################################################################################################### */
 
-    protected PermissionDto updatePermissions_generic() throws BrokerVirtualHostGrantException {
+    protected PermissionDto updatePermissions_generic() throws BrokerRemoteException, BrokerVirtualHostGrantException {
 
         /* mock */
         amqpUtils.createUser(USER_1_USERNAME, USER_1_RABBITMQ_CREATE_DTO);
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/QueueServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueueServiceIntegrationTest.java
index c5669b5407ea0225db338a63b204364895ebf1c4..4be1fb518bebd3dcc00d03bf092903a2a63f396d 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueueServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueueServiceIntegrationTest.java
@@ -10,6 +10,7 @@ import at.tuwien.config.MariaDbConfig;
 import at.tuwien.config.MariaDbContainerConfig;
 import at.tuwien.config.RabbitMqConfig;
 import at.tuwien.exception.AmqpException;
+import at.tuwien.exception.BrokerRemoteException;
 import at.tuwien.gateway.BrokerServiceGateway;
 import at.tuwien.listener.impl.RabbitMqListenerImpl;
 import at.tuwien.repository.mdb.DatabaseRepository;
@@ -208,7 +209,7 @@ public class QueueServiceIntegrationTest extends BaseUnitTest {
 
     @Test
     @Disabled("Not testable")
-    public void restore_succeeds() throws AmqpException, IOException {
+    public void restore_succeeds() throws AmqpException, IOException, BrokerRemoteException {
 
         /* mock */
         when(tableRepository.findAll())
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/rest-service/src/test/resources/application.properties b/dbrepo-metadata-service/rest-service/src/test/resources/application.properties
index 2e2bd0d465c79c57ce5ed3a24071c10789e2c503..a004db1bceab10545f026b3752c6db633ddc80b2 100644
--- a/dbrepo-metadata-service/rest-service/src/test/resources/application.properties
+++ b/dbrepo-metadata-service/rest-service/src/test/resources/application.properties
@@ -16,7 +16,7 @@ spring.jpa.hibernate.ddl-auto=create
 
 # logging
 logging.level.root=error
-logging.level.at.tuwien.=debug
+logging.level.at.tuwien.=${LOG_LEVEL:-debug}
 
 # rabbitmq
 fda.broker.endpoint=http://localhost:15672
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 ba38f6118fce9c18829ed8cf5c96d9866a37cb47..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
@@ -4,47 +4,66 @@ import at.tuwien.api.amqp.ConsumerDto;
 import at.tuwien.api.amqp.CreateVirtualHostDto;
 import at.tuwien.api.amqp.GrantVirtualHostPermissionsDto;
 import at.tuwien.api.user.ExchangeUpdatePermissionsDto;
-import at.tuwien.exception.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerRemoteException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 
 import java.util.List;
 
 public interface BrokerServiceGateway {
 
-    List<ConsumerDto> findAllConsumers();
+    /**
+     * Finds all active consumers on the virtual host "dbrepo".
+     *
+     * @return The list of active consumers.
+     * @throws BrokerRemoteException The Broker Service did not respond within the 3s timeout.
+     */
+    List<ConsumerDto> findAllConsumers() throws BrokerRemoteException;
 
     /**
      * Create virtual host at the queue service.
      *
      * @param data The virtual host.
-     * @throws BrokerVirtualHostCreationException The queue 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;
+    void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostModificationException, BrokerRemoteException;
 
     /**
      * Grants a user permission at a virtual host in the queue service.
      *
      * @param username The username of the user.
      * @param data     The grant data.
-     * @throws BrokerVirtualHostGrantException The queue service did not respond within the 3s timeout.
+     * @throws BrokerVirtualHostGrantException The permissions could not be granted.
+     * @throws BrokerRemoteException           The Broker Service did not respond within the 3s timeout.
+     */
+    void grantPermission(String username, ExchangeUpdatePermissionsDto data) throws BrokerVirtualHostGrantException, BrokerRemoteException;
+
+    /**
+     * Create 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 created.
      */
-    void grantPermission(String username, ExchangeUpdatePermissionsDto data)
-            throws BrokerVirtualHostGrantException;
+    void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException;
 
     /**
-     * Create user on the broker service
+     * Deletes a user on the broker service with given username.
      *
-     * @param username The new username.
-     * @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 deleted.
      */
-    void createUser(String username) throws BrokerVirtualHostCreationException;
+    void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException;
 
     /**
      * Grants a user permission at a virtual host in the queue service.
      *
      * @param username The username of the user.
      * @param data     The grant data.
-     * @throws BrokerVirtualHostGrantException The queue service did not respond within the 3s timeout.
+     * @throws BrokerRemoteException           The Broker Service did not respond within the 3s timeout.
+     * @throws BrokerVirtualHostGrantException The permissions could not be granted.
      */
-    void grantPermission(String username, GrantVirtualHostPermissionsDto data) throws BrokerVirtualHostGrantException;
+    void grantPermission(String username, GrantVirtualHostPermissionsDto data) throws BrokerRemoteException, BrokerVirtualHostGrantException;
 }
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 612ee2eb372cbee0f0c10067d55eba0d2029f988..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
@@ -9,11 +9,47 @@ import java.util.UUID;
 
 public interface KeycloakGateway {
 
+    /**
+     * Creates a user at the Authentication Service with given credentials.
+     *
+     * @param data The user 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 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.
+     *
+     * @param id       The user id.
+     * @param password The user credential.
+     * @throws AccessDeniedException   The admin token could not be obtained.
+     * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout.
+     */
     void updateUserCredentials(UUID id, UserPasswordDto password) throws AccessDeniedException,
             KeycloakRemoteException;
 
+    /**
+     * Finds a user in the metadata database by given username.
+     *
+     * @param username The user username.
+     * @return The updated user.
+     * @throws AccessDeniedException   The admin token could not be obtained.
+     * @throws UserNotFoundException   The user was not found,
+     * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout.
+     */
     UserDto findByUsername(String username) throws AccessDeniedException, UserNotFoundException,
             KeycloakRemoteException;
 }
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 52de16e2f364e3ea6f4896763dc0514cc0331a64..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,19 +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.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerRemoteException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 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;
@@ -25,50 +22,54 @@ 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
 @Service
 public class BrokerServiceGatewayImpl implements BrokerServiceGateway {
 
-    private final Environment environment;
     private final RestTemplate restTemplate;
     private final GatewayConfig gatewayConfig;
 
     private final static String VIRTUAL_SERVER = "dbrepo";
 
     @Autowired
-    public BrokerServiceGatewayImpl(Environment environment, GatewayConfig gatewayConfig,
+    public BrokerServiceGatewayImpl(GatewayConfig gatewayConfig,
                                     @Qualifier("brokerRestTemplate") RestTemplate restTemplate) {
-        this.environment = environment;
         this.restTemplate = restTemplate;
         this.gatewayConfig = gatewayConfig;
     }
 
-    private String parseUrl(String path) {
-        final String url = "/api" + path;
-        log.debug("parse url: {}", url);
-        return url;
-    }
-
     @Override
-    public void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostCreationException {
-        final ResponseEntity<Void> response = restTemplate.exchange(parseUrl("/vhost"), HttpMethod.POST,
-                new HttpEntity<>(data), Void.class);
+    public void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostModificationException, BrokerRemoteException {
+        final String url = "/api/vhost";
+        log.trace("POST {}{}", gatewayConfig.getBrokerEndpoint(), url);
+        final ResponseEntity<Void> response;
+        try {
+            response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(data), Void.class);
+        } catch (Exception e) {
+            log.error("Failed to create virtual host: remote host answered unexpected: {}", e.getMessage());
+            throw new BrokerRemoteException("Failed to create virtual host: remote host answered unexpected", e);
+        }
         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());
     }
 
     @Override
     public void grantPermission(String username, ExchangeUpdatePermissionsDto data)
-            throws BrokerVirtualHostGrantException {
-        final ResponseEntity<Void> response = restTemplate.exchange(parseUrl("/topic-permissions/dbrepo/" + username), HttpMethod.PUT,
-                new HttpEntity<>(data), Void.class);
+            throws BrokerVirtualHostGrantException, BrokerRemoteException {
+        final String url = "/api/topic-permissions/dbrepo/" + username;
+        log.trace("PUT {}{}", gatewayConfig.getBrokerEndpoint(), url);
+        final ResponseEntity<Void> response;
+        try {
+            response = restTemplate.exchange(url, HttpMethod.PUT, new HttpEntity<>(data), Void.class);
+        } catch (Exception e) {
+            log.error("Failed to grant permissions: remote host answered unexpected: {}", e.getMessage());
+            throw new BrokerRemoteException("Failed to grant permissions: remote host answered unexpected", e);
+        }
         if (!response.getStatusCode().equals(HttpStatus.CREATED) && !response.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
             log.error("Failed to grant exchange: {}", response.getStatusCode());
             throw new BrokerVirtualHostGrantException("Failed to grant exchange");
@@ -77,25 +78,57 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway {
     }
 
     @Override
-    public void createUser(String username) throws BrokerVirtualHostCreationException {
+    public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException {
         final CreateUserDto data = CreateUserDto.builder()
                 .passwordHash("")
                 .tags("")
                 .build();
-        final ResponseEntity<Void> response = restTemplate.exchange(parseUrl("/users/" + username), HttpMethod.PUT,
-                new HttpEntity<>(data), Void.class);
+        final String url = "/api/users/" + username;
+        log.trace("PUT {}{}", gatewayConfig.getBrokerEndpoint(), url);
+        final ResponseEntity<Void> response;
+        try {
+            response = restTemplate.exchange(url, HttpMethod.PUT, new HttpEntity<>(data), Void.class);
+        } catch (Exception e) {
+            log.error("Failed to create user: remote host answered unexpected: {}", e.getMessage());
+            throw new BrokerRemoteException("Failed to create user: remote host answered unexpected", e);
+        }
         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 grantPermission(String username, GrantVirtualHostPermissionsDto data)
-            throws BrokerVirtualHostGrantException {
-        final ResponseEntity<Void> response = restTemplate.exchange(parseUrl("/permissions/dbrepo/" + username), HttpMethod.PUT,
-                new HttpEntity<>(data), Void.class);
+    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 {
+        final String url = "/api/permissions/dbrepo/" + username;
+        log.trace("PUT {}{}", gatewayConfig.getBrokerEndpoint(), url);
+        final ResponseEntity<Void> response;
+        try {
+            response = restTemplate.exchange(url, HttpMethod.PUT, new HttpEntity<>(data), Void.class);
+        } catch (Exception e) {
+            log.error("Failed to create permissions: remote host answered unexpected: {}", e.getMessage());
+            throw new BrokerRemoteException("Failed to create permissions: remote host answered unexpected", e);
+        }
         if (!response.getStatusCode().equals(HttpStatus.CREATED) && !response.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
             log.error("Failed to grant virtual host: {}", response.getStatusCode());
             throw new BrokerVirtualHostGrantException("Failed to grant virtual host");
@@ -104,19 +137,19 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway {
     }
 
     @Override
-    public List<ConsumerDto> findAllConsumers() {
-        final StringBuilder urlBuilder = new StringBuilder(gatewayConfig.getBrokerEndpoint())
-                .append("/api");
-        if (Arrays.stream(environment.getActiveProfiles()).noneMatch(p -> p.equals("junit"))) {
-            urlBuilder.append("/broker");
-        }
-        urlBuilder.append("/consumers/")
-                .append(VIRTUAL_SERVER);
+    public List<ConsumerDto> findAllConsumers() throws BrokerRemoteException {
+        final String url = "/api/consumers/" + VIRTUAL_SERVER;
         log.trace("gateway broker find all consumers, virtual server={}", VIRTUAL_SERVER);
-        final URI findUri = URI.create(urlBuilder.toString());
-        final ResponseEntity<List<ConsumerDto>> response = restTemplate.exchange(findUri, HttpMethod.GET,
-                HttpEntity.EMPTY, new ParameterizedTypeReference<>() {
-                });
+        log.trace("GET {}{}", gatewayConfig.getBrokerEndpoint(), url);
+        final ResponseEntity<List<ConsumerDto>> response;
+        try {
+            response = restTemplate.exchange(URI.create(url), HttpMethod.GET, HttpEntity.EMPTY,
+                    new ParameterizedTypeReference<>() {
+                    });
+        } catch (Exception e) {
+            log.error("Failed to find consumers: remote host answered unexpected: {}", e.getMessage());
+            throw new BrokerRemoteException("Failed to find consumers: remote host answered unexpected", e);
+        }
         return response.getBody();
     }
 
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 91f33c336c3bb80322d573a2ad6737c0f32b40a7..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
@@ -33,7 +33,7 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
         this.keycloakConfig = keycloakConfig;
     }
 
-    public TokenDto obtainToken() throws AccessDeniedException {
+    public TokenDto obtainToken() throws AccessDeniedException, KeycloakRemoteException {
         final HttpHeaders headers = new HttpHeaders();
         headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
         final MultiValueMap<String, String> payload = new LinkedMultiValueMap<>();
@@ -49,6 +49,9 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
         } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) {
             log.error("Failed to obtain admin token: {}", e.getMessage());
             throw new AccessDeniedException("Failed to obtain admin token: " + e.getMessage());
+        } catch (Exception e) {
+            log.error("Failed to create user: remote host answered unexpected: {}", e.getMessage());
+            throw new KeycloakRemoteException("Failed to create user: remote host answered unexpected", e);
         }
         return response.getBody();
     }
@@ -76,11 +79,43 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
                 log.error("Conflict when creating user: {}", e.getMessage());
                 throw new UserAlreadyExistsException("Conflict when creating user: " + e.getMessage());
             }
+        } catch (Exception e) {
+            log.error("Failed to create user: remote host answered unexpected: {}", e.getMessage());
+            throw new KeycloakRemoteException("Failed to create user: remote host answered unexpected", e);
         }
         if (!response.getStatusCode().equals(HttpStatus.CREATED)) {
             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
@@ -99,11 +134,15 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
         } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) {
             log.error("Failed to update user credentials: {}", e.getMessage());
             throw new KeycloakRemoteException("Failed to update user credentials: " + e.getMessage());
+        } catch (Exception e) {
+            log.error("Failed to create user: remote host answered unexpected: {}", e.getMessage());
+            throw new KeycloakRemoteException("Failed to create user: remote host answered unexpected", e);
         }
         if (!response.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
             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
@@ -121,6 +160,9 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
         } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) {
             log.error("Failed to find user: {}", e.getMessage());
             throw new KeycloakRemoteException("Failed to find user: " + e.getMessage());
+        } catch (Exception e) {
+            log.error("Failed to create user: remote host answered unexpected: {}", e.getMessage());
+            throw new KeycloakRemoteException("Failed to create user: remote host answered unexpected", e);
         }
         final UserDto[] body = response.getBody();
         if (body == null || body.length != 1) {
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/MessageQueueListener.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/MessageQueueListener.java
index f6c0d703b0783e57ca580a58436ddd48a8abc468..7b5c1ffa2cf16f1996372a085f7a0958f36cf931 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/MessageQueueListener.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/MessageQueueListener.java
@@ -1,6 +1,7 @@
 package at.tuwien.listener;
 
 import at.tuwien.exception.AmqpException;
+import at.tuwien.exception.BrokerRemoteException;
 import org.springframework.scheduling.annotation.Scheduled;
 
 import java.util.concurrent.TimeUnit;
@@ -13,5 +14,5 @@ public interface MessageQueueListener {
      * @throws AmqpException The consumer could not be created.
      */
     @Scheduled(fixedDelay = 5, initialDelay = 300, timeUnit = TimeUnit.SECONDS)
-    void updateConsumers() throws AmqpException;
+    void updateConsumers() throws AmqpException, BrokerRemoteException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/RabbitMqListenerImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/RabbitMqListenerImpl.java
index cb6c74658562238f4d17d0d86b12ef104d4d849c..cc454351e616943f6179ab5a2bce9b43a91b9972 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/RabbitMqListenerImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/listener/impl/RabbitMqListenerImpl.java
@@ -1,6 +1,7 @@
 package at.tuwien.listener.impl;
 
 import at.tuwien.exception.AmqpException;
+import at.tuwien.exception.BrokerRemoteException;
 import at.tuwien.listener.MessageQueueListener;
 import at.tuwien.service.MessageQueueService;
 import lombok.extern.log4j.Log4j2;
@@ -23,7 +24,7 @@ public class RabbitMqListenerImpl implements MessageQueueListener {
     @Override
     @Scheduled(fixedDelay = 5, initialDelay = 300, timeUnit = TimeUnit.SECONDS)
     @Transactional(readOnly = true)
-    public void updateConsumers() throws AmqpException {
+    public void updateConsumers() throws AmqpException, BrokerRemoteException {
         messageQueueService.restore();
     }
 
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 bfd0d4a1d32f1c2817f67ec57a977fe94b6016af..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,11 +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.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerRemoteException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import jakarta.annotation.PostConstruct;
 
@@ -43,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 BrokerVirtualHostCreationException 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 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.
@@ -57,7 +66,7 @@ public interface MessageQueueService {
      * @param user The user.
      * @throws BrokerVirtualHostGrantException The Broker Service refused to grant the permissions.
      */
-    void updatePermissions(User user) throws BrokerVirtualHostGrantException;
+    void updatePermissions(User user) throws BrokerVirtualHostGrantException, BrokerRemoteException;
 
     /**
      * Deletes an exchange for a database.
@@ -82,5 +91,5 @@ public interface MessageQueueService {
      *
      * @throws AmqpException The consumer could not be created.
      */
-    void restore() throws AmqpException;
+    void restore() throws AmqpException, BrokerRemoteException;
 }
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 40272285475a690f8904c7583f5c8a8f6b88d4e2..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
@@ -8,7 +8,8 @@ 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.BrokerVirtualHostCreationException;
+import at.tuwien.exception.BrokerRemoteException;
+import at.tuwien.exception.BrokerVirtualHostModificationException;
 import at.tuwien.exception.BrokerVirtualHostGrantException;
 import at.tuwien.gateway.BrokerServiceGateway;
 import at.tuwien.mapper.AmqpMapper;
@@ -20,7 +21,6 @@ import at.tuwien.service.TableService;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.rabbitmq.client.BuiltinExchangeType;
 import com.rabbitmq.client.Channel;
-import com.rabbitmq.client.Connection;
 import com.rabbitmq.client.ConnectionFactory;
 import lombok.extern.log4j.Log4j2;
 import org.apache.http.auth.BasicUserPrincipal;
@@ -104,12 +104,17 @@ public class RabbitMqServiceImpl implements MessageQueueService {
     }
 
     @Override
-    public void createUser(String username) throws BrokerVirtualHostCreationException {
+    public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException {
         brokerServiceGateway.createUser(username);
     }
 
     @Override
-    public void updatePermissions(User user) throws BrokerVirtualHostGrantException {
+    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()
                 .configure(amqpMapper.databaseListToPermissionString(databaseRepository.findConfigureAccess(user.getId())))
                 .write(amqpMapper.databaseListToPermissionString(databaseRepository.findWriteAccess(user.getId())))
@@ -145,7 +150,7 @@ public class RabbitMqServiceImpl implements MessageQueueService {
     }
 
     @Override
-    public void restore() throws AmqpException {
+    public void restore() throws AmqpException, BrokerRemoteException {
         final List<Table> tables = tableService.findAll();
         final List<ConsumerDto> consumers = brokerServiceGateway.findAllConsumers();
         for (Table table : tables) {
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/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/utils/ObjectUtil.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/utils/ObjectUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..10286fc6bd0635fc340ef538658fcb9d4c267cde
--- /dev/null
+++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/utils/ObjectUtil.java
@@ -0,0 +1,15 @@
+package at.tuwien.test.utils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class ObjectUtil {
+
+    public static String asJsonString(final Object obj) {
+        try {
+            return new ObjectMapper().writeValueAsString(obj);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/dbrepo-ui/Dockerfile b/dbrepo-ui/Dockerfile
index def7915b216fe1f8e919e397219f6cb00f4c87f5..066d69cb53013b5a7de4d685545cfd0d2538d18b 100644
--- a/dbrepo-ui/Dockerfile
+++ b/dbrepo-ui/Dockerfile
@@ -41,7 +41,7 @@ EXPOSE 9100
 
 ENV BROKER_USERNAME="fda"
 ENV BROKER_PASSWORD="fda"
-ENV BROKER_LOGIN_URL="/broker/"
+ENV BROKER_LOGIN_URL="/admin/broker/"
 ENV KEYCLOAK_LOGIN_URL="/api/auth/"
 ENV SHARED_FILESYSTEM="/tmp"
 ENV LOGO="/logo.png"
diff --git a/dbrepo-ui/config.js b/dbrepo-ui/config.js
index 1ccca7b563eec4b1a6cf57d9325cb53b30fb229c..29847aaebe790ef5cdcc825951b8496496931eeb 100644
--- a/dbrepo-ui/config.js
+++ b/dbrepo-ui/config.js
@@ -1,21 +1,21 @@
 const config = {}
 
-config.title = process.env.TITLE || null
-config.icon = process.env.ICON || null
-config.brokerUsername = process.env.BROKER_USERNAME || null
-config.brokerPassword = process.env.BROKER_PASSWORD || null
-config.brokerLoginUrl = process.env.BROKER_LOGIN_URL || null
-config.keycloakLoginUrl = process.env.KEYCLOAK_LOGIN_URL || null
-config.sharedFilesystem = process.env.SHARED_FILESYSTEM || null
-config.version = process.env.VERSION || null
-config.logo = process.env.LOGO || null
-config.tokenMax = process.env.TOKEN_MAX || null
-config.searchUsername = process.env.SEARCH_USERNAME || null
-config.searchPassword = process.env.SEARCH_PASSWORD || null
-config.clientId = process.env.DBREPO_CLIENT_ID || null
-config.clientSecret = process.env.DBREPO_CLIENT_SECRET || null
-config.defaultPublisher = process.env.DEFAULT_PID_PUBLISHER || null
-config.doiUrl = process.env.DOI_URL || null
-config.uploadPath = process.env.UPLOAD_PATH || null
+config.title = process.env.TITLE
+config.icon = process.env.ICON
+config.brokerUsername = process.env.BROKER_USERNAME
+config.brokerPassword = process.env.BROKER_PASSWORD
+config.brokerLoginUrl = process.env.BROKER_LOGIN_URL
+config.keycloakLoginUrl = process.env.KEYCLOAK_LOGIN_URL
+config.sharedFilesystem = process.env.SHARED_FILESYSTEM
+config.version = process.env.VERSION
+config.logo = process.env.LOGO
+config.tokenMax = process.env.TOKEN_MAX
+config.searchUsername = process.env.SEARCH_USERNAME
+config.searchPassword = process.env.SEARCH_PASSWORD
+config.clientId = process.env.DBREPO_CLIENT_ID
+config.clientSecret = process.env.DBREPO_CLIENT_SECRET
+config.defaultPublisher = process.env.DEFAULT_PID_PUBLISHER
+config.doiUrl = process.env.DOI_URL
+config.uploadPath = process.env.UPLOAD_PATH
 
 module.exports = config
diff --git a/dbrepo-ui/package.json b/dbrepo-ui/package.json
index 61548c8c365411c283009ea84c387b58ec219161..d9fc5ed0314786876d03ee1fe8f4fb74fcd94f64 100644
--- a/dbrepo-ui/package.json
+++ b/dbrepo-ui/package.json
@@ -3,7 +3,7 @@
   "version": "1.0.0",
   "private": true,
   "scripts": {
-    "dev": "NODE_ENV=development nuxt --port 3001",
+    "dev": "NODE_ENV=development nuxt --dotenv ../.env --port 3001",
     "docker": "nuxt > /dev/null",
     "build": "nuxt build",
     "start": "nuxt start",
diff --git a/dbrepo-ui/pages/login.vue b/dbrepo-ui/pages/login.vue
index 4ffb24e8e72363cb563a02d83745a175b48612c0..fe6ce6651a514c5a2c904b6e8e623eeb64ae873d 100644
--- a/dbrepo-ui/pages/login.vue
+++ b/dbrepo-ui/pages/login.vue
@@ -51,19 +51,16 @@
             Login
           </v-btn>
         </v-card-actions>
+        <v-card-subtitle class="text-right">
+          <a v-if="rabbitMqUrl" class="mr-1" :href="rabbitMqUrl" target="_blank">
+            RabbitMQ Admin <sup><v-icon color="primary" x-small>mdi-open-in-new</v-icon></sup>
+          </a>
+          <a v-if="keycloakUrl" class="ml-1" :href="keycloakUrl" target="_blank">
+            Keycloak Admin <sup><v-icon color="primary" x-small>mdi-open-in-new</v-icon></sup>
+          </a>
+        </v-card-subtitle>
       </v-card>
     </v-form>
-    <v-toolbar v-if="!token" flat>
-      <v-spacer />
-      <v-toolbar-title>
-        <v-btn v-if="rabbitMqUrl" color="orange" plain :href="rabbitMqUrl">
-          <v-icon left>mdi-rabbit</v-icon> RabbitMQ
-        </v-btn>
-        <v-btn v-if="keycloakUrl" color="secondary" plain :href="keycloakUrl">
-          <v-icon left>mdi-key</v-icon> Keycloak
-        </v-btn>
-      </v-toolbar-title>
-    </v-toolbar>
   </div>
 </template>
 
diff --git a/docker-compose.yml b/docker-compose.yml
index bd8b3eb5e6173903aa54ea3a4290f3491718769e..4cbbac46746c4affcd1c5664ae558887e3d0d50f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -47,7 +47,7 @@ services:
       MARIADB_DATABASE: "${METADATA_DB:-fda}"
       MARIADB_ROOT_PASSWORD: "${METADATA_PASSWORD:-dbrepo}"
     healthcheck:
-      test: mysqladmin ping --user="$METADATA_USERNAME" --password="$METADATA_PASSWORD" --silent
+      test: mysqladmin ping --user="${METADATA_USERNAME:-root}" --password="${METADATA_PASSWORD:-dbrepo}" --silent
       interval: 10s
       timeout: 5s
       retries: 12
@@ -70,7 +70,7 @@ services:
     environment:
       MARIADB_ROOT_PASSWORD: "${USER_DB_PASSWORD:-dbrepo}"
     healthcheck:
-      test: mysqladmin ping --user="$USER_DB_USERNAME" --password="$USER_DB_PASSWORD" --silent
+      test: mysqladmin ping --user="${USER_DB_USERNAME:-root}" --password="${USER_DB_PASSWORD:-dbrepo}" --silent
       interval: 10s
       timeout: 5s
       retries: 12
@@ -93,7 +93,7 @@ services:
       MARIADB_DATABASE: "${AUTH_DB:-keycloak}"
       MARIADB_ROOT_PASSWORD: "${AUTH_PASSWORD:-dbrepo}"
     healthcheck:
-      test: mysqladmin ping --user="$AUTH_USERNAME" --password="$AUTH_PASSWORD" --silent
+      test: mysqladmin ping --user="${AUTH_USERNAME:-root}" --password="${AUTH_PASSWORD:-dbrepo}" --silent
       interval: 10s
       timeout: 5s
       retries: 12
@@ -157,13 +157,13 @@ 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}"
       EARLIEST_DATESTAMP: "${EARLIEST_DATESTAMP:-2022-09-17T18:23:00Z}"
       GRANULARITY: "${GRANULARITY:-YYYY-MM-DDThh:mm:ssZ}"
-      JWT_ISSUER: "${JWT_ISSUER:-http://localhost/realms/dbrepo}"
+      JWT_ISSUER: "${JWT_ISSUER:-http://localhost/api/auth/realms/dbrepo}"
       JWT_PUBKEY: "${JWT_PUBKEY:-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQAB}"
       LOG_LEVEL: "${LOG_LEVEL:-debug}"
       METADATA_DB: "${METADATA_DB:-fda}"
@@ -223,6 +223,11 @@ services:
     ports:
       - "5672:5672"
       - "15672:15672"
+    healthcheck:
+      test: wget -qO- localhost:15672/admin/broker | grep "RabbitMQ" || exit 1
+      interval: 10s
+      timeout: 5s
+      retries: 12
     depends_on:
       dbrepo-authentication-service:
         condition: service_healthy
@@ -273,8 +278,8 @@ services:
     environment:
       BROKER_USERNAME: "${BROKER_USERNAME:-fda}"
       BROKER_PASSWORD: "${BROKER_PASSWORD:-fda}"
-      BROKER_LOGIN_URL: "${BROKER_LOGIN_URL:-/broker/}"
-      KEYCLOAK_LOGIN_URL: "${KEYCLOAK_LOGIN_URL:-/api/auth/}"
+      BROKER_LOGIN_URL: "${BROKER_LOGIN_URL:-/admin/broker/}"
+      KEYCLOAK_LOGIN_URL: "${KEYCLOAK_LOGIN_URL:-/api/auth/admin/}"
       SHARED_FILESYSTEM: "${SHARED_FILESYSTEM:-/tmp}"
       LOGO: "${LOGO:-/logo.png}"
       SEARCH_USERNAME: "${SEARCH_USERNAME:-admin}"