diff --git a/fda-authentication-service/Dockerfile b/fda-authentication-service/Dockerfile
index a68b28577fa9c76437921607e1a4a0706018c916..f687467497b42f78b264aa986e77ae7fdf47da92 100644
--- a/fda-authentication-service/Dockerfile
+++ b/fda-authentication-service/Dockerfile
@@ -16,12 +16,21 @@ RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysi
 RUN /opt/keycloak/bin/kc.sh build
 
 ###### SECOND STAGE ######
+FROM redhat/ubi9-minimal as binary
+
+RUN microdnf update -y && microdnf install -y curl-minimal libcurl-minimal
+
+###### THIRD STAGE ######
 FROM keycloak/keycloak:21.0 as runtime
 COPY --from=config /opt/keycloak/ /opt/keycloak/
+COPY --from=binary /usr/lib64 /usr/lib64
+COPY --from=binary /usr/bin/curl /usr/bin/curl
 
 USER root
 
-COPY ./dbrepo-realm.json /dbrepo-realm.json
+COPY ./dbrepo-realm.json /opt/keycloak/data/import/dbrepo-realm.json
+COPY ./service-register.sh /app/service-register.sh
+COPY ./docker-entrypoint.sh /app/docker-entrypoint.sh
 
 ENV METADATA_USERNAME=root
 ENV METADATA_PASSWORD=dbrepo
@@ -32,10 +41,8 @@ ENV KC_DB_USERNAME=${METADATA_USERNAME}
 ENV KC_DB_PASSWORD=${METADATA_PASSWORD}
 ENV KC_HOSTNAME=localhost
 
-ENV KEYCLOAK_IMPORT=/dbrepo-realm.json
+ENV KEYCLOAK_IMPORT=/opt/keycloak/data/import/dbrepo-realm.json
 ENV KEYCLOAK_ADMIN=keycloak
 ENV KEYCLOAK_ADMIN_PASSWORD=keycloak
 
-USER 1000
-
-ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]
+ENTRYPOINT ["bash", "/app/docker-entrypoint.sh"]
diff --git a/fda-authentication-service/README.md b/fda-authentication-service/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..71ea75fc91dd2706f5576db7ff730a526097b566
--- /dev/null
+++ b/fda-authentication-service/README.md
@@ -0,0 +1,17 @@
+# Authentication Service
+
+Attention: self-enrollment is not possible anymore (Keycloak)
+
+## Create Users
+
+- Visit [localhost:8443](https://localhost:8443) and login with default admin credentials `keycloak:keycloak`
+- Select realm `dbrepo`
+- Visit `Users` -> `Create` and set a non-temporary password
+
+## API
+
+### Create Token
+
+```console
+curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d '{"client_id":"dbrepo-client","username":"ABC","password":"XYZ","client_secret":"123","grant_type":"password","scope":"openid"}'
+```
diff --git a/fda-authentication-service/dbrepo-realm.json b/fda-authentication-service/dbrepo-realm.json
index b565bac8136c23e7081ecc7f2961bc71697cde24..1e71c9a8a5425a9f92a13285d9d1dc31720c48df 100644
--- a/fda-authentication-service/dbrepo-realm.json
+++ b/fda-authentication-service/dbrepo-realm.json
@@ -26,7 +26,7 @@
   "oauth2DeviceCodeLifespan" : 600,
   "oauth2DevicePollingInterval" : 5,
   "enabled" : true,
-  "sslRequired" : "external",
+  "sslRequired" : "none",
   "registrationAllowed" : false,
   "registrationEmailAsUsername" : false,
   "rememberMe" : false,
@@ -375,7 +375,7 @@
   "otpPolicyLookAheadWindow" : 1,
   "otpPolicyPeriod" : 30,
   "otpPolicyCodeReusable" : false,
-  "otpSupportedApplications" : [ "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName", "totpAppFreeOTPName" ],
+  "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName" ],
   "webAuthnPolicyRpEntityName" : "keycloak",
   "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
   "webAuthnPolicyRpId" : "",
