diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml
index 0f675e47eb507fa1d2c6691f6e7708d4ffc414fd..f637eb4f8b30d5fa1d6d018ad7f692c61ec7d7e6 100644
--- a/.docker/docker-compose.yml
+++ b/.docker/docker-compose.yml
@@ -114,7 +114,7 @@ services:
     init: true
     restart: "no"
     container_name: dbrepo-auth-service-init
-    image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.6.4
     environment:
       AUTH_SERVICE_ADMIN: ${AUTH_SERVICE_ADMIN:-admin}
       AUTH_SERVICE_ADMIN_PASSWORD: ${AUTH_SERVICE_ADMIN_PASSWORD:-admin}
@@ -135,7 +135,7 @@ services:
     restart: "no"
     container_name: dbrepo-metadata-service
     hostname: metadata-service
-    image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.6.4
     volumes:
       - "${SHARED_VOLUME:-/tmp}:/tmp"
     environment:
@@ -198,7 +198,7 @@ services:
     restart: "no"
     container_name: dbrepo-analyse-service
     hostname: analyse-service
-    image: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.6.4
     environment:
       AUTH_SERVICE_CLIENT: ${AUTH_SERVICE_CLIENT:-dbrepo-client}
       AUTH_SERVICE_CLIENT_SECRET: ${AUTH_SERVICE_CLIENT:-MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG}
@@ -253,7 +253,7 @@ services:
     restart: "no"
     container_name: dbrepo-search-db
     hostname: search-db
-    image: registry.datalab.tuwien.ac.at/dbrepo/search-db:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/search-db:1.6.4
     healthcheck:
       test: curl -sSL localhost:9200/_plugins/_security/health | jq .status | grep UP
       interval: 10s
@@ -277,7 +277,7 @@ services:
     restart: "no"
     container_name: dbrepo-search-service
     hostname: search-service
-    image: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.6.4
     environment:
       AUTH_SERVICE_CLIENT: ${AUTH_SERVICE_CLIENT:-dbrepo-client}
       AUTH_SERVICE_CLIENT_SECRET: ${AUTH_SERVICE_CLIENT_SECRET:-MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG}
@@ -301,7 +301,7 @@ services:
     restart: "no"
     container_name: dbrepo-ui
     hostname: ui
-    image: registry.datalab.tuwien.ac.at/dbrepo/ui:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/ui:1.6.4
     environment:
       NUXT_PUBLIC_API_CLIENT: "${BASE_URL:-http://localhost}"
       NUXT_PUBLIC_API_SERVER: "${BASE_URL:-http://gateway-service}"
@@ -381,7 +381,7 @@ services:
     init: true
     container_name: dbrepo-search-service-init
     hostname: search-service-init
-    image: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.6.4
     environment:
       LOG_LEVEL: ${LOG_LEVEL:-info}
       METADATA_SERVICE_ENDPOINT: ${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}
@@ -438,7 +438,7 @@ services:
     restart: "no"
     container_name: dbrepo-dashboard-service
     hostname: dashboard-service
-    image: registry.datalab.tuwien.ac.at/dbrepo/dashboard-service:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/dashboard-service:1.6.4
     ports:
       - "3000:3000"
     volumes:
@@ -465,7 +465,7 @@ services:
     init: true
     container_name: dbrepo-storage-service-init
     hostname: storage-service-init
-    image: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.6.4
     environment:
       S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-seaweedfsadmin}
       S3_BUCKET: "${S3_BUCKET:-dbrepo}"
@@ -511,7 +511,7 @@ services:
     restart: "no"
     container_name: dbrepo-data-service
     hostname: data-service
-    image: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.7.0
+    image: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.6.4
     volumes:
       - "${SHARED_VOLUME:-/tmp}:/tmp"
     environment:
diff --git a/.docs/.openapi/api.base.yaml b/.docs/.openapi/api.base.yaml
index abadb218e7fa3b74a11caea3b01d3f73f2fa988a..f37d861b0955c50fd655e671716e0484d2d0502d 100644
--- a/.docs/.openapi/api.base.yaml
+++ b/.docs/.openapi/api.base.yaml
@@ -11,7 +11,7 @@ components:
       type: http
 externalDocs:
   description: Project Website
-  url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/
+  url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/
 info:
   contact:
     email: andreas.rauber@tuwien.ac.at
@@ -24,7 +24,7 @@ info:
     name: Apache 2.0
     url: https://www.apache.org/licenses/LICENSE-2.0
   title: DBRepo REST API
-  version: 1.7.0
+  version: 1.6.4
 openapi: 3.1.0
 servers:
   - description: Test Instance
diff --git a/.docs/changelog.md b/.docs/changelog.md
index efdb4dd291dbbc3194ffc3ec3168ed71befffee3..e1452dd12c4d6a6de98438087f61a1853e90779f 100644
--- a/.docs/changelog.md
+++ b/.docs/changelog.md
@@ -2,6 +2,17 @@
 author: Martin Weise
 ---
 