@@ -495,7 +495,9 @@
     "publicClient" : true,
     "frontchannelLogout" : false,
     "protocol" : "openid-connect",
-    "attributes" : { },
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
     "authenticationFlowBindingOverrides" : { },
     "fullScopeAllowed" : false,
     "nodeReRegistrationTimeout" : 0,
@@ -521,7 +523,9 @@
     "publicClient" : false,
     "frontchannelLogout" : false,
     "protocol" : "openid-connect",
-    "attributes" : { },
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
     "authenticationFlowBindingOverrides" : { },
     "fullScopeAllowed" : false,
     "nodeReRegistrationTimeout" : 0,
@@ -564,6 +568,22 @@
     "authenticationFlowBindingOverrides" : { },
     "fullScopeAllowed" : true,
     "nodeReRegistrationTimeout" : -1,
+    "protocolMappers" : [ {
+      "id" : "6ff49409-9800-4d86-bee4-c8e88aaa313e",
+      "name" : "User Theme",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "aggregate.attrs" : "true",
+        "multivalued" : "false",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "theme_dark",
+        "id.token.claim" : "false",
+        "access.token.claim" : "true",
+        "claim.name" : "theme_dark"
+      }
+    } ],
     "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
     "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
   }, {
@@ -586,7 +606,9 @@
     "publicClient" : false,
     "frontchannelLogout" : false,
     "protocol" : "openid-connect",
-    "attributes" : { },
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
     "authenticationFlowBindingOverrides" : { },
     "fullScopeAllowed" : false,
     "nodeReRegistrationTimeout" : 0,
@@ -656,7 +678,8 @@
       "consentRequired" : false,
       "config" : {
         "id.token.claim" : "true",
-        "access.token.claim" : "true"
+        "access.token.claim" : "true",
+        "userinfo.token.claim" : "true"
       }
     } ]
   }, {
@@ -928,6 +951,7 @@
       "consentRequired" : false,
       "config" : {
         "multivalued" : "true",
+        "userinfo.token.claim" : "true",
         "user.attribute" : "foo",
         "id.token.claim" : "true",
         "access.token.claim" : "true",
@@ -1178,7 +1202,7 @@
       "subType" : "authenticated",
       "subComponents" : { },
       "config" : {
-        "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper" ]
+        "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper" ]
       }
     }, {
       "id" : "3ab11d74-5e76-408a-b85a-26bf8950f979",
@@ -1187,7 +1211,7 @@
       "subType" : "anonymous",
       "subComponents" : { },
       "config" : {
-        "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "saml-user-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper" ]
+        "allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper" ]
       }
     } ],
     "org.keycloak.keys.KeyProvider" : [ {
@@ -1239,7 +1263,7 @@
   "internationalizationEnabled" : false,
   "supportedLocales" : [ ],
   "authenticationFlows" : [ {
-    "id" : "9c0078f1-0f2e-47c0-8cd6-78851acb1504",
+    "id" : "be20e5ff-4ce9-48eb-b9e0-b948f04fbfe4",
     "alias" : "Account verification options",
     "description" : "Method with which to verity the existing account",
     "providerId" : "basic-flow",
@@ -1261,7 +1285,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "ba90b374-8502-4a56-af42-f3a2aa931d32",
+    "id" : "029af9ca-193c-47cc-a6be-2361f9b08b69",
     "alias" : "Authentication Options",
     "description" : "Authentication options.",
     "providerId" : "basic-flow",
@@ -1290,7 +1314,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "3bd266c5-b1fd-4f50-95f3-70e9e4e47fda",
+    "id" : "aaaf8559-3c0e-4e27-9a44-8322c9b14874",
     "alias" : "Browser - Conditional OTP",
     "description" : "Flow to determine if the OTP is required for the authentication",
     "providerId" : "basic-flow",
@@ -1312,7 +1336,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "11e6957d-ea18-4657-8639-fcf935eac694",
+    "id" : "ccee98c6-2523-481a-8a35-6465d644e97c",
     "alias" : "Direct Grant - Conditional OTP",
     "description" : "Flow to determine if the OTP is required for the authentication",
     "providerId" : "basic-flow",
@@ -1334,7 +1358,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "c5791aee-2c8c-4077-bc02-b57d6bdfa2c8",
+    "id" : "b5148d25-047f-48cb-8e11-643cc2899dc1",
     "alias" : "First broker login - Conditional OTP",
     "description" : "Flow to determine if the OTP is required for the authentication",
     "providerId" : "basic-flow",
@@ -1356,7 +1380,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "ffd20971-0d90-44d9-943c-a1aaef135be7",
+    "id" : "9f8ca1e9-8367-45b0-9ada-3da48daf16c9",
     "alias" : "Handle Existing Account",
     "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
     "providerId" : "basic-flow",
@@ -1378,7 +1402,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "9593a3cc-c7fd-40a4-95fb-05a7b06ad04c",
+    "id" : "395d349a-2e8e-454d-8caa-009e304f2b46",
     "alias" : "Reset - Conditional OTP",
     "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
     "providerId" : "basic-flow",
@@ -1400,7 +1424,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "7a81f226-53f3-407d-99cf-483b60eba0a9",
+    "id" : "22103f15-a3ae-46bb-8063-2b2308bade2a",
     "alias" : "User creation or linking",
     "description" : "Flow for the existing/non-existing user alternatives",
     "providerId" : "basic-flow",
@@ -1423,7 +1447,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "90ab1710-d1e5-4f37-8c0e-5dc4acabf82b",
+    "id" : "5157fbeb-d121-434c-808f-06fcbf634880",
     "alias" : "Verify Existing Account by Re-authentication",
     "description" : "Reauthentication of existing account",
     "providerId" : "basic-flow",
@@ -1445,7 +1469,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "ede4d86a-92d4-4803-bbb4-753f0fa7d33e",
+    "id" : "1c52aa5a-6d1b-4e47-b1b3-d747dc0bcf24",
     "alias" : "browser",
     "description" : "browser based authentication",
     "providerId" : "basic-flow",
@@ -1481,7 +1505,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "aac32d41-adc7-4a06-948e-660dcb305218",
+    "id" : "135f84a3-208d-4764-b8df-68c64ada4ac7",
     "alias" : "clients",
     "description" : "Base authentication for clients",
     "providerId" : "client-flow",
@@ -1517,7 +1541,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "ade1ad88-2db7-4986-9cfa-b948e0808655",
+    "id" : "5b647e08-40e0-45d7-9327-af31f7387abe",
     "alias" : "direct grant",
     "description" : "OpenID Connect Resource Owner Grant",
     "providerId" : "basic-flow",
@@ -1546,7 +1570,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "570ea615-bd6b-49f2-abb3-e6bd27f44e0d",
+    "id" : "92438146-c5d5-4059-9e0e-f4532ce4ef63",
     "alias" : "docker auth",
     "description" : "Used by Docker clients to authenticate against the IDP",
     "providerId" : "basic-flow",
@@ -1561,7 +1585,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "e878d8d8-0da7-4682-9124-483e8b8c6b59",
+    "id" : "c47ac645-5877-44b3-b12f-fbe0d01f8bc4",
     "alias" : "first broker login",
     "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
     "providerId" : "basic-flow",
@@ -1584,7 +1608,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "83aec897-602b-40c0-8df8-14abdba141bf",
+    "id" : "f60f7d34-9311-4d6d-ac84-05de99fd42e6",
     "alias" : "forms",
     "description" : "Username, password, otp and other auth forms.",
     "providerId" : "basic-flow",
@@ -1606,7 +1630,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "ddb3f5d4-6395-4c09-ba1a-593dd3c85c16",
+    "id" : "ed2df37f-c19b-4356-9b7c-70c4e7e3f886",
     "alias" : "http challenge",
     "description" : "An authentication flow based on challenge-response HTTP Authentication Schemes",
     "providerId" : "basic-flow",
@@ -1628,7 +1652,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "3e707d1d-bfa5-4e54-a2e5-cccadad9e75b",
+    "id" : "1c515cf9-c6fa-44ba-be4c-3956e1a6bdda",
     "alias" : "registration",
     "description" : "registration flow",
     "providerId" : "basic-flow",
@@ -1644,7 +1668,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "ed0157b5-6d81-47c9-8555-7082e92d5a62",
+    "id" : "644fd203-6727-4797-a62f-82accc38a990",
     "alias" : "registration form",
     "description" : "registration form",
     "providerId" : "form-flow",
@@ -1680,7 +1704,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "c61c0070-feba-4770-b17f-7dfa3ba774ef",
+    "id" : "bf1690f9-daf5-4f9e-9ac2-51e5e3388f5a",
     "alias" : "reset credentials",
     "description" : "Reset credentials for a user if they forgot their password or something",
     "providerId" : "basic-flow",
@@ -1716,7 +1740,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "4a928f9c-461e-437a-8eb8-3f120bddbb98",
+    "id" : "b2b85b81-f205-4136-988e-c0b984e45f14",
     "alias" : "saml ecp",
     "description" : "SAML ECP Profile Authentication Flow",
     "providerId" : "basic-flow",
@@ -1732,13 +1756,13 @@
     } ]
   } ],
   "authenticatorConfig" : [ {
-    "id" : "03d31f7c-8f00-4d23-b0fc-4413c20d64c9",
+    "id" : "208c6a70-7e63-45bf-99a4-d7867f61540d",
     "alias" : "create unique user config",
     "config" : {
       "require.password.update.after.registration" : "false"
     }
   }, {
-    "id" : "96db8eb0-e810-428e-a814-d753c8b086c6",
+    "id" : "6301fcc4-bfe0-49c1-888e-7b01ffcbec34",
     "alias" : "review profile config",
     "config" : {
       "update.profile.on.first.login" : "missing"
diff --git a/fda-authentication-service/docker-entrypoint.sh b/fda-authentication-service/docker-entrypoint.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ca82a7badaf62a1fe8aef07e992df833d17755b6
--- /dev/null
+++ b/fda-authentication-service/docker-entrypoint.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+/app/service-register.sh authentication-service 8080
+(while sleep 60; do bash /app/service-register.sh authentication-service 8080; done) &
+
+/opt/keycloak/bin/kc.sh start-dev --import-realm
diff --git a/fda-authentication-service/service-register.sh b/fda-authentication-service/service-register.sh
new file mode 100755
index 0000000000000000000000000000000000000000..72734426bbe787ca64d394dd514b79f4561cf2c6
--- /dev/null
+++ b/fda-authentication-service/service-register.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+# $1 is used as the host name.
+
+EUREKA_HOST="discovery-service"
+EUREKA_PORT="9090"
+EUREKA_URI="http://$EUREKA_HOST:$EUREKA_PORT"
+
+SERVICE_NAME="$1"
+SERVICE_PROTOCOL="http"
+SERVICE_HOST="$1"
+SERVICE_PORT="${2:-9000}"
+
+SERVICE_URI="$SERVICE_PROTOCOL://$SERVICE_HOST:$SERVICE_PORT"
+HOME_URI="$SERVICE_URI/realms/dbrepo"
+HEALTH_URI="$SERVICE_URI/health"
+
+# This is the URL shown in the "status" field in the
+# instances section of the eureka dashboard.
+#
+# It's up to you to decide what the URL points to. Some
+# information or status endpoint might be good.
+STATUS_URI="$SERVICE_URI/health"
+
+# This is the name displayed to the right of the status
+# on the eureka dashbard. If the app (FAKE_SERVICE) is
+# registered with more than one hostname, they will be
+# displayed as a comma-separated list. This hostname
+# is part of the heartbeat message.
+#
+# If you'll have more than one host per service,
+# make sure they have different host names.
+HOST_NAME="${1:-fake01}"
+
+# Everyone of these parameters seem to be required. I don't know
+# anything about secureVipAddress and vipAddress.
+#
+# dataCenterInfo must have a name of "MyOwn" or "Amazon".
+#
+# status can be UP, DOWN, STARTING, OUT_OF_SERVICE, UNKNOWN.
+#   if the registration status is STARTING, then the service
+#   will never be evicted. Also, simply sending a Heartbeat
+#   does not change the status.
+#
+# The metadata fields can be any information you want associated
+# with a service. I recommend keeping it short.
+#
+
+cat <<EOF > /tmp/json.json
+{
+  "instance": {
+    "instanceId": "$SERVICE_NAME:$SERVICE_NAME:$SERVICE_PORT",
+    "hostName": "$HOST_NAME",
+    "app": "$SERVICE_NAME",
+    "ipAddr": "$SERVICE_HOST",
+    "status": "UP",
+    "dataCenterInfo": {
+      "@class": "com.netflix.appinfo.MyDataCenterInfo",
+      "name": "MyOwn"
+    },
+    "healthCheckUrl": "$HEALTH_URI",
+    "homePageUrl": "$HOME_URI",
+    "leaseInfo": {
+      "evictionDurationInSecs": 90
+    },
+    "metadata": {
+      "zone": "default",
+      "management.port": "8443"
+    },
+    "port": {
+      "\$": "$SERVICE_PORT",
+      "@enabled": "true"
+    },
+    "securePort": {
+      "\$": "$SERVICE_PORT",
+      "@enabled": "false"
+    },
+    "vipAddress": "$SERVICE_HOST",
+    "secureVipAddress": "$SERVICE_HOST",
+    "statusPageUrl": "$STATUS_URI"
+  }
+}
+EOF
+
+curl --header "content-type: application/json" --data-binary @/tmp/json.json --silent $EUREKA_URI/eureka/apps/$SERVICE_NAME
diff --git a/fda-ui/.env.example b/fda-ui/.env.example
index 00f7fc8871f021c34ef36a11ea99a513cc027a58..9498c087a5670bd0e2a77ba52455abdac3e8b508 100644
--- a/fda-ui/.env.example
+++ b/fda-ui/.env.example
@@ -5,6 +5,6 @@ NODE_ENV=dev
 API="http://localhost:9095"
 BROKER_USERNAME=fda
 BROKER_PASSWORD=fda
-SANDBOX=true
+SANDBOX=false
 SHARED_FILESYSTEM=/tmp
 CLIENT_SECRET=
diff --git a/fda-ui/layouts/default.vue b/fda-ui/layouts/default.vue
index 73a9829d61d6489c0d0d4ff0792cb649150df8ba..9ba45c2b7351add71e11c935a0e89af64b1ae0d3 100644
--- a/fda-ui/layouts/default.vue
+++ b/fda-ui/layouts/default.vue
@@ -61,13 +61,6 @@
           @click="login">
           <v-icon left>mdi-login</v-icon> Login
         </v-btn>
-        <v-btn
-          v-if="!token"
-          class="mr-2"
-          color="primary"
-          to="/signup">
-          <v-icon left>mdi-account-plus</v-icon> Signup
-        </v-btn>
         <v-btn v-if="user" to="/user" plain>
           {{ user.username }} <sup v-if="isDeveloper">
             <v-tooltip bottom>
diff --git a/fda-ui/nuxt.config.js b/fda-ui/nuxt.config.js
index d537faae8af0e10bf79da71eb8386375309f5a6f..9327472ae752ff3efb05dd23cab75300030936f0 100644
--- a/fda-ui/nuxt.config.js
+++ b/fda-ui/nuxt.config.js
@@ -43,7 +43,7 @@ export default {
   plugins: [
     { src: '@/plugins/toast', ssr: false },
     { src: '@/plugins/vendors', ssr: false },
-    { src: '@/plugins/axios' },
+    { src: '@/plugins/axios', ssr: false },
     { src: '@/plugins/vuex-persist.js', mode: 'client' }
   ],
 
@@ -87,7 +87,6 @@ export default {
   },
 
   proxy: {
-    '/auth': process.env.KEYCLOAK || 'https://localhost:8443',
     '/api': process.env.API || 'http://localhost:9095',
     '/pid': {
       target: process.env.API + '/api' || 'http://localhost:9095/api',
diff --git a/fda-ui/package.json b/fda-ui/package.json
index 7d4b5cb16b5aecfe883850a9afede905ec516847..e0e1c96189fd7d7bf0604df48d5fa0f11324266e 100644
--- a/fda-ui/package.json
+++ b/fda-ui/package.json
@@ -42,9 +42,11 @@
     "node-fetch": "^2.6.1",
     "nuxt": "^2.15.8",
     "nuxt-i18n": "^6.15.4",
+    "qs": "^6.11.1",
     "sql-formatter": "^6.1.1",
     "vue": "^2.6.12",
     "vue-chartjs": "^4.1.1",
+    "vue-jwt-decode": "^0.1.0",
     "vue-toast-notification": "^0.5.4",
     "vue2-ace-editor": "^0.0.15",
     "vuetify": "^2.6.9",
diff --git a/fda-ui/pages/login.vue b/fda-ui/pages/login.vue
index 9457e6eb65394b2ed68aa824dcc9013df35e7561..5d61dd88f1a870cc102ca627c9261ffe32f84c72 100644
--- a/fda-ui/pages/login.vue
+++ b/fda-ui/pages/login.vue
@@ -56,6 +56,8 @@
 </template>
 
 <script>
+import VueJwtDecode from 'vue-jwt-decode'
+import qs from 'qs'
 export default {
   data () {
     return {
@@ -67,7 +69,8 @@ export default {
         username: null,
         password: null,
         grant_type: 'password',
-        client_secret: this.$config.client_secret
+        client_secret: this.$config.client_secret,
+        scope: 'openid'
       }
     }
   },
@@ -88,6 +91,11 @@ export default {
       return {
         headers: { Authorization: `Bearer ${this.token}` }
       }
+    },
+    keycloakConfig () {
+      return {
+        headers: { ContentType: 'application/x-www-form-urlencoded' }
+      }
     }
   },
   mounted () {
@@ -106,11 +114,23 @@ export default {
     async login () {
       try {
         this.loading = true
-        const res = await this.$axios.post('/auth/realms/dbrepo/protocol/openid-connect/token', this.loginAccount)
+        const res = await this.$axios.post('/api/auth/realms/dbrepo/protocol/openid-connect/token', qs.stringify(this.loginAccount), this.keycloakConfig)
         console.debug('login user', res.data)
-        const { token } = res.data
-        this.$store.commit('SET_TOKEN', token)
-        await this.setUser()
+        // eslint-disable-next-line camelcase
+        const { access_token } = res.data
+        this.$store.commit('SET_TOKEN', access_token)
+        const data = VueJwtDecode.decode(access_token)
+        const user = {
+          id: data.sub,
+          firstname: data.given_name,
+          lastname: data.family_name,
+          username: data.preferred_username,
+          theme_dark: data.theme_dark,
+          email_verified: data.email_verified
+        }
+        this.$store.commit('SET_USER', user)
+        this.$vuetify.theme.dark = false
+        await this.$router.push({ path: this.$route.query.redirect ? this.$route.query.redirect : '/container' })
       } catch (error) {
         const { status } = error.response
         if (status === 418) {
@@ -126,19 +146,6 @@ export default {
         this.loading = false
       }
     },
-    async setUser () {
-      try {
-        const res = await this.$axios.put('/api/auth', {}, this.config)
-        this.$store.commit('SET_USER', res.data)
-        this.$vuetify.theme.dark = res.data.theme_dark
-        await this.$router.push({ path: this.$route.query.redirect ? this.$route.query.redirect : '/container' })
-      } catch (error) {
-        const { message } = error.response
-        console.error('Failed to load user information', error)
-        this.$toast.error('Failed to load user information: ' + message)
-      }
-      this.loading = false
-    },
     signup () {
       this.$router.push('/signup')
     },
diff --git a/fda-ui/pages/signup.vue b/fda-ui/pages/signup.vue
deleted file mode 100644
index 2b88602a4e7b006558a5f5759771a9c2dcbde622..0000000000000000000000000000000000000000
--- a/fda-ui/pages/signup.vue
+++ /dev/null
@@ -1,172 +0,0 @@
-<template>
-  <div>
-    <v-form ref="form" v-model="valid" @submit.prevent="submit">
-      <v-card flat tile>
-        <v-card-title>
-          Create Account
-        </v-card-title>
-        <v-card-text>
-          <v-alert
-            v-if="mailVerify"
-            border="left"
-            color="info">
-            Before you can use the repository, you will need to <i>confirm</i> your email address, make sure to check your spam folder.
-          </v-alert>
-          <v-row dense>
-            <v-col sm="6">
-              <v-text-field
-                v-model="createAccount.email"
-                type="email"
-                autocomplete="off"
-                autofocus
-                required
-                name="email"
-                :rules="[v => !!v || $t('Required')]"
-                hint="e.g. max.mustermann@work.com"
-                label="Work E-Mail Address *" />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col sm="6">
-              <v-text-field
-                v-model="createAccount.username"
-                autocomplete="off"
-                required
-                name="username"
-                :rules="[v => !!v || $t('Required'),
-                         v => /^[a-z0-9]{3,}$/.test(v) || $t('Only lowercase letters, min. 3 length')]"
-                hint="e.g. mmustermann"
-                label="Username *" />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col sm="6">
-              <v-text-field
-                v-model="createAccount.password"
-                autocomplete="off"
-                required
-                name="password"
-                :rules="[v => !!v || $t('Required')]"
-                type="password"
-                label="Password *" />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col sm="6">
-              <v-text-field
-                v-model="password2"
-                autocomplete="off"
-                required
-                name="password-confirm"
-                :rules="[v => !!v || $t('Required'), v => (!!v && v) === createAccount.password || $t('Not matching!')]"
-                type="password"
-                label="Repeat Password *" />
-            </v-col>
-          </v-row>
-          <v-row v-if="sandbox" dense>
-            <v-col sm="6">
-              <v-checkbox
-                v-model="consent"
-                required
-                name="consent"
-                :rules="[v => !!v || $t('Required')]"
-                label="I understand the warning and do not use production data" />
-            </v-col>
-          </v-row>
-          <v-row v-if="sandbox" dense>
-            <v-col sm="6">
-              <v-checkbox
-                v-model="privacy"
-                required
-                name="privacy"
-                :rules="[v => !!v || $t('Required')]"
-                label="I have read and accept the privacy statement" />
-            </v-col>
-          </v-row>
-        </v-card-text>
-        <v-card-text>
-          <v-btn
-            id="login"
-            :disabled="!valid"
-            color="primary"
-            type="submit"
-            name="submit"
-            :loading="loading"
-            @click="register">
-            Submit
-          </v-btn>
-        </v-card-text>
-      </v-card>
-    </v-form>
-  </div>
-</template>
-
-<script>
-export default {
-  data () {
-    return {
-      loading: false,
-      error: false, // XXX: `error` is never changed
-      valid: false,
-      password2: null,
-      privacy: false,
-      consent: false,
-      createAccount: {
-        username: null,
-        email: null,
-        password: null
-      }
-    }
-  },
-  computed: {
-    loadingColor () {
-      return this.error ? 'red lighten-2' : 'primary'
-    },
-    sandbox () {
-      return this.$config.sandbox
-    },
-    mailVerify () {
-      return this.$config.mailVerify
-    }
-  },
-  methods: {
-    submit () {
-      this.$refs.form.validate()
-    },
-    async register () {
-      const url = '/api/user'
-      try {
-        this.loading = true
-        const res = await this.$axios.post(url, this.createAccount)
-        console.debug('create user', res.data)
-        this.$toast.success('Success. Check your inbox!')
-        this.$router.push('/login')
-      } catch (err) {
-        if (err.response !== undefined && err.response.status !== undefined) {
-          if (err.response.status === 417) {
-            this.$toast.error('This e-mail address is taken')
-            console.error('email taken', err)
-            this.loading = false
-            return
-          }
-          if (err.response.status === 409) {
-            this.$toast.error('This username is taken')
-            console.error('username taken', err)
-            this.loading = false
-            return
-          }
-          if (err.response.status === 428) {
-            this.$toast.warning('Account was created but the server failed to send a mail')
-            console.warn('email sending failed', err)
-            this.loading = false
-            return
-          }
-        }
-        console.error('create user failed', err)
-        this.$toast.error('Failed to create user')
-      }
-      this.loading = false
-    }
-  }
-}
-</script>
diff --git a/fda-ui/yarn.lock b/fda-ui/yarn.lock
index 421217b621020514a9f20925a4ba668b5d2735c6..c13f79ce87b2b72bc9c6e59bcb8157db87582c41 100644
--- a/fda-ui/yarn.lock
+++ b/fda-ui/yarn.lock
@@ -2133,6 +2133,15 @@
     postcss "^8.4.14"
     source-map "^0.6.1"
 
+"@vue/compiler-sfc@2.7.14":
+  version "2.7.14"
+  resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz#3446fd2fbb670d709277fc3ffa88efc5e10284fd"
+  integrity sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==
+  dependencies:
+    "@babel/parser" "^7.18.4"
+    postcss "^8.4.14"
+    source-map "^0.6.1"
+
 "@vue/component-compiler-utils@^2.3.1":
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz#aa46d2a6f7647440b0b8932434d22f12371e543b"
@@ -10205,6 +10214,13 @@ qs@6.10.3:
   dependencies:
     side-channel "^1.0.4"
 
+qs@^6.11.1:
+  version "6.11.1"
+  resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f"
+  integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==
+  dependencies:
+    side-channel "^1.0.4"
+
 qs@^6.9.4:
   version "6.11.0"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
@@ -12242,6 +12258,13 @@ vue-i18n@^8.25.0:
   resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.27.2.tgz#b649a65ff42b7d1a482679b732902f889965a068"
   integrity sha512-QVzn7u2WVH8F7eSKIM00lujC7x1mnuGPaTnDTmB01Hd709jDtB9kYtBqM+MWmp5AJRx3gnqAdZbee9MelqwFBg==
 
+vue-jwt-decode@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/vue-jwt-decode/-/vue-jwt-decode-0.1.0.tgz#f9caf7b9030d5459cc567b1c3117d9d1f291458f"
+  integrity sha512-4iP0NzYHkAF7G13tYPc/nudk4oNpB8GCVZupc7lekxXok1XKEgefNaGTpDT14g7RKe5H9GaMphPduDj4UVfZwQ==
+  dependencies:
+    vue "^2.3.3"
+
 vue-loader@^15.9.7:
   version "15.10.0"
   resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.10.0.tgz#2a12695c421a2a2cc2138f05a949d04ed086e38b"
@@ -12317,6 +12340,14 @@ vue2-ace-editor@^0.0.15:
   dependencies:
     brace "^0.11.0"
 
+vue@^2.3.3:
+  version "2.7.14"
+  resolved "https://registry.yarnpkg.com/vue/-/vue-2.7.14.tgz#3743dcd248fd3a34d421ae456b864a0246bafb17"
+  integrity sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==
+  dependencies:
+    "@vue/compiler-sfc" "2.7.14"
+    csstype "^3.1.0"
+
 vue@^2.6.12:
   version "2.7.10"
   resolved "https://registry.yarnpkg.com/vue/-/vue-2.7.10.tgz#ae516cc6c88e1c424754468844218fdd5e280f40"