+## v1.6.4 (2025-02-13)
+
+[:simple-gitlab: GitLab Release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.6.4)
+
+### What's Changed
+
+#### Fixes
+
+* Fixed a bug where the users were not synced with the Metadata Database and the API Password was not recommended on 
+  first login in [#489](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/489).
+
 ## v1.6.3 (2025-02-05)
 
 [:simple-gitlab: GitLab Release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.6.3)
diff --git a/.docs/index.md b/.docs/index.md
index aa9c6e7693f3758fadcddbe05cd5904c5e92b7da..cf54cf46ccafc0bbf5c3d15b7d4c3e25b0c4975d 100644
--- a/.docs/index.md
+++ b/.docs/index.md
@@ -14,7 +14,7 @@ author: Martin Weise
 ![Maintainability Rating](./images/maintainability.svg)
 ![Security Rating](./images/security.svg)
 
-Documentation for version: [v1.7.0](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/releases).
+Documentation for version: [v1.6.4](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/releases).
 
 DBRepo is a repository for data in databases that are used from the beginning until the end of a research 
 project supporting data evolution, -citation and -versioning. It implements the query store of the 
diff --git a/.docs/kubernetes.md b/.docs/kubernetes.md
index 68f9bc16c1190a7f5d9827028d57757432aeb17d..ea377171d37d2538502faa3a65a61309681c3f16 100644
--- a/.docs/kubernetes.md
+++ b/.docs/kubernetes.md
@@ -14,7 +14,7 @@ helm upgrade --install dbrepo \
   -n dbrepo \
   "oci://registry.datalab.tuwien.ac.at/dbrepo/helm/dbrepo" \
   --values ./values.yaml \
-  --version "1.7.0" \
+  --version "1.6.4" \
   --create-namespace \
   --cleanup-on-fail
 ```
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b20acd3f2a029594345b6992ef7deb625a608513..74cfb6df9a689e5a4a70469369c11a9da34cf8ea 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,9 +9,9 @@ variables:
   NODE_VERSION: "18"
   SONARQUBE_VERSION: "10.0"
   BUN_VERSION: "1.1.40"
-  DOC_VERSION: "1.7"
-  APP_VERSION: "1.7.0"
-  CHART_VERSION: "1.7.0"
+  DOC_VERSION: "1.6"
+  APP_VERSION: "1.6.4"
+  CHART_VERSION: "1.6.4"
   CACHE_FALLBACK_KEY: "${CI_DEFAULT_BRANCH}"
   # This will supress any download for dependencies and plugins or upload messages which would clutter the console log.
   # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
diff --git a/Makefile b/Makefile
index e8f2553784f38ea5e656d776e34043886ed1ed4c..c81307ab1f26f6d77a1457301b764e751d7e837f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 .PHONY: all
 
-APP_VERSION ?= 1.7.0
-CHART_VERSION ?= 1.7.0
+APP_VERSION ?= 1.6.4
+CHART_VERSION ?= 1.6.4
 REPOSITORY_URL ?= registry.datalab.tuwien.ac.at/dbrepo
 
 .PHONY: all
diff --git a/README.md b/README.md
index 901d24dd06dd2863da84c5622f9aa8b157462171..628da3f3f3335717b5b4e0962a6ff45d36fed420 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ If you have [Docker](https://docs.docker.com/engine/install/) already installed
 with:
 
 ```bash
-curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/release-1.7/install.sh | bash
+curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/release-1.6/install.sh | bash
 ```
 
 ## Documentation
diff --git a/dbrepo-analyse-service/Pipfile b/dbrepo-analyse-service/Pipfile
index 6b144eec80011a340dbbaabc0c3bce5894e3c654..3d7911147c825d17bebf78e8f5aeaa64050c7eb0 100644
--- a/dbrepo-analyse-service/Pipfile
+++ b/dbrepo-analyse-service/Pipfile
@@ -21,7 +21,7 @@ numpy = "*"
 pandas = "*"
 minio = "*"
 pydantic = "*"
-dbrepo = {path = "./lib/dbrepo-1.7.0.tar.gz"}
+dbrepo = {path = "./lib/dbrepo-1.6.4.tar.gz"}
 opensearch-py = "*"
 
 [dev-packages]
diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock
index 83ed8a674de78d5f8c89365a355b19261abbada0..c3a282c98512ad5c6dd6d1bed525bf3b3060827b 100644
--- a/dbrepo-analyse-service/Pipfile.lock
+++ b/dbrepo-analyse-service/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "0af9d522f713554dd7996401992cffddf372ade320c11d7950bdcd5888aa1a03"
+            "sha256": "b24e4e03891018663e2746e2dbe5a9fe716f823be5ccb310c90e8e68b9ffd1d5"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -180,20 +180,20 @@
         },
         "boto3": {
             "hashes": [
-                "sha256:59bcf0c4b04d9cc36f8b418ad17ab3c4a99a21a175d2fad7096aa21cbe84630b",
-                "sha256:5ecae20e780a3ce9afb3add532b61c466a8cb8960618e4fa565b3883064c1346"
+                "sha256:7784590369a9d545bb07b2de56b6ce4d5a5e232883a957f704c3f842caeba155",
+                "sha256:8c2c2a4ccdfe35dd2611ee1b7473dd2383948415c777e42dc4e7f1ebe371fe8c"
             ],
             "index": "pypi",
             "markers": "python_version >= '3.8'",
-            "version": "==1.36.17"
+            "version": "==1.36.19"
         },
         "botocore": {
             "hashes": [
-                "sha256:069858b2fd693548035d7fd53a774e37e4260fea64e0ac9b8a3aee904f9321df",
-                "sha256:cec13e0a7ce78e71aad0b397581b4e81824c7981ef4c261d2e296d200c399b09"
+                "sha256:98882c106fec4c08678ea028199f7f5119550fab95d682b30846f7aae04b7bec",
+                "sha256:cdf6729f601f82b1acdb9004b1f88b57cfb470f576394cdb3bbf5150f7fafb5b"
             ],
             "markers": "python_version >= '3.8'",
-            "version": "==1.36.17"
+            "version": "==1.36.19"
         },
         "certifi": {
             "hashes": [
@@ -421,9 +421,9 @@
         },
         "dbrepo": {
             "hashes": [
-                "sha256:f25d5adbd618bf2906578e671af2bf3bcc24d738ef8bc791c220e7e5b714e2f7"
+                "sha256:a518aee79540d9e302b161e7e10072f50730489da19368f00a1e68204009ce44"
             ],
-            "path": "./lib/dbrepo-1.7.0.tar.gz"
+            "path": "./lib/dbrepo-1.6.4.tar.gz"
         },
         "events": {
             "hashes": [
@@ -1621,7 +1621,7 @@
                 "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df",
                 "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"
             ],
-            "markers": "python_version >= '3.10'",
+            "markers": "python_version >= '3.9'",
             "version": "==2.3.0"
         },
         "werkzeug": {
@@ -2246,7 +2246,7 @@
                 "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df",
                 "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"
             ],
-            "markers": "python_version >= '3.10'",
+            "markers": "python_version >= '3.9'",
             "version": "==2.3.0"
         },
         "wrapt": {
diff --git a/dbrepo-analyse-service/lib/dbrepo-1.6.4-py3-none-any.whl b/dbrepo-analyse-service/lib/dbrepo-1.6.4-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..d083b0bafc937528fdcc09634c41132578cbf345
Binary files /dev/null and b/dbrepo-analyse-service/lib/dbrepo-1.6.4-py3-none-any.whl differ
diff --git a/dbrepo-analyse-service/lib/dbrepo-1.6.4.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.6.4.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..87e9a503ebc621238ebe7efca15f2bdf0a6e1a85
Binary files /dev/null and b/dbrepo-analyse-service/lib/dbrepo-1.6.4.tar.gz differ
diff --git a/dbrepo-auth-service/dbrepo-realm.json b/dbrepo-auth-service/dbrepo-realm.json
index 1c703b83750c5aa21d4da06c7895d74211122ae9..bac2ddc9782822da0fac897c7bbc9a2f8ae84ed6 100644
--- a/dbrepo-auth-service/dbrepo-realm.json
+++ b/dbrepo-auth-service/dbrepo-realm.json
@@ -1475,6 +1475,39 @@
         "claim.name" : "language",
         "jsonType.label" : "String"
       }
+    }, {
+      "id" : "9bdc3e60-09b8-4241-915e-29f083434026",
+      "name" : "provider",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "user.session.note" : "identity_provider",
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "id.token.claim" : "true",
+        "lightweight.claim" : "false",
+        "access.token.claim" : "true",
+        "claim.name" : "identity_provider",
+        "jsonType.label" : "String",
+        "access.tokenResponse.claim" : "false"
+      }
+    }, {
+      "id" : "e567cb5c-8856-4124-8b86-f19cd53d7c71",
+      "name" : "setup_finished",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "SETUP_FINISHED",
+        "id.token.claim" : "true",
+        "lightweight.claim" : "false",
+        "access.token.claim" : "true",
+        "claim.name" : "setup_finished",
+        "jsonType.label" : "boolean"
+      }
     }, {
       "id" : "b817424d-7f91-43d8-b7d0-6a32582377fb",
       "name" : "family name",
@@ -2376,7 +2409,7 @@
       "subType" : "anonymous",
       "subComponents" : { },
       "config" : {
-        "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper" ]
+        "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper" ]
       }
     }, {
       "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1",
@@ -2402,7 +2435,7 @@
       "subType" : "authenticated",
       "subComponents" : { },
       "config" : {
-        "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-address-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper" ]
+        "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-role-list-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "oidc-address-mapper" ]
       }
     } ],
     "org.keycloak.userprofile.UserProfileProvider" : [ {
@@ -2426,8 +2459,8 @@
           "config" : {
             "ldap.attribute" : [ "createTimestamp" ],
             "is.mandatory.in.ldap" : [ "false" ],
-            "always.read.value.from.ldap" : [ "true" ],
             "read.only" : [ "true" ],
+            "always.read.value.from.ldap" : [ "true" ],
             "user.model.attribute" : [ "createTimestamp" ]
           }
         }, {
@@ -2438,8 +2471,8 @@
           "config" : {
             "ldap.attribute" : [ "sn" ],
             "is.mandatory.in.ldap" : [ "true" ],
-            "read.only" : [ "false" ],
             "always.read.value.from.ldap" : [ "true" ],
+            "read.only" : [ "false" ],
             "user.model.attribute" : [ "lastName" ]
           }
         }, {
@@ -2450,8 +2483,8 @@
           "config" : {
             "ldap.attribute" : [ "cn" ],
             "is.mandatory.in.ldap" : [ "true" ],
-            "always.read.value.from.ldap" : [ "true" ],
             "read.only" : [ "false" ],
+            "always.read.value.from.ldap" : [ "true" ],
             "user.model.attribute" : [ "firstName" ]
           }
         }, {
@@ -2462,8 +2495,8 @@
           "config" : {
             "ldap.attribute" : [ "mail" ],
             "is.mandatory.in.ldap" : [ "false" ],
-            "always.read.value.from.ldap" : [ "false" ],
             "read.only" : [ "false" ],
+            "always.read.value.from.ldap" : [ "false" ],
             "user.model.attribute" : [ "email" ]
           }
         }, {
@@ -2476,15 +2509,15 @@
             "membership.attribute.type" : [ "DN" ],
             "user.roles.retrieve.strategy" : [ "LOAD_GROUPS_BY_MEMBER_ATTRIBUTE" ],
             "group.name.ldap.attribute" : [ "cn" ],
-            "membership.user.ldap.attribute" : [ "uid" ],
-            "ignore.missing.groups" : [ "false" ],
             "preserve.group.inheritance" : [ "false" ],
             "membership.ldap.attribute" : [ "member" ],
-            "memberof.ldap.attribute" : [ "memberOf" ],
-            "group.object.classes" : [ "groupOfNames" ],
+            "ignore.missing.groups" : [ "false" ],
+            "membership.user.ldap.attribute" : [ "uid" ],
             "groups.dn" : [ "ou=users,dc=dbrepo,dc=at" ],
-            "groups.path" : [ "/" ],
-            "drop.non.existing.groups.during.sync" : [ "false" ]
+            "group.object.classes" : [ "groupOfNames" ],
+            "memberof.ldap.attribute" : [ "memberOf" ],
+            "drop.non.existing.groups.during.sync" : [ "false" ],
+            "groups.path" : [ "/" ]
           }
         }, {
           "id" : "b6ff3285-35af-4e86-8bb4-d94b8e0d70bb",
@@ -2518,8 +2551,8 @@
         "fullSyncPeriod" : [ "-1" ],
         "pagination" : [ "false" ],
         "startTls" : [ "false" ],
-        "connectionPooling" : [ "true" ],
         "usersDn" : [ "ou=users,dc=dbrepo,dc=at" ],
+        "connectionPooling" : [ "true" ],
         "cachePolicy" : [ "DEFAULT" ],
         "useKerberosForPasswordAuthentication" : [ "false" ],
         "importEnabled" : [ "true" ],
@@ -2531,8 +2564,8 @@
         "lastSync" : [ "1719252666" ],
         "vendor" : [ "other" ],
         "uuidLDAPAttribute" : [ "entryUUID" ],
-        "allowKerberosAuthentication" : [ "false" ],
         "connectionUrl" : [ "ldap://identity-service:1389" ],
+        "allowKerberosAuthentication" : [ "false" ],
         "syncRegistrations" : [ "true" ],
         "authType" : [ "simple" ],
         "useTruststoreSpi" : [ "always" ],
diff --git a/dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java
index 769ec49097223e5fd49f76d855d9acef1cfbe35c..c63e88618b792f4d85e52b4aee55c80e1a2f1db8 100644
--- a/dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java
+++ b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/Client.java
@@ -31,8 +31,7 @@ public class Client {
             if (systemPassword == null || systemPassword.isEmpty()) {
                 throw new IllegalArgumentException("Environment variable SYSTEM_PASSWORD is not set or is empty.");
             }
-
-            URL url = URI.create(urlString).toURL();
+            final URL url = URI.create(urlString + "/api/user").toURL();
             HttpURLConnection conn = (HttpURLConnection) url.openConnection();
             conn.setDoOutput(true);
             conn.setRequestMethod("POST");
diff --git a/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java
index 93f2b2919b81940e8803b8b451c5388163f7d5dd..ea4aa7794b6f26167da704e4c12057cf9d8c5c42 100644
--- a/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java
+++ b/dbrepo-auth-service/listeners/src/main/java/at/tuwien/CreateEventListenerProvider.java
@@ -57,7 +57,6 @@ public class CreateEventListenerProvider implements EventListenerProvider {
         final String userData = "{" +
                 quoteAttr("id", user.getId()) + ", " +
                 quoteAttr("username", user.getUsername()) + ", " +
-                quoteAttr("email", user.getEmail()) + ", " +
                 quoteAttr("ldap_id", user.getFirstAttribute("LDAP_ID")) + ", " +
                 quoteAttr("given_name", user.getFirstName()) + ", " +
                 quoteAttr("family_name", user.getLastName()) +
diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar
index a23243d39509ec3821219e5799a25740c93e2ca1..a970096eeaa5015d9e95064f6b341fffdf8aae5f 100644
Binary files a/dbrepo-auth-service/listeners/target/create-event-listener.jar and b/dbrepo-auth-service/listeners/target/create-event-listener.jar differ
diff --git a/dbrepo-data-service/pom.xml b/dbrepo-data-service/pom.xml
index db7947432e3f6117bfe8d888a47e7b6d176b66ab..0e2001b9319f1d755eca5f3f6dbe6335b1cbede3 100644
--- a/dbrepo-data-service/pom.xml
+++ b/dbrepo-data-service/pom.xml
@@ -11,7 +11,7 @@
     <groupId>at.tuwien</groupId>
     <artifactId>dbrepo-data-service</artifactId>
     <name>dbrepo-data-service</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <description>Service that manages the data</description>
 
diff --git a/dbrepo-data-service/querystore/pom.xml b/dbrepo-data-service/querystore/pom.xml
index 1aa138f611c7fa5ec2fc4f6dc98beb8a177f24b5..0c01d6893c9d39bfea9890b2a848030d0373146f 100644
--- a/dbrepo-data-service/querystore/pom.xml
+++ b/dbrepo-data-service/querystore/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-data-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-data-service-querystore</artifactId>
     <name>dbrepo-data-service-querystore</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies/>
 
diff --git a/dbrepo-data-service/report/pom.xml b/dbrepo-data-service/report/pom.xml
index 98536501d3beb70b5c05f632e673a401b03ae2cd..ed4826a38d5aa6f820914db64def695882261d9c 100644
--- a/dbrepo-data-service/report/pom.xml
+++ b/dbrepo-data-service/report/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-data-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>report</artifactId>
     <name>dbrepo-data-service-report</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
     <description>
         This module is only intended for the pipeline coverage report. See the detailed report in the
         respective modules
diff --git a/dbrepo-data-service/rest-service/pom.xml b/dbrepo-data-service/rest-service/pom.xml
index 434c423ef056566305e2d72db984781e7b1429fc..836782387040df14680ade1af7b49f2fffb10895 100644
--- a/dbrepo-data-service/rest-service/pom.xml
+++ b/dbrepo-data-service/rest-service/pom.xml
@@ -6,18 +6,18 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-data-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>rest-service</artifactId>
     <name>dbrepo-data-service-rest-service</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
             <groupId>at.tuwien</groupId>
             <artifactId>services</artifactId>
-            <version>1.7.0</version>
+            <version>1.6.4</version>
         </dependency>
     </dependencies>
 
diff --git a/dbrepo-data-service/services/pom.xml b/dbrepo-data-service/services/pom.xml
index 5252e6a3d30439671d085b9ac2d6bca81bf462c0..3f645dda320c2774eba62b273c5f851f7a3b3e8d 100644
--- a/dbrepo-data-service/services/pom.xml
+++ b/dbrepo-data-service/services/pom.xml
@@ -6,18 +6,18 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-data-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>services</artifactId>
     <name>dbrepo-data-service-services</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
             <groupId>at.tuwien</groupId>
             <artifactId>dbrepo-data-service-querystore</artifactId>
-            <version>1.7.0</version>
+            <version>1.6.4</version>
         </dependency>
     </dependencies>
 
diff --git a/dbrepo-metadata-service/api/pom.xml b/dbrepo-metadata-service/api/pom.xml
index 6c3b1aa13fbe0ccac21e0e0ce1ede0a78e6f340d..3f68887ec008b41db2d0afe027ce3d65eaa8a7d1 100644
--- a/dbrepo-metadata-service/api/pom.xml
+++ b/dbrepo-metadata-service/api/pom.xml
@@ -6,18 +6,18 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-api</artifactId>
     <name>dbrepo-metadata-service-api</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
             <groupId>at.tuwien</groupId>
             <artifactId>dbrepo-metadata-service-entities</artifactId>
-            <version>1.7.0</version>
+            <version>1.6.4</version>
             <scope>compile</scope>
         </dependency>
     </dependencies>
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java
index 16f45aec4d625639f1188e0e853b3a81bd71811f..9742986ae08df9f9d00f5c1bc9da15b245bad8fc 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java
@@ -40,7 +40,4 @@ public class CreateUserDto {
     @Schema(example = "bar")
     private String familyName;
 
-    @Schema(example = "foo.bar@example.com")
-    private String email;
-
 }
diff --git a/dbrepo-metadata-service/entities/pom.xml b/dbrepo-metadata-service/entities/pom.xml
index 313309e18831501558a149cab52920bb90e89e91..382fa2e7e81dcd2629b0c4cc3c25b8bce3364b4f 100644
--- a/dbrepo-metadata-service/entities/pom.xml
+++ b/dbrepo-metadata-service/entities/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-entities</artifactId>
     <name>dbrepo-metadata-service-entity</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies/>
 
diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java
index ba86e3d29c6913d45d51ae0498fdac8d3092b657..156fc3b4c8efbd44e4d8389b50a7cb0f65814aac 100644
--- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java
+++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java
@@ -65,7 +65,7 @@ public class User {
     @Column(name = "mariadb_password", nullable = false)
     private String mariadbPassword;
 
-    @Column(name = "is_internal", nullable = false, updatable = false)
+    @Column(name = "is_internal", nullable = false, updatable = false, columnDefinition = "bool default false")
     private Boolean isInternal;
 
 }
diff --git a/dbrepo-metadata-service/oai/pom.xml b/dbrepo-metadata-service/oai/pom.xml
index 54c464b11a31cea0e588f797fa38012c573a1d02..76beb8d88f596107f16e135c7aa17cedd5fb2d2b 100644
--- a/dbrepo-metadata-service/oai/pom.xml
+++ b/dbrepo-metadata-service/oai/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-oai</artifactId>
     <name>dbrepo-metadata-service-oai</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies/>
 
diff --git a/dbrepo-metadata-service/pom.xml b/dbrepo-metadata-service/pom.xml
index d64da973f01777505b79c85232aac253494a52b6..ae5c004e0cbdb64c3adac5d091e39cafd5376ad7 100644
--- a/dbrepo-metadata-service/pom.xml
+++ b/dbrepo-metadata-service/pom.xml
@@ -11,7 +11,7 @@
     <groupId>at.tuwien</groupId>
     <artifactId>dbrepo-metadata-service</artifactId>
     <name>dbrepo-metadata-service</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <description>Service that manages the metadata</description>
 
diff --git a/dbrepo-metadata-service/report/pom.xml b/dbrepo-metadata-service/report/pom.xml
index 6bcb8d579b67439ad4bcd590cf5af3819f70218e..be6e86a4d08965220aaf87d6ec93b8162514f943 100644
--- a/dbrepo-metadata-service/report/pom.xml
+++ b/dbrepo-metadata-service/report/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-report</artifactId>
     <name>dbrepo-metadata-service-report</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
diff --git a/dbrepo-metadata-service/repositories/pom.xml b/dbrepo-metadata-service/repositories/pom.xml
index 4d3b5f933d2c39674b2f9e58461387c0a2cffdb8..cf327942a45f9efeb7e8e06374ffdec8c443fa4c 100644
--- a/dbrepo-metadata-service/repositories/pom.xml
+++ b/dbrepo-metadata-service/repositories/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-repositories</artifactId>
     <name>dbrepo-metadata-service-repositories</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
diff --git a/dbrepo-metadata-service/rest-service/pom.xml b/dbrepo-metadata-service/rest-service/pom.xml
index 9e9f23d11fdbab4fc2308bead597a7626272ceb1..e1524f79715ffbd081c170257c1ab295d45a5052 100644
--- a/dbrepo-metadata-service/rest-service/pom.xml
+++ b/dbrepo-metadata-service/rest-service/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-rest-service</artifactId>
     <name>dbrepo-metadata-service-rest</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
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 50016103d83ccfffab65ddc153e6b88074e34e2c..41cc59ca6ad3aa8b3a74bf3ae5eda482231863be 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
@@ -511,19 +511,26 @@ public class DatabaseEndpoint extends AbstractEndpoint {
                     .stream()
                     .filter(a -> a.getUser().getId().equals(getId(principal)))
                     .findFirst();
+            optional.ifPresentOrElse(access -> log.trace("user has access: {}", access), () -> log.trace("user has no access"));
             if (!database.getIsPublic() && !database.getIsSchemaPublic() && optional.isEmpty() && !isSystem(principal)) {
                 log.error("Failed to find database: not public and no access found");
                 throw new NotAllowedException("Failed to find database: not public and no access found");
             }
             /* reduce metadata */
+            final int tables = database.getTables()
+                    .size();
             database.setTables(database.getTables()
                     .stream()
                     .filter(t -> t.getIsPublic() || t.getIsSchemaPublic() || optional.isPresent())
                     .toList());
+            log.trace("filtered database tables from {} to {}", tables, database.getTables().size());
+            final int views = database.getViews()
+                    .size();
             database.setViews(database.getViews()
                     .stream()
                     .filter(v -> v.getIsPublic() || v.getIsSchemaPublic() || optional.isPresent())
                     .toList());
+            log.trace("filtered database views from {} to {}", views, database.getViews().size());
             if (!isSystem(principal) && !database.getOwner().getId().equals(getId(principal))) {
                 log.trace("authenticated user {} is not owner: remove access list", principal.getName());
                 database.setAccesses(List.of());
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 51f323c30f1581314df88dab86ec2900775c215e..5ca14a5a34605e80ab48c5f2309f6dd15bea714f 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
@@ -106,47 +106,15 @@ public class UserEndpoint extends AbstractEndpoint {
             @ApiResponse(responseCode = "400",
                     description = "Parameters are not well-formed (likely email)",
                     content = {@Content(mediaType = "application/json")}),
-            @ApiResponse(responseCode = "403",
-                    description = "Internal authentication to the auth service is invalid",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Default role not found",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "409",
-                    description = "User with username already exists",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "417",
-                    description = "User with e-mail already exists",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "502",
-                    description = "Failed to create in auth service",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "503",
-                    description = "Failed to create in auth service",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
-    public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody CreateUserDto data)
-            throws UserExistsException, EmailExistsException, AuthServiceException, AuthServiceConnectionException,
-            UserNotFoundException, CredentialsInvalidException {
+    public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody CreateUserDto data) {
         log.debug("endpoint create user, data.id={}, data.username={}", data.getId(), data.getUsername());
         return ResponseEntity.status(HttpStatus.CREATED)
                 .body(userMapper.userToUserBriefDto(
                         userService.create(data)));
     }
 
-    @GetMapping("/{userId}")
+    @RequestMapping(value = "/{userId}", method = {RequestMethod.GET, RequestMethod.HEAD})
     @Transactional(readOnly = true)
     @PreAuthorize("isAuthenticated()")
     @Observed(name = "dbrepo_user_find")
@@ -181,12 +149,14 @@ public class UserEndpoint extends AbstractEndpoint {
             throw new NotAllowedException("Failed to find user: foreign user");
         }
         if (user.getIsInternal()) {
-            throw new UserNotFoundException("Failed to find user with username: " + user.getUsername());
+            log.error("Failed to find user: internal user");
+            throw new NotAllowedException("Failed to find user: internal user");
         }
         final HttpHeaders headers = new HttpHeaders();
         if (isSystem(principal)) {
             headers.set("X-Username", user.getUsername());
             headers.set("X-Password", user.getMariadbPassword());
+            headers.set("Access-Control-Expose-Headers", "X-Username X-Password");
         }
         return ResponseEntity.status(HttpStatus.OK)
                 .headers(headers)
@@ -282,18 +252,18 @@ public class UserEndpoint extends AbstractEndpoint {
                                          @NotNull @Valid @RequestBody UserPasswordDto data,
                                          @NotNull Principal principal) throws NotAllowedException,
             UserNotFoundException, DatabaseNotFoundException, DataServiceException,
-            DataServiceConnectionException {
+            DataServiceConnectionException, AuthServiceException {
         log.debug("endpoint modify a user password, userId={}, principal.name={}", userId, principal.getName());
         final User user = userService.findById(userId);
         if (!user.getUsername().equals(principal.getName())) {
             log.error("Failed to modify user password: not current user");
             throw new NotAllowedException("Failed to modify user password: not current user");
         }
-        authenticationService.updatePassword(user, data);
         for (Database database : databaseService.findAllAtLestReadAccess(userId)) {
             databaseService.updatePassword(database, user);
         }
         userService.updatePassword(user, data);
+        authenticationService.setupFinished(user);
         return ResponseEntity.accepted()
                 .build();
     }
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
index a54f616b01e61edad50d85d4b5f0d494c9e429d6..6fe29c118bd47683874cd4a92397c62317de3a83 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
@@ -131,7 +131,7 @@ public class EndpointValidator extends AbstractEndpoint {
         final Optional<CreateTableColumnDto> optional3 = data.getColumns()
                 .stream()
                 .filter(c -> c.getType().equals(ColumnTypeDto.SET))
-                .filter(c -> c.getEnums() == null || c.getSets().isEmpty())
+                .filter(c -> c.getSets() == null || c.getSets().isEmpty())
                 .findFirst();
         if (optional3.isPresent()) {
             log.error("Validation failed: column {} needs at least 1 allowed set value", optional3.get().getName());
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/ApplicationIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/ApplicationIntegrationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..33c7bc76c552c70989dbc4ffc39e317fdb5826ac
--- /dev/null
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/ApplicationIntegrationTest.java
@@ -0,0 +1,23 @@
+package at.tuwien;
+
+import lombok.extern.log4j.Log4j2;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@Log4j2
+@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
+@SpringBootTest
+@ExtendWith(SpringExtension.class)
+public class ApplicationIntegrationTest {
+
+    @Test
+    public void main_succeeds() {
+
+        /* test */
+        DbrepoMetadataServiceApplication.main(new String[]{});
+    }
+
+}
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 fd91fb5655ad563ee0b4f8503dbdb5b60db6fea9..1340d552d1b8ff3da3be847704d3d9ccd328eabc 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
@@ -269,7 +269,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
 
     @Test
     @WithAnonymousUser
-    public void list_anonymous_succeeds() throws DatabaseNotFoundException, UserNotFoundException {
+    public void list_anonymous_succeeds() {
 
         /* mock */
         when(databaseService.findAllPublicOrSchemaPublic())
@@ -281,7 +281,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
 
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = {"list-databases"})
-    public void list_hasRole_succeeds() throws DatabaseNotFoundException, UserNotFoundException {
+    public void list_hasRole_succeeds() {
 
         /* pre-condition */
         assertTrue(DATABASE_3_PUBLIC);
@@ -296,7 +296,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
 
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = {"list-databases"})
-    public void list_hasRoleForeign_succeeds() throws DatabaseNotFoundException, UserNotFoundException {
+    public void list_hasRoleForeign_succeeds() {
 
         /* pre-condition */
         assertTrue(DATABASE_3_PUBLIC);
@@ -311,7 +311,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
 
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = {"list-databases"})
-    public void list_hasRoleFilter_succeeds() throws DatabaseNotFoundException, UserNotFoundException {
+    public void list_hasRoleFilter_succeeds() {
 
         /* mock */
         when(databaseService.findAllPublicOrSchemaPublicOrReadAccessByInternalName(USER_1_ID, DATABASE_3_INTERNALNAME))
@@ -323,7 +323,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
 
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = {"list-databases"})
-    public void list_hasRoleFilterNoResult_succeeds() throws DatabaseNotFoundException, UserNotFoundException {
+    public void list_hasRoleFilterNoResult_succeeds() {
 
         /* mock */
         when(databaseService.findAllPublicOrSchemaPublicOrReadAccessByInternalName(USER_1_ID, "i_do_not_exist"))
@@ -333,6 +333,18 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
         list_generic("i_do_not_exist", USER_1_PRINCIPAL, 0);
     }
 
+    @Test
+    @WithAnonymousUser
+    public void list_filterNoResult_succeeds() {
+
+        /* mock */
+        when(databaseService.findAllPublicOrSchemaPublicByInternalName("i_do_not_exist"))
+                .thenReturn(List.of());
+
+        /* test */
+        list_generic("i_do_not_exist", null, 0);
+    }
+
     @Test
     @WithAnonymousUser
     public void visibility_anonymous_fails() {
@@ -562,15 +574,15 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
     }
 
     @Test
-    @WithAnonymousUser
-    public void findById_anonymousPrivateSchemaNoAccessSystem_succeeds() throws UserNotFoundException,
+    @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"})
+    public void findById_privateSchemaNoAccessInternalUser_succeeds() throws UserNotFoundException,
             NotAllowedException, DataServiceException, DatabaseNotFoundException, ExchangeNotFoundException,
             DataServiceConnectionException {
 
         /* test */
-        final DatabaseDto database = findById_generic(DATABASE_1_ID, DATABASE_1, USER_LOCAL_ADMIN_PRINCIPAL);
-        assertEquals(4, database.getTables().size());
-        assertEquals(2, database.getViews().size());
+        final DatabaseDto database = findById_generic(DATABASE_3_ID, DATABASE_3, USER_LOCAL_ADMIN_PRINCIPAL);
+        assertEquals(0, database.getTables().size());
+        assertEquals(1, database.getViews().size());
         assertNotEquals(0, database.getAccesses().size());
     }
 
@@ -610,6 +622,58 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
         assertEquals(3, database.getAccesses().size());
     }
 
+    @Test
+    @WithMockUser(username = USER_2_USERNAME)
+    public void findById_hiddenAccessRights_succeeds() throws DataServiceException, DataServiceConnectionException,
+            DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException {
+
+        /* mock */
+        when(accessService.list(DATABASE_1))
+                .thenReturn(List.of(DATABASE_1_USER_1_WRITE_ALL_ACCESS, DATABASE_1_USER_2_READ_ACCESS));
+
+        /* test */
+        final DatabaseDto database = findById_generic(DATABASE_1_ID, DATABASE_1, USER_2_PRINCIPAL);
+        assertEquals(4, database.getTables().size());
+        assertEquals(3, database.getViews().size());
+        assertEquals(0, database.getAccesses().size());
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME)
+    public void findById_hiddenAccessRightsSeesOwn_succeeds() throws DataServiceException, DataServiceConnectionException,
+            DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException {
+
+        /* mock */
+        when(accessService.list(DATABASE_1))
+                .thenReturn(List.of(DATABASE_1_USER_1_WRITE_ALL_ACCESS, DATABASE_1_USER_2_READ_ACCESS));
+
+        /* test */
+        final DatabaseDto database = findById_generic(DATABASE_1_ID, DATABASE_1, USER_1_PRINCIPAL);
+        assertEquals(4, database.getTables().size());
+        assertEquals(3, database.getViews().size());
+        assertEquals(3, database.getAccesses().size());
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME)
+    public void findById_privateDataPrivateSchemaNoAccess_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            findById_generic(DATABASE_1_ID, DATABASE_1, USER_4_PRINCIPAL);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME)
+    public void findById_anonymousPrivateDataPrivateSchema_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            findById_generic(DATABASE_1_ID, DATABASE_1, null);
+        });
+    }
+
     @Test
     @WithAnonymousUser
     public void findPreviewImage_anonymous_succeeds() throws DatabaseNotFoundException {
@@ -660,8 +724,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest {
     /* ## GENERIC TEST CASES                                                                            ## */
     /* ################################################################################################### */
 
-    public void list_generic(String internalName, Principal principal, Integer expectedSize)
-            throws DatabaseNotFoundException, UserNotFoundException {
+    public void list_generic(String internalName, Principal principal, Integer expectedSize) {
 
         /* test */
         final ResponseEntity<List<DatabaseBriefDto>> response = databaseEndpoint.list(internalName, principal);
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java
index a17d31649e6824442613261b91bca4ee923a4817..16551784c883cc69dfbb87504fafc504f1af7015 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java
@@ -1,12 +1,12 @@
 package at.tuwien.endpoints;
 
-import at.tuwien.api.database.table.TableBriefDto;
 import at.tuwien.api.database.table.CreateTableDto;
+import at.tuwien.api.database.table.TableBriefDto;
 import at.tuwien.api.database.table.TableDto;
 import at.tuwien.api.database.table.TableUpdateDto;
-import at.tuwien.api.database.table.columns.CreateTableColumnDto;
 import at.tuwien.api.database.table.columns.ColumnDto;
 import at.tuwien.api.database.table.columns.ColumnTypeDto;
+import at.tuwien.api.database.table.columns.CreateTableColumnDto;
 import at.tuwien.api.database.table.columns.concepts.ColumnSemanticsUpdateDto;
 import at.tuwien.api.database.table.constraints.CreateTableConstraintsDto;
 import at.tuwien.api.semantics.EntityDto;
@@ -40,6 +40,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import java.security.Principal;
 import java.util.List;
+import java.util.UUID;
 import java.util.stream.Stream;
 
 import static org.junit.jupiter.api.Assertions.*;
@@ -524,7 +525,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
     @Test
     @WithAnonymousUser
     public void findById_publicDatabasePrivateDataPrivateSchemaAnonymous_succeeds() throws UserNotFoundException,
-            TableNotFoundException, NotAllowedException, DataServiceException, DatabaseNotFoundException, AccessNotFoundException, QueueNotFoundException, DataServiceConnectionException {
+            TableNotFoundException, NotAllowedException, DataServiceException, DatabaseNotFoundException,
+            AccessNotFoundException, QueueNotFoundException, DataServiceConnectionException {
 
         /* test */
         final ResponseEntity<TableDto> response = generic_findById(DATABASE_3_ID, DATABASE_3, TABLE_8_ID, TABLE_8, null, null, null);
@@ -596,6 +598,16 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
         });
     }
 
+    @Test
+    @WithMockUser(username = USER_4_USERNAME, authorities = {"table-semantic-analyse"})
+    public void analyseTable_notOwner_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            analyseTable_generic(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1, USER_4_PRINCIPAL);
+        });
+    }
+
     @Test
     @WithMockUser(username = USER_4_USERNAME)
     public void findAll_noRole_fails() {
@@ -930,6 +942,29 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
         generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_2_ID, TABLE_2, null, null, null);
     }
 
+    @Test
+    @WithMockUser(username = USER_4_USERNAME)
+    public void findById_privateSchemaNotOwnerNoAccess_fails() {
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            generic_findById(DATABASE_3_ID, DATABASE_3, TABLE_8_ID, TABLE_8, USER_4_PRINCIPAL, USER_4, null);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_4_USERNAME)
+    public void findById_publicSchemaNotOwnerNoAccess_succeeds() throws UserNotFoundException, TableNotFoundException,
+            NotAllowedException, DataServiceException, DatabaseNotFoundException, AccessNotFoundException,
+            QueueNotFoundException, DataServiceConnectionException {
+
+        /* test */
+        final ResponseEntity<TableDto> response = generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_2_ID, TABLE_2, USER_4_PRINCIPAL, USER_4, null);
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+        final TableDto body = response.getBody();
+        assertNotNull(body);
+    }
+
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = "find-table")
     public void findById_privateHasRoleTableNotFound_fails() {
@@ -970,7 +1005,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
             AccessNotFoundException, QueueNotFoundException, DataServiceConnectionException {
 
         /* test */
-        generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1, USER_4_PRINCIPAL, USER_4, null);
+        generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1, USER_4_PRINCIPAL, USER_4, DATABASE_1_USER_4_READ_ACCESS);
     }
 
     @Test
@@ -1081,6 +1116,17 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
         assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
     }
 
+    @Test
+    @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system", "update-table-statistic"})
+    public void updateStatistic_internalUser_succeeds() throws TableNotFoundException, SearchServiceException,
+            MalformedException, NotAllowedException, DataServiceException, DatabaseNotFoundException,
+            SearchServiceConnectionException, DataServiceConnectionException {
+
+        /* test */
+        final ResponseEntity<Void> response = generic_updateStatistic(USER_LOCAL_ADMIN_PRINCIPAL);
+        assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
+    }
+
     /* ################################################################################################### */
     /* ## GENERIC TEST CASES                                                                            ## */
     /* ################################################################################################### */
@@ -1148,7 +1194,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
     }
 
     protected ResponseEntity<TableBriefDto> generic_create(Long databaseId, Database database, CreateTableDto data,
-                                                      Principal principal, User user, DatabaseAccess access)
+                                                           Principal principal, User user, DatabaseAccess access)
             throws MalformedException, NotAllowedException, DataServiceException, DataServiceConnectionException,
             UserNotFoundException, DatabaseNotFoundException, AccessNotFoundException, TableNotFoundException,
             TableExistsException, SearchServiceException, SearchServiceConnectionException, OntologyNotFoundException,
@@ -1203,11 +1249,21 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                     .when(tableService)
                     .findById(any(Database.class), eq(tableId));
         }
-        if (principal != null) {
+        if (user != null) {
             when(userService.findById(user.getId()))
                     .thenReturn(user);
-            when(accessService.find(any(Database.class), eq(user)))
+        } else {
+            doThrow(UserNotFoundException.class)
+                    .when(userService)
+                    .findById(any(UUID.class));
+        }
+        if (access != null) {
+            when(accessService.find(any(Database.class), any(User.class)))
                     .thenReturn(access);
+        } else {
+            doThrow(AccessNotFoundException.class)
+                    .when(accessService)
+                    .find(any(Database.class), any(User.class));
         }
 
         /* test */
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 6ef4bd8779f08abaaa28d68e306e0a700eebd39b..de5c8993a118471b786710a72fbc8799499d4a82 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
@@ -1,5 +1,6 @@
 package at.tuwien.endpoints;
 
+import at.tuwien.api.auth.CreateUserDto;
 import at.tuwien.api.user.UserBriefDto;
 import at.tuwien.api.user.UserDto;
 import at.tuwien.api.user.UserPasswordDto;
@@ -19,6 +20,7 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.test.context.support.WithAnonymousUser;
@@ -63,6 +65,15 @@ public class UserEndpointUnitTest extends AbstractUnitTest {
         assertEquals(2, response.size());
     }
 
+    @Test
+    @WithAnonymousUser
+    public void findAll_filterInternalUserEmptyList_succeeds() throws UserNotFoundException {
+
+        /* test */
+        final List<UserBriefDto> response = findAll_generic(USER_LOCAL_ADMIN_USERNAME, null);
+        assertEquals(0, response.size());
+    }
+
     @Test
     @WithMockUser(username = USER_1_USERNAME)
     public void findAll_noRole_succeeds() throws UserNotFoundException {
@@ -142,6 +153,18 @@ public class UserEndpointUnitTest extends AbstractUnitTest {
         assertEquals(USER_3_DATABASE_PASSWORD, response.getHeaders().get("X-Password").get(0));
     }
 
+    @Test
+    @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"})
+    public void find_internalUser_fails() {
+        final Principal principal = new UsernamePasswordAuthenticationToken(USER_LOCAL_ADMIN_DETAILS, USER_LOCAL_ADMIN_PASSWORD, List.of(
+                new SimpleGrantedAuthority("system")));
+
+        /* test */
+        assertThrows(NotAllowedException.class, () -> {
+            find_generic(USER_LOCAL_ADMIN_ID, USER_LOCAL, principal);
+        });
+    }
+
     @Test
     @WithAnonymousUser
     public void modify_anonymous_fails() {
@@ -233,7 +256,7 @@ public class UserEndpointUnitTest extends AbstractUnitTest {
     @Test
     @WithMockUser(username = USER_1_USERNAME)
     public void password_succeeds() throws NotAllowedException, DataServiceException, DataServiceConnectionException,
-            UserNotFoundException, DatabaseNotFoundException {
+            UserNotFoundException, DatabaseNotFoundException, AuthServiceException {
         final UserPasswordDto request = UserPasswordDto.builder()
                 .password(USER_1_PASSWORD)
                 .build();
@@ -242,6 +265,38 @@ public class UserEndpointUnitTest extends AbstractUnitTest {
         password_generic(USER_1_PRINCIPAL, request);
     }
 
+    @Test
+    @WithAnonymousUser
+    public void create_anonymous_fails() {
+
+        /* test */
+        assertThrows(AccessDeniedException.class, () -> {
+            generic_create(USER_1_CREATE_USER_DTO);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_2_USERNAME)
+    public void create_notInternalUser_fails() {
+
+        /* test */
+        assertThrows(AccessDeniedException.class, () -> {
+            generic_create(USER_1_CREATE_USER_DTO);
+        });
+    }
+
+    @Test
+    @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"})
+    public void create_succeeds() {
+
+        /* mock */
+        when(userService.create(USER_1_CREATE_USER_DTO))
+                .thenReturn(USER_1);
+
+        /* test */
+        generic_create(USER_1_CREATE_USER_DTO);
+    }
+
     /* ################################################################################################### */
     /* ## GENERIC TEST CASES                                                                            ## */
     /* ################################################################################################### */
@@ -260,7 +315,7 @@ public class UserEndpointUnitTest extends AbstractUnitTest {
             }
         } else {
             when(userService.findAll())
-                    .thenReturn(List.of(USER_1, USER_2));
+                    .thenReturn(List.of(USER_1, USER_2, USER_LOCAL));
         }
 
         /* test */
@@ -310,14 +365,15 @@ public class UserEndpointUnitTest extends AbstractUnitTest {
     }
 
     protected void password_generic(Principal principal, UserPasswordDto data) throws NotAllowedException,
-            DataServiceException, DataServiceConnectionException, UserNotFoundException, DatabaseNotFoundException {
+            DataServiceException, DataServiceConnectionException, UserNotFoundException, DatabaseNotFoundException,
+            AuthServiceException {
 
         /* mock */
         when(userService.findById(USER_1_ID))
                 .thenReturn(USER_1);
         doNothing()
                 .when(authenticationService)
-                .updatePassword(USER_1, data);
+                .setupFinished(USER_1);
         doNothing()
                 .when(userService)
                 .updatePassword(USER_1, data);
@@ -331,4 +387,13 @@ public class UserEndpointUnitTest extends AbstractUnitTest {
         final ResponseEntity<?> response = userEndpoint.password(USER_1_ID, data, principal);
         assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
     }
+
+    protected void generic_create(CreateUserDto data) {
+
+        /* test */
+        final ResponseEntity<UserBriefDto> response = userEndpoint.create(data);
+        assertEquals(HttpStatus.CREATED, response.getStatusCode());
+        final UserBriefDto body = response.getBody();
+        assertNotNull(body);
+    }
 }
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayIntegrationTest.java
index e72cd7fa7591a7e641c74df6eab07845b0a193ea..58701adfc34f3d8c1be0b189a857307737bcfc47 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayIntegrationTest.java
@@ -92,23 +92,4 @@ public class KeycloakGatewayIntegrationTest extends AbstractUnitTest {
         });
     }
 
-    @Test
-    public void updateUserCredentials_succeeds() throws UserNotFoundException {
-
-        /* mock */
-        keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST);
-
-        /* test */
-        keycloakGateway.updateUserCredentials(keycloakUtils.getUserId(USER_1_USERNAME), USER_1_PASSWORD_DTO);
-    }
-
-    @Test
-    public void updateUserCredentials_notFound_fails() {
-
-        /* test */
-        assertThrows(UserNotFoundException.class, () -> {
-            keycloakGateway.updateUserCredentials(keycloakUtils.getUserId(USER_1_USERNAME), USER_1_PASSWORD_DTO);
-        });
-    }
-
 }
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java
index 9075ec2a02d0420b9fe0cec8c307a9dc8ac1c13e..a58a4b49da03358371c1346b16d893ac8b51bb8e 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/handlers/ApiExceptionHandlerTest.java
@@ -1,12 +1,16 @@
 package at.tuwien.handlers;
 
+import at.tuwien.api.error.ApiErrorDto;
+import at.tuwien.exception.*;
 import at.tuwien.test.AbstractUnitTest;
 import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.Assertions;
 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.context.SpringBootTest;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.web.bind.annotation.ResponseStatus;
 
@@ -18,12 +22,17 @@ import java.util.Optional;
 
 import static at.tuwien.test.utils.EndpointUtils.getErrorCodes;
 import static at.tuwien.test.utils.EndpointUtils.getExceptions;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 @Log4j2
 @ExtendWith(SpringExtension.class)
 @SpringBootTest
 public class ApiExceptionHandlerTest extends AbstractUnitTest {
 
+    @Autowired
+    private ApiExceptionHandler apiExceptionHandler;
+
     @Test
     public void handle_succeeds() throws ClassNotFoundException, IOException {
         final List<Method> handlers = Arrays.asList(ApiExceptionHandler.class.getMethods());
@@ -42,7 +51,903 @@ public class ApiExceptionHandlerTest extends AbstractUnitTest {
             Assertions.assertNotNull(exception.getDeclaredAnnotation(ResponseStatus.class).reason(), "Exception " + exception.getName() + " does not provide a reason code");
             Assertions.assertTrue(errorCodes.contains(exception.getDeclaredAnnotation(ResponseStatus.class).reason()), "Exception code " + exception.getDeclaredAnnotation(ResponseStatus.class).reason() + " does have a reason code mapped in localized ui error messages");
             /* handler method */
-            Assertions.assertEquals(method.getDeclaredAnnotation(ResponseStatus.class).code(), exception.getDeclaredAnnotation(ResponseStatus.class).code());
+            assertEquals(method.getDeclaredAnnotation(ResponseStatus.class).code(), exception.getDeclaredAnnotation(ResponseStatus.class).code());
         }
     }
+
+    @Test
+    public void handle_accessNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new AccessNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.access.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_accountNotSetupException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new AccountNotSetupException("msg"));
+        assertEquals(HttpStatus.PRECONDITION_REQUIRED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.PRECONDITION_REQUIRED, body.getStatus());
+        assertEquals("error.user.setup", body.getCode());
+    }
+
+
+    @Test
+    public void handle_analyseServiceException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new AnalyseServiceException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.analyse.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_authServiceConnectionException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new AuthServiceConnectionException("msg"));
+        assertEquals(HttpStatus.BAD_GATEWAY, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_GATEWAY, body.getStatus());
+        assertEquals("error.auth.connection", body.getCode());
+    }
+
+
+    @Test
+    public void handle_authServiceException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new AuthServiceException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.auth.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_brokerServiceConnectionException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new BrokerServiceConnectionException("msg"));
+        assertEquals(HttpStatus.BAD_GATEWAY, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_GATEWAY, body.getStatus());
+        assertEquals("error.broker.connection", body.getCode());
+    }
+
+
+    @Test
+    public void handle_brokerServiceException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new BrokerServiceException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.broker.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_conceptNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ConceptNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.concept.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_containerAlreadyExistsException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ContainerAlreadyExistsException("msg"));
+        assertEquals(HttpStatus.CONFLICT, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.CONFLICT, body.getStatus());
+        assertEquals("error.container.exists", body.getCode());
+    }
+
+
+    @Test
+    public void handle_containerNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ContainerNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.container.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_containerQuotaException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ContainerQuotaException("msg"));
+        assertEquals(HttpStatus.LOCKED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.LOCKED, body.getStatus());
+        assertEquals("error.container.quota", body.getCode());
+    }
+
+
+    @Test
+    public void handle_credentialsInvalidException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new CredentialsInvalidException("msg"));
+        assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.FORBIDDEN, body.getStatus());
+        assertEquals("error.user.credentials", body.getCode());
+    }
+
+
+    @Test
+    public void handle_dataServiceConnectionException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new DataServiceConnectionException("msg"));
+        assertEquals(HttpStatus.BAD_GATEWAY, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_GATEWAY, body.getStatus());
+        assertEquals("error.data.connection", body.getCode());
+    }
+
+
+    @Test
+    public void handle_dataServiceException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new DataServiceException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.data.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_databaseMalformedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new DatabaseMalformedException("msg"));
+        assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.EXPECTATION_FAILED, body.getStatus());
+        assertEquals("error.database.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_databaseNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new DatabaseNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.database.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_databaseUnavailableException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new DatabaseUnavailableException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.database.connection", body.getCode());
+    }
+
+
+    @Test
+    public void handle_doiNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new DoiNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.doi.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_emailExistsException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new EmailExistsException("msg"));
+        assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.EXPECTATION_FAILED, body.getStatus());
+        assertEquals("error.user.email-exists", body.getCode());
+    }
+
+
+    @Test
+    public void handle_exchangeNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ExchangeNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.exchange.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_externalServiceException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ExternalServiceException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.external.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_filterBadRequestException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new FilterBadRequestException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.semantic.filter", body.getCode());
+    }
+
+
+    @Test
+    public void handle_formatNotAvailableException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new FormatNotAvailableException("msg"));
+        assertEquals(HttpStatus.NOT_ACCEPTABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_ACCEPTABLE, body.getStatus());
+        assertEquals("error.identifier.format", body.getCode());
+    }
+
+
+    @Test
+    public void handle_identifierNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new IdentifierNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.identifier.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_identifierNotSupportedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new IdentifierNotSupportedException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.identifier.unsupported", body.getCode());
+    }
+
+
+    @Test
+    public void handle_imageAlreadyExistsException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ImageAlreadyExistsException("msg"));
+        assertEquals(HttpStatus.CONFLICT, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.CONFLICT, body.getStatus());
+        assertEquals("error.image.exists", body.getCode());
+    }
+
+
+    @Test
+    public void handle_imageInvalidException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ImageInvalidException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.image.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_imageNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ImageNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.image.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_licenseNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new LicenseNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.license.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_malformedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new MalformedException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.request.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_messageNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new MessageNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.message.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_metadataServiceConnectionException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new MetadataServiceConnectionException("msg"));
+        assertEquals(HttpStatus.BAD_GATEWAY, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_GATEWAY, body.getStatus());
+        assertEquals("error.metadata.connection", body.getCode());
+    }
+
+
+    @Test
+    public void handle_metadataServiceException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new MetadataServiceException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.metadata.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_notAllowedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new NotAllowedException("msg"));
+        assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.FORBIDDEN, body.getStatus());
+        assertEquals("error.request.forbidden", body.getCode());
+    }
+
+
+    @Test
+    public void handle_ontologyNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new OntologyNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.ontology.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_orcidNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new OrcidNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.orcid.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_paginationException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new PaginationException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.request.pagination", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queryMalformedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueryMalformedException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.query.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queryNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueryNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.query.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queryNotSupportedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueryNotSupportedException("msg"));
+        assertEquals(HttpStatus.NOT_IMPLEMENTED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_IMPLEMENTED, body.getStatus());
+        assertEquals("error.query.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queryStoreCreateException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueryStoreCreateException("msg"));
+        assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.EXPECTATION_FAILED, body.getStatus());
+        assertEquals("error.store.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queryStoreGCException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueryStoreGCException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.store.clean", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queryStoreInsertException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueryStoreInsertException("msg"));
+        assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.EXPECTATION_FAILED, body.getStatus());
+        assertEquals("error.store.insert", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queryStorePersistException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueryStorePersistException("msg"));
+        assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.EXPECTATION_FAILED, body.getStatus());
+        assertEquals("error.store.persist", body.getCode());
+    }
+
+
+    @Test
+    public void handle_queueNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new QueueNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.queue.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_remoteUnavailableException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new RemoteUnavailableException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.metadata.privileged", body.getCode());
+    }
+
+
+    @Test
+    public void handle_rorNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new RorNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.ror.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_searchServiceConnectionException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new SearchServiceConnectionException("msg"));
+        assertEquals(HttpStatus.BAD_GATEWAY, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_GATEWAY, body.getStatus());
+        assertEquals("error.search.connection", body.getCode());
+    }
+
+
+    @Test
+    public void handle_searchServiceException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new SearchServiceException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.search.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_semanticEntityNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new SemanticEntityNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.semantic.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_sortException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new SortException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.request.sort", body.getCode());
+    }
+
+
+    @Test
+    public void handle_storageNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new StorageNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.storage.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_storageUnavailableException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new StorageUnavailableException("msg"));
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.SERVICE_UNAVAILABLE, body.getStatus());
+        assertEquals("error.storage.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_tableExistsException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new TableExistsException("msg"));
+        assertEquals(HttpStatus.CONFLICT, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.CONFLICT, body.getStatus());
+        assertEquals("error.table.exists", body.getCode());
+    }
+
+
+    @Test
+    public void handle_tableMalformedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new TableMalformedException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.table.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_tableNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new TableNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.table.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_tableSchemaException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new TableSchemaException("msg"));
+        assertEquals(HttpStatus.CONFLICT, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.CONFLICT, body.getStatus());
+        assertEquals("error.schema.table", body.getCode());
+    }
+
+
+    @Test
+    public void handle_unitNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new UnitNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.unit.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_uriMalformedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new UriMalformedException("msg"));
+        assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.EXPECTATION_FAILED, body.getStatus());
+        assertEquals("error.semantics.uri", body.getCode());
+    }
+
+
+    @Test
+    public void handle_userExistsException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new UserExistsException("msg"));
+        assertEquals(HttpStatus.CONFLICT, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.CONFLICT, body.getStatus());
+        assertEquals("error.user.exists", body.getCode());
+    }
+
+
+    @Test
+    public void handle_userNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new UserNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.user.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_viewMalformedException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ViewMalformedException("msg"));
+        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.BAD_REQUEST, body.getStatus());
+        assertEquals("error.view.invalid", body.getCode());
+    }
+
+
+    @Test
+    public void handle_viewNotFoundException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ViewNotFoundException("msg"));
+        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.NOT_FOUND, body.getStatus());
+        assertEquals("error.view.missing", body.getCode());
+    }
+
+
+    @Test
+    public void handle_viewSchemaException_succeeds() {
+
+        /* test */
+        final ResponseEntity<ApiErrorDto> response = apiExceptionHandler.handle(new ViewSchemaException("msg"));
+        assertEquals(HttpStatus.CONFLICT, response.getStatusCode());
+        final ApiErrorDto body = response.getBody();
+        assertNotNull(body);
+        assertEquals("msg", body.getMessage());
+        assertEquals(HttpStatus.CONFLICT, body.getStatus());
+        assertEquals("error.schema.view", body.getCode());
+    }
+
 }
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
new file mode 100644
index 0000000000000000000000000000000000000000..39aed0d28ea800574177821a252dbbfbde647db9
--- /dev/null
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java
@@ -0,0 +1,85 @@
+package at.tuwien.service;
+
+import at.tuwien.entities.user.User;
+import at.tuwien.exception.AuthServiceException;
+import at.tuwien.exception.UserNotFoundException;
+import at.tuwien.gateway.KeycloakGateway;
+import at.tuwien.repository.UserRepository;
+import at.tuwien.test.AbstractUnitTest;
+import at.tuwien.utils.KeycloakUtils;
+import dasniko.testcontainers.keycloak.KeycloakContainer;
+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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+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 java.util.List;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@Log4j2
+@Testcontainers
+@ExtendWith(SpringExtension.class)
+@SpringBootTest
+public class UserServiceIntegrationTest extends AbstractUnitTest {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private KeycloakUtils keycloakUtils;
+
+    @BeforeEach
+    public void beforeEach() {
+        genesis();
+        /* keycloak */
+        userRepository.deleteAll();
+        keycloakUtils.deleteUser(USER_1_USERNAME);
+    }
+
+    @Container
+    private static KeycloakContainer keycloakContainer = new KeycloakContainer(KEYCLOAK_IMAGE)
+            .withImagePullPolicy(PullPolicy.alwaysPull())
+            .withAdminUsername("admin")
+            .withAdminPassword("admin")
+            .withRealmImportFile("./init/dbrepo-realm.json")
+            .withEnv("KC_HOSTNAME_STRICT_HTTPS", "false");
+
+    @DynamicPropertySource
+    static void keycloakProperties(DynamicPropertyRegistry registry) {
+        final String authServiceEndpoint = "http://localhost:" + keycloakContainer.getMappedPort(8080);
+        log.trace("set auth endpoint: {}", authServiceEndpoint);
+        registry.add("dbrepo.endpoints.authService", () -> authServiceEndpoint);
+    }
+
+    @Test
+    public void create_succeeds() throws UserNotFoundException, AuthServiceException {
+
+        /* test */
+        final User response = userService.create(USER_1_CREATE_USER_DTO);
+        assertEquals(USER_1_ID, response.getId());
+        assertEquals(USER_1_KEYCLOAK_ID, response.getKeycloakId());
+        assertEquals(USER_1_USERNAME, response.getUsername());
+        assertEquals(USER_1_THEME, response.getTheme());
+        assertNotNull(response.getMariadbPassword());
+        assertEquals(USER_1_LANGUAGE, response.getLanguage());
+        assertEquals(USER_1_FIRSTNAME, response.getFirstname());
+        assertEquals(USER_1_LASTNAME, response.getLastname());
+        assertEquals(USER_1_IS_INTERNAL, response.getIsInternal());
+    }
+
+}
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java
index 514d23b227dc3294741e2dcd212083f9ff23f619..eb228ab3c3c3f781a585fa199b63c7a512d222c3 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java
@@ -42,7 +42,7 @@ public class UserServicePersistenceTest extends AbstractUnitTest {
     public void beforeEach() {
         genesis();
         /* metadata database */
-        userRepository.save(USER_1);
+        userRepository.saveAll(List.of(USER_1, USER_LOCAL));
     }
 
     @Test
@@ -54,6 +54,16 @@ public class UserServicePersistenceTest extends AbstractUnitTest {
         assertEquals(USER_1_USERNAME, response.getUsername());
     }
 
+    @Test
+    public void findAllInternalUsers_succeeds() {
+
+        /* test */
+        final List<User> response = userService.findAllInternalUsers();
+        assertEquals(1, response.size());
+        final User user0 = response.get(0);
+        assertEquals(USER_LOCAL_ADMIN_ID, user0.getId());
+    }
+
     @Test
     public void findByUsername_fails() {
 
@@ -68,7 +78,7 @@ public class UserServicePersistenceTest extends AbstractUnitTest {
 
         /* test */
         final List<User> response = userService.findAll();
-        assertEquals(1, response.size());
+        assertEquals(2, response.size());
     }
 
     @Test
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 58d7cdc5e47f79cd45dd868d1b473a8051c79dce..df13d00b0858a28dd4ccc38c5542601790dc964a 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
@@ -93,12 +93,12 @@ public class UserServiceUnitTest extends AbstractUnitTest {
     }
 
     @Test
-    public void updatePassword_succeeds() throws UserNotFoundException {
+    public void updatePassword_succeeds() throws UserNotFoundException, AuthServiceException {
 
         /* mock */
         doNothing()
                 .when(keycloakGateway)
-                .updateUserCredentials(USER_1_ID, USER_1_PASSWORD_DTO);
+                .setupFinished(USER_1_ID);
         when(userRepository.findById(USER_1_ID))
                 .thenReturn(Optional.of(USER_1));
         when(userRepository.save(any(User.class)))
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java
index 486db28e5945737e776da4b8f0aaf6d6d977715e..8105a7fb8907b508a336876e9c5e6ce94916e59d 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java
@@ -52,9 +52,27 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest {
 
     public static Stream<Arguments> needSize_parameters() {
         return Stream.of(
-                Arguments.arguments(ColumnTypeDto.VARCHAR),
-                Arguments.arguments(ColumnTypeDto.BINARY),
-                Arguments.arguments(ColumnTypeDto.VARBINARY)
+                Arguments.arguments("varchar", ColumnTypeDto.VARCHAR),
+                Arguments.arguments("binary", ColumnTypeDto.BINARY),
+                Arguments.arguments("varbinary", ColumnTypeDto.VARBINARY)
+        );
+    }
+
+    public static Stream<Arguments> needSizeAndD_parameters() {
+        return Stream.of(
+                Arguments.arguments("double_size", ColumnTypeDto.DOUBLE, 40L, null),
+                Arguments.arguments("double_d", ColumnTypeDto.DOUBLE, null, 10L),
+                Arguments.arguments("decimal_size", ColumnTypeDto.DECIMAL, 40L, null),
+                Arguments.arguments("decimal_d", ColumnTypeDto.DECIMAL, null, 10L)
+        );
+    }
+
+    public static Stream<Arguments> enums_parameters() {
+        return Stream.of(
+                Arguments.arguments("enums_null", ColumnTypeDto.ENUM, null),
+                Arguments.arguments("enums_empty", ColumnTypeDto.ENUM, List.of()),
+                Arguments.arguments("sets_null", ColumnTypeDto.SET, null),
+                Arguments.arguments("sets_empty", ColumnTypeDto.SET, List.of())
         );
     }
 
@@ -244,6 +262,20 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest {
         endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(TABLE_1, USER_1);
     }
 
+    @Test
+    public void validateOnlyWriteOwnOrWriteAllAccess_writeOwnAccess_succeeds() throws DatabaseNotFoundException,
+            TableNotFoundException, AccessNotFoundException, NotAllowedException {
+
+        /* mock */
+        when(tableService.findById(DATABASE_1, TABLE_1_ID))
+                .thenReturn(TABLE_1);
+        when(accessService.find(eq(DATABASE_1), any(User.class)))
+                .thenReturn(DATABASE_1_USER_1_WRITE_OWN_ACCESS);
+
+        /* test */
+        endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(TABLE_1, USER_1);
+    }
+
     @Test
     public void validateOnlyWriteOwnOrWriteAllAccess_privateHasReadAccess_fails() throws DatabaseNotFoundException,
             TableNotFoundException, AccessNotFoundException {
@@ -285,7 +317,7 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest {
 
     @ParameterizedTest
     @MethodSource("needSize_parameters")
-    public void validateColumnCreateConstraints_needSize_fails(ColumnTypeDto type) {
+    public void validateColumnCreateConstraints_needSize_fails(String name, ColumnTypeDto type) {
         final CreateTableDto request = CreateTableDto.builder()
                 .columns(List.of(CreateTableColumnDto.builder()
                         .type(type)
@@ -299,12 +331,13 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest {
         });
     }
 
-    @Test
-    public void validateColumnCreateConstraints_needEnum_fails() {
+    @ParameterizedTest
+    @MethodSource("enums_parameters")
+    public void validateColumnCreateConstraints_needEnum_fails(String name, ColumnTypeDto type, List<String> enums) {
         final CreateTableDto request = CreateTableDto.builder()
                 .columns(List.of(CreateTableColumnDto.builder()
-                        .type(ColumnTypeDto.ENUM)
-                        .enums(null) // <<<<<<<
+                        .type(type)
+                        .enums(enums)
                         .build()))
                 .build();
 
@@ -314,12 +347,14 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest {
         });
     }
 
-    @Test
-    public void validateColumnCreateConstraints_needSet_fails() {
+    @ParameterizedTest
+    @MethodSource("needSizeAndD_parameters")
+    public void validateColumnCreateConstraints_needSizeAndD_fails(String name, ColumnTypeDto type, Long size, Long d) {
         final CreateTableDto request = CreateTableDto.builder()
                 .columns(List.of(CreateTableColumnDto.builder()
-                        .type(ColumnTypeDto.SET)
-                        .sets(null) // <<<<<<<
+                        .type(type)
+                        .size(size)
+                        .d(d)
                         .build()))
                 .build();
 
@@ -345,6 +380,34 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest {
         });
     }
 
+    @Test
+    public void validateOnlyOwnerOrWriteAll_writeOwnAccess_succeeds() throws DatabaseNotFoundException,
+            TableNotFoundException, AccessNotFoundException, NotAllowedException {
+
+        /* mock */
+        when(tableService.findById(DATABASE_1, TABLE_1_ID))
+                .thenReturn(TABLE_1);
+        when(accessService.find(DATABASE_1, USER_1))
+                .thenReturn(DATABASE_1_USER_1_WRITE_OWN_ACCESS);
+
+        /* test */
+        endpointValidator.validateOnlyOwnerOrWriteAll(TABLE_1, USER_1);
+    }
+
+    @Test
+    public void validateOnlyOwnerOrWriteAll_writeAllAccess_succeeds() throws DatabaseNotFoundException,
+            TableNotFoundException, AccessNotFoundException, NotAllowedException {
+
+        /* mock */
+        when(tableService.findById(DATABASE_1, TABLE_1_ID))
+                .thenReturn(TABLE_1);
+        when(accessService.find(DATABASE_1, USER_2))
+                .thenReturn(DATABASE_1_USER_2_WRITE_ALL_ACCESS);
+
+        /* test */
+        endpointValidator.validateOnlyOwnerOrWriteAll(TABLE_1, USER_2);
+    }
+
     @Test
     public void validateOnlyPrivateDataHasRole_publicDatabase_succeeds() throws NotAllowedException {
 
@@ -555,6 +618,13 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest {
         assertTrue(endpointValidator.validateOnlyMineOrWriteAccessOrHasRole(USER_1, USER_1_PRINCIPAL, DATABASE_1_USER_1_WRITE_OWN_ACCESS, "nobody-role"));
     }
 
+    @Test
+    public void validateOnlyMineOrWriteAccessOrHasRole_ownerOnlyWriteAll_succeeds() {
+
+        /* test */
+        assertTrue(endpointValidator.validateOnlyMineOrWriteAccessOrHasRole(USER_1, USER_1_PRINCIPAL, DATABASE_1_USER_1_WRITE_ALL_ACCESS, "nobody-role"));
+    }
+
     @Test
     public void validateOnlyMineOrWriteAccessOrHasRole_notOwnerOnlyWriteOwn_fails() {
 
diff --git a/dbrepo-metadata-service/services/pom.xml b/dbrepo-metadata-service/services/pom.xml
index 906fa5258b02807565c4acc0e361d5c65bd65b77..e918d3ae24adf706455b8ca7767b166198f5028f 100644
--- a/dbrepo-metadata-service/services/pom.xml
+++ b/dbrepo-metadata-service/services/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-services</artifactId>
     <name>dbrepo-metadata-service-services</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
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 cd5fd08a7ef64e88134a1fc19aa0840ad1e98020..296457b3d8ba1cd6e14e8a46be85a217b9cb8e13 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
@@ -1,7 +1,6 @@
 package at.tuwien.gateway;
 
 import at.tuwien.api.keycloak.TokenDto;
-import at.tuwien.api.user.UserPasswordDto;
 import at.tuwien.api.user.UserUpdateDto;
 import at.tuwien.exception.AuthServiceException;
 import at.tuwien.exception.UserNotFoundException;
@@ -22,13 +21,7 @@ public interface KeycloakGateway {
      */
     void deleteUser(UUID id) throws UserNotFoundException;
 
-    /**
-     * Update the credentials for a given user.
-     *
-     * @param id       The user id.
-     * @param password The user credential.
-     */
-    void updateUserCredentials(UUID id, UserPasswordDto password) throws UserNotFoundException;
+    void setupFinished(UUID id) throws AuthServiceException, UserNotFoundException;
 
     void updateUser(UUID id, UserUpdateDto data) throws AuthServiceException, UserNotFoundException;
 }
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 af54651d6c36197e136134003291ea88f5df2a49..270653ee8ffade88a9b96c24e2650843b21c5dd5 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
@@ -1,14 +1,12 @@
 package at.tuwien.gateway.impl;
 
 import at.tuwien.api.keycloak.TokenDto;
-import at.tuwien.api.user.UserPasswordDto;
 import at.tuwien.api.user.UserUpdateDto;
 import at.tuwien.config.KeycloakConfig;
 import at.tuwien.exception.AuthServiceException;
 import at.tuwien.exception.UserNotFoundException;
 import at.tuwien.gateway.KeycloakGateway;
 import at.tuwien.mapper.MetadataMapper;
-import jakarta.ws.rs.BadRequestException;
 import jakarta.ws.rs.ForbiddenException;
 import jakarta.ws.rs.NotFoundException;
 import jakarta.ws.rs.core.Response;
@@ -17,7 +15,6 @@ import org.keycloak.OAuth2Constants;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.admin.client.KeycloakBuilder;
 import org.keycloak.admin.client.resource.UserResource;
-import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.springframework.stereotype.Service;
 
@@ -80,21 +77,25 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
     }
 
     @Override
-    public void updateUserCredentials(UUID id, UserPasswordDto data) throws UserNotFoundException {
-        final CredentialRepresentation credential = new CredentialRepresentation();
-        credential.setTemporary(false);
-        credential.setValue(data.getPassword());
-        credential.setType(CredentialRepresentation.PASSWORD);
+    public void setupFinished(UUID id) throws AuthServiceException, UserNotFoundException {
+        final UserResource resource = keycloak.realm(keycloakConfig.getRealm())
+                .users()
+                .get(String.valueOf(id));
+        final UserRepresentation user;
         try {
-            keycloak.realm(keycloakConfig.getRealm())
-                    .users()
-                    .get(String.valueOf(id))
-                    .resetPassword(credential);
+            user = resource.toRepresentation();
         } catch (NotFoundException e) {
-            log.error("Failed to update user password: not found");
-            throw new UserNotFoundException("Failed to update user password: not found", e);
+            log.error("Failed to update user setup: not found: {}", e.getMessage());
+            throw new UserNotFoundException("Failed to update user setup: not found", e);
+        }
+        user.singleAttribute("SETUP_FINISHED", "true");
+        try {
+            resource.update(user);
+        } catch (ForbiddenException e) {
+            log.error("Failed to update user setup: forbidden: {}", e.getMessage());
+            throw new AuthServiceException("Failed to update user setup: forbidden", e);
         }
-        log.info("Updated user {} password at auth service", id);
+        log.info("Updated user {} setup at auth service", id);
     }
 
     @Override
@@ -102,7 +103,7 @@ public class KeycloakGatewayImpl implements KeycloakGateway {
         final UserResource resource = keycloak.realm(keycloakConfig.getRealm())
                 .users()
                 .get(String.valueOf(id));
-        UserRepresentation user;
+        final UserRepresentation user;
         try {
             user = resource.toRepresentation();
         } catch (NotFoundException e) {
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
index 75b647bf954fd638dfde8ffa8b7f650d03ce7c49..3abe07a10a16b7b72ec144d6ddeb7ee32cd599b6 100644
--- 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
@@ -1,6 +1,5 @@
 package at.tuwien.service;
 
-import at.tuwien.api.user.UserPasswordDto;
 import at.tuwien.entities.user.User;
 import at.tuwien.exception.AuthServiceConnectionException;
 import at.tuwien.exception.AuthServiceException;
@@ -23,8 +22,7 @@ public interface AuthenticationService {
      * Updates the password of a user with given id.
      *
      * @param user The user.
-     * @param data The new password.
      * @throws UserNotFoundException      The user was not found after creation in the auth database.
      */
-    void updatePassword(User user, UserPasswordDto data) throws UserNotFoundException;
+    void setupFinished(User user) throws UserNotFoundException, AuthServiceException;
 }
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 581641a93ab95927d63c5b4a5f6b069eb6f270b7..c6ca0ff21eb02986f30d42ec0b8727b368d5bfe4 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
@@ -4,7 +4,6 @@ import at.tuwien.api.auth.CreateUserDto;
 import at.tuwien.api.user.UserPasswordDto;
 import at.tuwien.api.user.UserUpdateDto;
 import at.tuwien.entities.user.User;
-import at.tuwien.exception.AuthServiceConnectionException;
 import at.tuwien.exception.AuthServiceException;
 import at.tuwien.exception.UserExistsException;
 import at.tuwien.exception.UserNotFoundException;
@@ -47,7 +46,7 @@ public interface UserService {
      * @param data The user data.
      * @return The user, if successful.
      */
-    User create(CreateUserDto data) throws UserNotFoundException, AuthServiceException;
+    User create(CreateUserDto data);
 
     /**
      * Updates the user information for a user with given id in the metadata database.
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
index 1159913039ef59227758006f28d678db99329386..dec3577886de7e4e0b60b015f72f73099a441065 100644
--- 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
@@ -1,10 +1,7 @@
 package at.tuwien.service.impl;
 
-import at.tuwien.api.user.UserPasswordDto;
 import at.tuwien.entities.user.User;
-import at.tuwien.exception.AuthServiceConnectionException;
 import at.tuwien.exception.AuthServiceException;
-import at.tuwien.exception.CredentialsInvalidException;
 import at.tuwien.exception.UserNotFoundException;
 import at.tuwien.gateway.KeycloakGateway;
 import at.tuwien.service.AuthenticationService;
@@ -29,8 +26,8 @@ public class AuthenticationServiceImpl implements AuthenticationService {
     }
 
     @Override
-    public void updatePassword(User user, UserPasswordDto data) throws UserNotFoundException {
-        keycloakGateway.updateUserCredentials(user.getKeycloakId(), data);
+    public void setupFinished(User user) throws AuthServiceException, UserNotFoundException {
+        keycloakGateway.setupFinished(user.getKeycloakId());
     }
 
 }
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 1d582bb9752a0cecd6885c72ba5de19d5cb78887..e79dd9bd842ac4cbb145f3b86f533962c23e2625 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
@@ -65,14 +65,14 @@ public class UserServiceImpl implements UserService {
     }
 
     @Override
-    public User create(CreateUserDto data) throws UserNotFoundException, AuthServiceException {
+    public User create(CreateUserDto data) {
         /* create at authentication service */
         final User entity = User.builder()
                 .id(data.getLdapId())
                 .keycloakId(data.getId())
                 .username(data.getUsername())
                 .theme("light")
-                .mariadbPassword(getMariaDbPassword(RandomStringUtils.randomAlphabetic(10))) /* user needs to set it later to access */
+                .mariadbPassword(getMariaDbPassword(RandomStringUtils.randomAlphabetic(10)))
                 .language("en")
                 .firstname(data.getGivenName())
                 .lastname(data.getFamilyName())
diff --git a/dbrepo-metadata-service/test/pom.xml b/dbrepo-metadata-service/test/pom.xml
index 792523227eaa968b3dd8c340779bece2323cb461..4aa6188f9fa7b26d9181a1cdc42a0ee00bce3b39 100644
--- a/dbrepo-metadata-service/test/pom.xml
+++ b/dbrepo-metadata-service/test/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.7.0</version>
+        <version>1.6.4</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-test</artifactId>
     <name>dbrepo-metadata-service-test</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <dependencies>
         <dependency>
diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
index bccf903b8befe7ceec1915f10a49ff0fdb0e35c0..860eeb8253c18a58d19ac6c61d8017382399875a 100644
--- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
+++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
@@ -5,6 +5,7 @@ import at.tuwien.api.amqp.CreateVirtualHostDto;
 import at.tuwien.api.amqp.ExchangeDto;
 import at.tuwien.api.amqp.GrantVirtualHostPermissionsDto;
 import at.tuwien.api.amqp.QueueDto;
+import at.tuwien.api.auth.CreateUserDto;
 import at.tuwien.api.auth.LoginRequestDto;
 import at.tuwien.api.auth.RefreshTokenRequestDto;
 import at.tuwien.api.container.ContainerBriefDto;
@@ -478,8 +479,6 @@ public abstract class BaseTest {
     @SuppressWarnings("java:S2068")
     public final static String USER_1_PASSWORD = "junit1";
     @SuppressWarnings("java:S2068")
-    public final static String USER_1_PASSWORD_ENCODED = "$2a$10$0dtdedA/RLTrFbUsvpbUw.I73AXOKeQP3t5UXj96OvnDEaDb3d3M6";
-    @SuppressWarnings("java:S2068")
     public final static String USER_1_DATABASE_PASSWORD = "*440BA4FD1A87A0999647DB67C0EE258198B247BA" /* junit1 */;
     public final static String USER_1_FIRSTNAME = "John";
     public final static String USER_1_LASTNAME = "Doe";
@@ -487,18 +486,11 @@ public abstract class BaseTest {
     public final static String USER_1_NAME = "John Doe";
     public final static String USER_1_AFFILIATION = "TU Graz";
     public final static String USER_1_ORCID_URL = "https://orcid.org/0000-0003-4216-302X";
-    public final static String USER_1_TITLES_BEFORE = "Dr.";
-    public final static String USER_1_TITLES_AFTER = "MSc BSc";
-    public final static Boolean USER_1_VERIFIED = false;
-    public final static Boolean USER_1_TOTP = false;
-    public final static Long USER_1_NOT_BEFORE = 0L;
     public final static Boolean USER_1_ENABLED = true;
     public final static Boolean USER_1_IS_INTERNAL = false;
     public final static String USER_1_THEME = "light";
     public final static String USER_1_LANGUAGE = "en";
     public final static Instant USER_1_CREATED = Instant.ofEpochSecond(1677399441L) /* 2023-02-26 08:17:21 (UTC) */;
-    public final static Instant USER_1_LAST_MODIFIED = USER_1_CREATED;
-    public final static UUID USER_1_REALM_ID = REALM_DBREPO_ID;
 
     public final static UpdateUserPasswordDto USER_1_UPDATE_PASSWORD_DTO = UpdateUserPasswordDto.builder()
             .username(USER_1_USERNAME)
@@ -568,6 +560,14 @@ public abstract class BaseTest {
             .qualifiedName(USER_1_QUALIFIED_NAME)
             .build();
 
+    public final static CreateUserDto USER_1_CREATE_USER_DTO = CreateUserDto.builder()
+            .id(USER_1_KEYCLOAK_ID)
+            .ldapId(USER_1_ID)
+            .givenName(USER_1_FIRSTNAME)
+            .familyName(USER_1_LASTNAME)
+            .username(USER_1_USERNAME)
+            .build();
+
     public final static UserUpdateDto USER_1_UPDATE_DTO = UserUpdateDto.builder()
             .firstname(USER_1_FIRSTNAME)
             .lastname(USER_1_LASTNAME)
@@ -608,7 +608,6 @@ public abstract class BaseTest {
 
     public final static UUID USER_2_ID = UUID.fromString("eeb9a51b-4cd8-4039-90bf-e24f17372f7c");
     public final static UUID USER_2_KEYCLOAK_ID = UUID.fromString("eeb9a51b-4cd8-4039-90bf-e24f17372f7c");
-    public final static String USER_2_EMAIL = "jane.doe@example.com";
     public final static String USER_2_USERNAME = "junit2";
     public final static String USER_2_FIRSTNAME = "Jane";
     public final static String USER_2_LASTNAME = "Doe";
@@ -620,16 +619,9 @@ public abstract class BaseTest {
     @SuppressWarnings("java:S2068")
     public final static String USER_2_DATABASE_PASSWORD = "*9AA70A8B0EEFAFCB5BED5BDEF6EE264D5DA915AE" /* junit2 */;
     public final static String USER_2_QUALIFIED_NAME = USER_2_FIRSTNAME + " " + USER_2_LASTNAME + " — @" + USER_2_USERNAME;
-    public final static Boolean USER_2_VERIFIED = true;
-    public final static Boolean USER_2_TOTP = false;
-    public final static Long USER_2_NOT_BEFORE = 0L;
-    public final static Boolean USER_2_ENABLED = true;
     public final static Boolean USER_2_IS_INTERNAL = false;
     public final static String USER_2_THEME = "light";
     public final static String USER_2_LANGUAGE = "de";
-    public final static Instant USER_2_CREATED = Instant.ofEpochSecond(1677399528L) /* 2023-02-26 08:18:48 (UTC) */;
-    public final static Instant USER_2_LAST_MODIFIED = USER_1_CREATED;
-    public final static UUID USER_2_REALM_ID = REALM_DBREPO_ID;
 
     public final static UserAttributesDto USER_2_ATTRIBUTES_DTO = UserAttributesDto.builder()
             .theme(USER_2_THEME)
@@ -697,20 +689,13 @@ public abstract class BaseTest {
     public final static String USER_3_AFFILIATION = "TU Wien";
     public final static String USER_3_ORCID_URL = null;
     public final static String USER_3_ORCID_UNCOMPRESSED = null;
-    public final static String USER_3_EMAIL = "system@example.com";
     @SuppressWarnings("java:S2068")
     public final static String USER_3_PASSWORD = "password";
     @SuppressWarnings("java:S2068")
     public final static String USER_3_DATABASE_PASSWORD = "*D65FCA043964B63E849DD6334699ECB065905DA4" /* junit3 */;
     public final static String USER_3_QUALIFIED_NAME = USER_3_FIRSTNAME + " " + USER_3_LASTNAME + " — @" + USER_3_USERNAME;
-    public final static Boolean USER_3_VERIFIED = true;
-    public final static Boolean USER_3_TOTP = false;
-    public final static Long USER_3_NOT_BEFORE = 0L;
-    public final static Boolean USER_3_ENABLED = true;
     public final static Boolean USER_3_IS_INTERNAL = false;
     public final static String USER_3_THEME = "light";
-    public final static Instant USER_3_CREATED = Instant.ofEpochSecond(1677399559L) /* 2023-02-26 08:19:19 (UTC) */;
-    public final static UUID USER_3_REALM_ID = REALM_DBREPO_ID;
 
     public final static UserAttributesDto USER_3_ATTRIBUTES_DTO = UserAttributesDto.builder()
             .theme(USER_3_THEME)
@@ -779,12 +764,8 @@ public abstract class BaseTest {
     @SuppressWarnings("java:S2068")
     public final static String USER_4_DATABASE_PASSWORD = "*C20EF5C6875857DEFA9BE6E9B62DD76AAAE51882" /* junit4 */;
     public final static String USER_4_QUALIFIED_NAME = USER_4_FIRSTNAME + " " + USER_4_LASTNAME + " — @" + USER_4_USERNAME;
-    public final static Boolean USER_4_VERIFIED = true;
-    public final static Boolean USER_4_ENABLED = true;
     public final static Boolean USER_4_IS_INTERNAL = false;
     public final static String USER_4_THEME = "light";
-    public final static Instant USER_4_CREATED = Instant.ofEpochSecond(1677399592L) /* 2023-02-26 08:19:52 (UTC) */;
-    public final static UUID USER_4_REALM_ID = REALM_DBREPO_ID;
 
     public final static UserAttributesDto USER_4_ATTRIBUTES_DTO = UserAttributesDto.builder()
             .theme(USER_4_THEME)
@@ -842,18 +823,13 @@ public abstract class BaseTest {
     public final static String USER_5_LASTNAME = "Body";
     public final static String USER_5_NAME = "No Body";
     public final static String USER_5_AFFILIATION = "TU Wien";
-    public final static String USER_5_ORCID = null;
     @SuppressWarnings("java:S2068")
     public final static String USER_5_PASSWORD = "junit5";
     @SuppressWarnings("java:S2068")
     public final static String USER_5_DATABASE_PASSWORD = "*C20EF5C6875857DEFA9BE6E9B62DD76AAAE51882" /* junit5 */;
     public final static String USER_5_QUALIFIED_NAME = USER_5_FIRSTNAME + " " + USER_5_LASTNAME + " — @" + USER_5_USERNAME;
-    public final static Boolean USER_5_VERIFIED = true;
-    public final static Boolean USER_5_ENABLED = true;
     public final static Boolean USER_5_IS_INTERNAL = false;
     public final static String USER_5_THEME = "dark";
-    public final static Instant USER_5_CREATED = Instant.ofEpochSecond(1677399592L) /* 2023-02-26 08:19:52 (UTC) */;
-    public final static UUID USER_5_REALM_ID = REALM_DBREPO_ID;
 
     public final static UserAttributesDto USER_5_ATTRIBUTES_DTO = UserAttributesDto.builder()
             .theme(USER_5_THEME)
@@ -7680,6 +7656,21 @@ public abstract class BaseTest {
             .user(USER_3_BRIEF_DTO)
             .build();
 
+    public final static DatabaseAccess DATABASE_1_USER_4_READ_ACCESS = DatabaseAccess.builder()
+            .type(AccessType.READ)
+            .hdbid(DATABASE_1_ID)
+            .database(DATABASE_1)
+            .huserid(USER_4_ID)
+            .user(USER_4)
+            .build();
+
+    public final static DatabaseAccessDto DATABASE_1_USER_4_READ_ACCESS_DTO = DatabaseAccessDto.builder()
+            .type(AccessTypeDto.READ)
+            .hdbid(DATABASE_1_ID)
+            .huserid(USER_4_ID)
+            .user(USER_4_BRIEF_DTO)
+            .build();
+
     public final static Database DATABASE_2 = Database.builder()
             .id(DATABASE_2_ID)
             .created(DATABASE_2_CREATED)
diff --git a/dbrepo-search-service/Pipfile b/dbrepo-search-service/Pipfile
index 6284708cc1d7f99f10843ad47c05b35a25916bf4..4e3f9968022e35187cec3fbe92fdc33e70898ab8 100644
--- a/dbrepo-search-service/Pipfile
+++ b/dbrepo-search-service/Pipfile
@@ -18,7 +18,7 @@ jwt = "~=1.3"
 testcontainers-opensearch = "*"
 pytest = "*"
 rdflib = "*"
-dbrepo = {path = "./lib/dbrepo-1.7.0.tar.gz"}
+dbrepo = {path = "./lib/dbrepo-1.6.4.tar.gz"}
 gunicorn = "*"
 
 [dev-packages]
diff --git a/dbrepo-search-service/Pipfile.lock b/dbrepo-search-service/Pipfile.lock
index 4fc5ec3cab2dcfb47e52f6804e9888da37a42055..87013913cdcee8520ff2760de0e16e81d0082d3c 100644
--- a/dbrepo-search-service/Pipfile.lock
+++ b/dbrepo-search-service/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "30aa6fefdbdbb9f57d58ebc8660eee64445a831cea44c6ca1fa605f2a2e1adc3"
+            "sha256": "c22580f5873b7bd3fc1edb71c84b7269ae79da6a2554225fe8d95cab6af9f14d"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -369,9 +369,9 @@
         },
         "dbrepo": {
             "hashes": [
-                "sha256:f25d5adbd618bf2906578e671af2bf3bcc24d738ef8bc791c220e7e5b714e2f7"
+                "sha256:a518aee79540d9e302b161e7e10072f50730489da19368f00a1e68204009ce44"
             ],
-            "path": "./lib/dbrepo-1.7.0.tar.gz"
+            "path": "./lib/dbrepo-1.6.4.tar.gz"
         },
         "docker": {
             "hashes": [
diff --git a/dbrepo-search-service/init/lib/dbrepo-1.6.4-py3-none-any.whl b/dbrepo-search-service/init/lib/dbrepo-1.6.4-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..d083b0bafc937528fdcc09634c41132578cbf345
Binary files /dev/null and b/dbrepo-search-service/init/lib/dbrepo-1.6.4-py3-none-any.whl differ
diff --git a/dbrepo-search-service/init/lib/dbrepo-1.6.4.tar.gz b/dbrepo-search-service/init/lib/dbrepo-1.6.4.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..87e9a503ebc621238ebe7efca15f2bdf0a6e1a85
Binary files /dev/null and b/dbrepo-search-service/init/lib/dbrepo-1.6.4.tar.gz differ
diff --git a/dbrepo-search-service/lib/dbrepo-1.6.4-py3-none-any.whl b/dbrepo-search-service/lib/dbrepo-1.6.4-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..d083b0bafc937528fdcc09634c41132578cbf345
Binary files /dev/null and b/dbrepo-search-service/lib/dbrepo-1.6.4-py3-none-any.whl differ
diff --git a/dbrepo-search-service/lib/dbrepo-1.6.4.tar.gz b/dbrepo-search-service/lib/dbrepo-1.6.4.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..87e9a503ebc621238ebe7efca15f2bdf0a6e1a85
Binary files /dev/null and b/dbrepo-search-service/lib/dbrepo-1.6.4.tar.gz differ
diff --git a/dbrepo-ui/composables/authentication-service.ts b/dbrepo-ui/composables/authentication-service.ts
deleted file mode 100644
index 39f6cc5a3fc843bd8db07c22b0f94a2ea2d7a93a..0000000000000000000000000000000000000000
--- a/dbrepo-ui/composables/authentication-service.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import {jwtDecode} from 'jwt-decode'
-
-export const useAuthenticationService = (): any => {
-
-  function isExpiredToken(token: string): boolean {
-    if (!token) {
-      return false
-    }
-    return tokenToExpiryDate(token) < Date.now()
-  }
-
-  function tokenToExpiryDate(token: string): number {
-    if (!token) {
-      return -1
-    }
-    const exp: number = jwtDecode<Token>(token).exp
-    if (exp) {
-      return exp * 1000
-    }
-    return -1
-  }
-
-  return {isExpiredToken, tokenToExpiryDate}
-}
diff --git a/dbrepo-ui/composables/axios-instance.ts b/dbrepo-ui/composables/axios-instance.ts
index ca7a7b111cf70cf92524f5459808277e4b14144e..cd3737f2bfad4bbd40d15f6cb5cf334a73d0c334 100644
--- a/dbrepo-ui/composables/axios-instance.ts
+++ b/dbrepo-ui/composables/axios-instance.ts
@@ -16,7 +16,7 @@ export const useAxiosInstance = () => {
       baseURL: config.public.api.client
     });
     instance.interceptors.request.use((config) => {
-      const { loggedIn, user, login, logout } = useOidcAuth()
+      const { loggedIn, user } = useOidcAuth()
       if (!loggedIn) {
         return config
       }
diff --git a/dbrepo-ui/composables/user-service.ts b/dbrepo-ui/composables/user-service.ts
index 3425dbaa5c7d77d927798914b8a4fdac6123c166..b90ee34033fb773418a16b1f9ffc9afdbfcc1f4c 100644
--- a/dbrepo-ui/composables/user-service.ts
+++ b/dbrepo-ui/composables/user-service.ts
@@ -1,5 +1,3 @@
-import {jwtDecode} from 'jwt-decode'
-import axios from 'axios'
 import {axiosErrorToApiError} from '@/utils'
 
 export const useUserService = (): any => {
@@ -80,36 +78,6 @@ export const useUserService = (): any => {
     })
   }
 
-  async function refreshToken(refreshToken: string): Promise<KeycloakOpenIdTokenDto> {
-    console.debug('refresh user token')
-    return new Promise<KeycloakOpenIdTokenDto>((resolve, reject) => {
-      const config = useRuntimeConfig()
-      const instance = axios.create({
-        timeout: 90_000,
-        params: {},
-        baseURL: config.public.api.client
-      })
-      instance.put<KeycloakOpenIdTokenDto>('/api/user/token', {refresh_token: refreshToken})
-        .then((response) => {
-          console.info('Refreshed user token')
-          const userStore = useUserStore()
-          // eslint-disable-next-line camelcase
-          const {access_token, refresh_token} = response.data
-          userStore.setToken(access_token)
-          userStore.setRefreshToken(refresh_token)
-          resolve(response.data)
-        }).catch((error) => {
-          console.error('Failed to refresh user token', error)
-          reject(axiosErrorToApiError(error))
-      })
-    })
-  }
-
-  function tokenToRoles(token: string): string[] {
-    const data: Token = jwtDecode<Token>(token)
-    return data.realm_access.roles || []
-  }
-
   function nameIdentifierToNameIdentifierScheme(nameIdentifier: string) {
     if (nameIdentifier.includes('orcid.org')) {
       return 'ORCID'
diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue
index a26c6d2539c86a240a3f4f45818e2780915aff9f..85d530e74daf40dcf3deb47bae5adca762ef99c2 100644
--- a/dbrepo-ui/layouts/default.vue
+++ b/dbrepo-ui/layouts/default.vue
@@ -141,12 +141,30 @@
     </v-form>
     <v-main>
       <v-container>
-        <slot />
+        <div
+          v-cloak>
+          <v-alert
+            v-if="isNotFinishedAccountSetup"
+            border="start"
+            color="info"
+            class="mb-4">
+            {{ $t('pages.settings.subpages.authentication.setup.text') }}
+            <v-btn
+              variant="flat"
+              size="small"
+              to="/user/authentication">
+              {{ $t('pages.settings.subpages.authentication.setup.action') }}
+            </v-btn>
+            .
+          </v-alert>
+        </div>
         <JumboBox
           v-if="error"
           :title="$t(errorCodeKey(error).title, { resource })"
           :subtitle="$t(errorCodeKey(error).subtitle)"
           :text="$t(errorCodeKey(error).text, { resource })" />
+        <slot
+          v-else />
       </v-container>
     </v-main>
   </v-app>
@@ -251,6 +269,15 @@ export default {
     commitShort () {
       return this.$config.public.commit.substr(0, 8)
     },
+    isNotFinishedAccountSetup () {
+      if (!this.cacheUser) {
+        return false
+      }
+      if (!('setup_finished' in this.cacheUser)) {
+        return true
+      }
+      return this.cacheUser.setup_finished === false
+    },
     error () {
       if (this.identifier) {
         return null
diff --git a/dbrepo-ui/locales/en-US.json b/dbrepo-ui/locales/en-US.json
index 07ac0163ef086dd1915d90daf5cf7aabc59695d4..d17da2341db70b270a9cf780773ea7900afa4c03 100644
--- a/dbrepo-ui/locales/en-US.json
+++ b/dbrepo-ui/locales/en-US.json
@@ -794,11 +794,11 @@
           },
           "firstname": {
             "label": "Given Name",
-            "hint": ""
+            "hint": "Managed by your identity provider: {provider}"
           },
           "lastname": {
             "label": "Family Name",
-            "hint": ""
+            "hint": "Managed by your identity provider: {provider}"
           },
           "affiliation": {
             "label": "Affiliation Identifier",
@@ -834,8 +834,12 @@
     "settings": {
       "subpages": {
         "authentication": {
-          "title": "User Password",
-          "subtitle": "Update the user password used for basic authentication with all interfaces",
+          "title": "API Password",
+          "subtitle": "Update the user password used for authentication with all interfaces (e.g. HTTP API, AMQP API, MQTT API)",
+          "setup": {
+            "text": "Finish your account setup by setting the",
+            "action": "API Password"
+          },
           "password": {
             "label": "Password",
             "hint": "Required"
diff --git a/dbrepo-ui/pages/user/authentication.vue b/dbrepo-ui/pages/user/authentication.vue
index 50008d3c5dab56111fb15ae7a6164e1a591af1f9..912c1878c4940556e1dae3e890e4087ca7af5984 100644
--- a/dbrepo-ui/pages/user/authentication.vue
+++ b/dbrepo-ui/pages/user/authentication.vue
@@ -61,7 +61,7 @@
 </template>
 
 <script setup>
-const { loggedIn } = useOidcAuth()
+const { loggedIn, user } = useOidcAuth()
 </script>
 <script>
 import UserToolbar from '@/components/user/UserToolbar.vue'
@@ -113,11 +113,20 @@ export default {
       const userService = useUserService()
       userService.updatePassword(this.cacheUser.uid, {'password': this.password})
         .then(() => {
+          const user = Object.assign({}, this.cacheUser)
+          user.setup_finished = true
+          this.cacheStore.setUser(user)
+          // fixme [mweise]: currently nuxt-oidc-auth cannot refresh the session correctly
           const toast = useToastInstance()
           toast.success(this.$t('success.user.password'))
           this.loadingUpdate = false
         })
-        .catch(() => {
+        .catch(({code, message}) => {
+          const toast = useToastInstance()
+          if (typeof code !== 'string') {
+            return
+          }
+          toast.error(message)
           this.loadingUpdate = false
         })
         .finally(() => {
diff --git a/dbrepo-ui/pages/user/info.vue b/dbrepo-ui/pages/user/info.vue
index 8674c57e2d15abb0be7a50182f2681d5e0f6526e..9c8dbf873d5b7ec4c13a4cde7a42a61790fdc4a3 100644
--- a/dbrepo-ui/pages/user/info.vue
+++ b/dbrepo-ui/pages/user/info.vue
@@ -74,24 +74,24 @@
                 <v-col md="6">
                   <v-text-field
                     v-model="model.firstname"
-                    :disabled="!canModifyInformation"
+                    :disabled="!canModifyInformation || identityProvider"
                     clearable
                     persistent-hint
                     :variant="inputVariant"
                     :label="$t('pages.user.subpages.info.firstname.label')"
-                    :hint="$t('pages.user.subpages.info.firstname.hint')" />
+                    :hint="identityProvider ? $t('pages.user.subpages.info.firstname.hint', { provider: identityProvider }) : ''" />
                 </v-col>
               </v-row>
               <v-row dense>
                 <v-col md="6">
                   <v-text-field
                     v-model="model.lastname"
-                    :disabled="!canModifyInformation"
+                    :disabled="!canModifyInformation || identityProvider"
                     clearable
                     persistent-hint
                     :variant="inputVariant"
                     :label="$t('pages.user.subpages.info.lastname.label')"
-                    :hint="$t('pages.user.subpages.info.lastname.hint')" />
+                    :hint="identityProvider ? $t('pages.user.subpages.info.lastname.hint', { provider: identityProvider }) : ''" />
                 </v-col>
               </v-row>
               <v-row dense>
@@ -191,6 +191,12 @@ export default {
     cacheUser () {
       return this.cacheStore.getUser
     },
+    identityProvider () {
+      if (!this.cacheUser || !('identity_provider' in this.cacheUser)) {
+        return false
+      }
+      return this.cacheUser.identity_provider
+    },
     canModifyInformation () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-upload-service/pom.xml b/dbrepo-upload-service/pom.xml
index 9a5531c0be3e149d22d69f8271fa323a0c7826c5..7e4f27586e27b6a76a5ccd9fccd7f4e1d34b8542 100644
--- a/dbrepo-upload-service/pom.xml
+++ b/dbrepo-upload-service/pom.xml
@@ -11,7 +11,7 @@
     <groupId>at.tuwien</groupId>
     <artifactId>dbrepo-upload-service</artifactId>
     <name>dbrepo-upload-service</name>
-    <version>1.7.0</version>
+    <version>1.6.4</version>
 
     <url>https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/</url>
     <developers>
diff --git a/docker-compose.yml b/docker-compose.yml
index 9176f6404a06df5e30269f4a0dde4d8e4483ebd8..94b5fc30a61c1081e194fd4eb98c45d7af9b261c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -96,7 +96,7 @@ services:
       KEYCLOAK_DATABASE_NAME: "${AUTH_DB_NAME:-keycloak}"
       KEYCLOAK_DATABASE_USER: "${AUTH_DB_USERNAME:-keycloak}"
       KEYCLOAK_DATABASE_PASSWORD: "${AUTH_DB_PASSWORD:-dbrepo}"
-      METADATA_SERVICE_ENDPOINT: "${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}/api/user"
+      METADATA_SERVICE_ENDPOINT: "${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}"
       SYSTEM_USERNAME: "${SYSTEM_USERNAME:-admin}"
       SYSTEM_PASSWORD: "${SYSTEM_PASSWORD:-admin}"
     healthcheck:
diff --git a/helm/dbrepo/Chart.yaml b/helm/dbrepo/Chart.yaml
index b6fa24359ad19fba6595c53a2f64b7f0472d7ff3..9418fa7c6628c3b26154d460bdf02404114dabf8 100644
--- a/helm/dbrepo/Chart.yaml
+++ b/helm/dbrepo/Chart.yaml
@@ -7,14 +7,14 @@ description: Helm Chart for installing DBRepo
 sources:
   - https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services
 type: application
-version: "1.7.0"
-appVersion: "1.7.0"
+version: "1.6.4"
+appVersion: "1.6.4"
 keywords:
   - dbrepo
 maintainers:
   - name: Martin Weise
     email: martin.weise@tuwien.ac.at
-home: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/
+home: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/
 icon: https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/master/dbrepo-ui/public/favicon.png
 dependencies:
   - name: opensearch
diff --git a/helm/dbrepo/README.md b/helm/dbrepo/README.md
index 086b635a63f8e25fc78a25b54315f838ae4097f9..88051e6035586bdc5f27ff4c6c78a4d33e041671 100644
--- a/helm/dbrepo/README.md
+++ b/helm/dbrepo/README.md
@@ -1,17 +1,17 @@
 # DBRepo Helm chart
 
-[DBRepo](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/) is a database repository system that
+[DBRepo](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/) is a database repository system that
 allows researchers to ingest data into a central, versioned repository through common interfaces.
 
 ## TL;DR
 
 Download the
 sample [
-`values.yaml`](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/release-1.7/helm-charts/dbrepo/values.yaml?inline=true)
+`values.yaml`](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/release-1.6/helm-charts/dbrepo/values.yaml?inline=true)
 for your deployment and update the variables, especially `hostname`.
 
 ```bash
-helm install my-release "oci://registry.datalab.tuwien.ac.at/dbrepo/helm/dbrepo" --values ./values.yaml --version "1.7.0"
+helm install my-release "oci://registry.datalab.tuwien.ac.at/dbrepo/helm/dbrepo" --values ./values.yaml --version "1.6.4"
 ```
 
 ## Prerequisites
@@ -28,7 +28,7 @@ helm install my-release "oci://registry.datalab.tuwien.ac.at/dbrepo/helm/dbrepo"
 To install the chart with the release name `my-release`:
 
 ```bash
-helm install my-release "oci://oci://registry.datalab.tuwien.ac.at/dbrepo/helm" --values ./values.yaml --version "1.7.0"
+helm install my-release "oci://oci://registry.datalab.tuwien.ac.at/dbrepo/helm" --values ./values.yaml --version "1.6.4"
 ```
 
 The command deploys DBRepo on the Kubernetes cluster in the default configuration. The Parameters section lists the
@@ -68,7 +68,7 @@ The command removes all the Kubernetes components associated with the chart and
 | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
 | `metadatadb.enabled`                     | Enable the Metadata datadb.                                                                                                            | `true`                                                                 |
 | `metadatadb.host`                        | The hostname for the microservices.                                                                                                    | `metadata-db`                                                          |
-| `metadatadb.extraFlags`                  | Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/data-db/#data | `--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci` |
+| `metadatadb.extraFlags`                  | Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/data-db/#data | `--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci` |
 | `metadatadb.rootUser.user`               | The root username.                                                                                                                     | `root`                                                                 |
 | `metadatadb.rootUser.password`           | The root user password.                                                                                                                | `dbrepo`                                                               |
 | `metadatadb.db.name`                     | The database name.                                                                                                                     | `dbrepo`                                                               |
@@ -101,7 +101,7 @@ The command removes all the Kubernetes components associated with the chart and
 | Name                                 | Description                                                                                                                            | Value                                                                  |
 | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
 | `datadb.host`                        | The hostname for the microservices.                                                                                                    | `data-db`                                                              |
-| `datadb.extraFlags`                  | Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/data-db/#data | `--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci` |
+| `datadb.extraFlags`                  | Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/data-db/#data | `--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci` |
 | `datadb.rootUser.user`               | The root username.                                                                                                                     | `root`                                                                 |
 | `datadb.rootUser.password`           | The root user password.                                                                                                                | `dbrepo`                                                               |
 | `datadb.db.name`                     | The database name.                                                                                                                     | `dbrepo`                                                               |
diff --git a/helm/dbrepo/files/create-event-listener.jar b/helm/dbrepo/files/create-event-listener.jar
index a23243d39509ec3821219e5799a25740c93e2ca1..a970096eeaa5015d9e95064f6b341fffdf8aae5f 100644
Binary files a/helm/dbrepo/files/create-event-listener.jar and b/helm/dbrepo/files/create-event-listener.jar differ
diff --git a/helm/dbrepo/values.yaml b/helm/dbrepo/values.yaml
index 18a0ec69c78cc56f559c56d8c95a63e1c42ab619..d5260781df5e8e68484bf939e5b254e55b7365af 100644
--- a/helm/dbrepo/values.yaml
+++ b/helm/dbrepo/values.yaml
@@ -33,7 +33,7 @@ metadatadb:
   fullnameOverride: metadata-db
   ## @param metadatadb.host The hostname for the microservices.
   host: metadata-db
-  ## @param metadatadb.extraFlags Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/data-db/#data
+  ## @param metadatadb.extraFlags Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/data-db/#data
   extraFlags: "--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci"
   rootUser:
     ## @param metadatadb.rootUser.user The root username.
@@ -118,7 +118,7 @@ authservice:
   setupJob:
     image:
       ## @skip authservice.setupJob.image.name
-      name: registry.datalab.tuwien.ac.at/dbrepo/auth-service-init:1.7.0
+      name: registry.datalab.tuwien.ac.at/dbrepo/auth-service-init:1.6.4
     ## @param authservice.setupJob.resourcesPreset The container resource preset
     resourcesPreset: "nano"
     ## @param authservice.setupJob.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads)
@@ -162,7 +162,7 @@ datadb:
   fullnameOverride: data-db
   ## @param datadb.host The hostname for the microservices.
   host: data-db
-  ## @param datadb.extraFlags Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/data-db/#data
+  ## @param datadb.extraFlags Extra flags to ensure the query store works as intended, ref https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/data-db/#data
   extraFlags: "--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci"
   rootUser:
     ## @param datadb.rootUser.user The root username.
@@ -401,7 +401,7 @@ analyseservice:
   enabled: true
   image:
     ## @skip analyseservice.image.name
-    name: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.7.0
+    name: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.6.4
   ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
   podSecurityContext:
     ## @param analyseservice.podSecurityContext.enabled Enable pods' Security Context
@@ -462,7 +462,7 @@ metadataservice:
   enabled: true
   image:
     ## @skip metadataservice.image.name
-    name: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.0
+    name: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.6.4
   ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
   podSecurityContext:
     ## @param metadataservice.podSecurityContext.enabled Enable pods' Security Context
@@ -559,7 +559,7 @@ dataservice:
   endpoint: http://data-service
   image:
     ## @skip dataservice.image.name
-    name: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.7.0
+    name: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.6.4
   ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
   podSecurityContext:
     ## @param dataservice.podSecurityContext.enabled Enable pods' Security Context
@@ -645,7 +645,7 @@ searchservice:
   endpoint: http://search-service
   image:
     ## @skip searchservice.image.name
-    name: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.7.0
+    name: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.6.4
   ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
   podSecurityContext:
     ## @param searchservice.podSecurityContext.enabled Enable pods' Security Context
@@ -692,7 +692,7 @@ searchservice:
   init:
     image:
       ## @skip searchservice.init.image.name
-      name: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.7.0
+      name: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.6.4
     ## @param searchservice.init.resourcesPreset The container resource preset
     resourcesPreset: "nano"
     ## @param searchservice.init.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads)
@@ -753,7 +753,7 @@ storageservice:
   init:
     image:
       ## @skip storageservice.init.image.name
-      name: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.7.0
+      name: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.6.4
     s3:
       ## @param storageservice.init.s3.endpoint The S3-capable endpoint the microservice connects to.
       endpoint: http://storage-service-s3:8333
@@ -862,7 +862,7 @@ ui:
   enabled: true
   image:
     ## @skip ui.image.name
-    name: registry.datalab.tuwien.ac.at/dbrepo/ui:1.7.0
+    name: registry.datalab.tuwien.ac.at/dbrepo/ui:1.6.4
   ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
   podSecurityContext:
     ## @param ui.podSecurityContext.enabled Enable pods' Security Context
diff --git a/install.sh b/install.sh
index 6de016007f4e4eab84cd331a0a1a7aafca046b38..c5f130f5b7a4b59ea9a8d98e172984e09ae7ff48 100644
--- a/install.sh
+++ b/install.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 # preset
-VERSION="1.7.0"
+VERSION="1.6.4"
 MIN_CPU=8
 MIN_RAM=4
 MIN_MAP_COUNT=262144
diff --git a/lib/python/README.md b/lib/python/README.md
index d4599caee863105b3cebd337d290e0fcb1a5a6c0..443787cbb4cdcb13d0e3ec522d0d9762262000e8 100644
--- a/lib/python/README.md
+++ b/lib/python/README.md
@@ -48,17 +48,17 @@ client.import_table_data(database_id=7, table_id=13, file_name_or_data_frame=df)
 ## Supported Features & Best-Practices
 
 - Manage user
-  account ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/#create-user-account))
+  account ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/#create-user-account))
 - Manage
-  databases ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/usage-overview/#create-database))
+  databases ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/usage-overview/#create-database))
 - Manage database access &
-  visibility ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/#create-database))
+  visibility ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/#create-database))
 - Import
-  dataset ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/#import-dataset))
+  dataset ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/#import-dataset))
 - Create persistent
-  identifiers ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/#assign-database-pid))
+  identifiers ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/#assign-database-pid))
 - Execute
-  queries ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/#export-subset))
+  queries ([docs](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/#export-subset))
 - Get data from tables/views/subsets
 
 ## Configure
diff --git a/lib/python/docs/index.rst b/lib/python/docs/index.rst
index 137dde40c6abbc4ec83fbb3b999c660b94d85efd..6c0c17e37503b68240274f7a6081efc598dea544 100644
--- a/lib/python/docs/index.rst
+++ b/lib/python/docs/index.rst
@@ -6,13 +6,13 @@ Pandas `DataFrame <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame
 provides an object-oriented API as well as low-level access to DBRepo services.
 
 .. note::
-   The SDK has been implemented and documented for DBRepo version 1.7.0, earlier versions may be supported but are not tested for compatibility.
+   The SDK has been implemented and documented for DBRepo version 1.6.4, earlier versions may be supported but are not tested for compatibility.
 
 Quickstart
 ----------
 
 Find numerous quickstart examples on
-the `DBRepo website <https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/api/>`_.
+the `DBRepo website <https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/api/>`_.
 
 AMQP API Client
 -----------
diff --git a/lib/python/pyproject.toml b/lib/python/pyproject.toml
index 65d9c7e3d9c2611bb1bfed55d59f1da01e41e874..b956d6afd0ff66f7ae83f38112b7443001e98da1 100644
--- a/lib/python/pyproject.toml
+++ b/lib/python/pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "dbrepo"
-version = "1.7.0"
+version = "1.6.4"
 description = "DBRepo Python Library"
 keywords = [
     "DBRepo",
@@ -34,7 +34,7 @@ requires = [
 build-backend = "setuptools.build_meta"
 
 [project.urls]
-Homepage = "https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/"
-Documentation = "https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/python/"
+Homepage = "https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/"
+Documentation = "https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/python/"
 Issues = "https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues"
 Source = "https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/"
\ No newline at end of file
diff --git a/lib/python/setup.py b/lib/python/setup.py
index 4fff48185b04734932caad08d4aa06583730a52f..53f4832404814c0e1468082add0b090ea106de84 100644
--- a/lib/python/setup.py
+++ b/lib/python/setup.py
@@ -2,9 +2,9 @@
 from distutils.core import setup
 
 setup(name="dbrepo",
-      version="1.7.0",
+      version="1.6.4",
       description="A library for communicating with DBRepo",
-      url="https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/",
+      url="https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/",
       author="Martin Weise",
       license="Apache-2.0",
       author_email="martin.weise@tuwien.ac.at",
diff --git a/mkdocs.yml b/mkdocs.yml
index 536eed294ed4f5683d601f2e0a460a8ade5267d1..5ec3a92799fba08d9299e466e780422f20bf1a65 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,5 +1,5 @@
 site_name: Database Repository
-site_url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/
+site_url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/
 repo_url: https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services
 repo_name: fda-services
 site_author: Research Unit Data Science, Technische Universit&auml;t Wien
@@ -120,9 +120,9 @@ markdown_extensions:
         custom_icons:
           - .docs/overrides/.icons
 extra:
-  homepage: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/
+  homepage: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/
   version:
-    default: 1.7
+    default: 1.6
     provider: mike
   social:
     - icon: simple/artifacthub
diff --git a/sonar-project.properties b/sonar-project.properties
index 0d25b112d7133494be618d3f61e3e17a2c415e94..e118258889d85c43894ea7493ba9c16bcc83c5fa 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -2,7 +2,7 @@
 sonar.projectKey=fair-data-austria-db-repository_fda-services_a57fa043-ab99-4cdd-a721-162d9a916d77
 sonar.host.url=https://s39.datalab.tuwien.ac.at
 # project
-sonar.projectVersion=1.7.0
+sonar.projectVersion=1.6.4
 # general
 sonar.qualitygate.wait=true
 sonar.projectCreation.mainBranchName=master
diff --git a/versions.json b/versions.json
index 95ca2a62a6fec4b73534bc3d6981b1bcdfd8fff2..b42a3dfd7d8ac8f78858923d4ac6d89906452771 100644
--- a/versions.json
+++ b/versions.json
@@ -1,9 +1,4 @@
 [
-  {
-    "version": "1.7",
-    "title": "1.7",
-    "aliases": []
-  },
   {
     "version": "1.6",
     "title": "1.6",