diff --git a/dbrepo-ui/components/JumboBox.vue b/dbrepo-ui/components/JumboBox.vue
index d2b804f819f22782ba4895c601c8b2ea118ce4e3..5a26ec6139bff1a1b816c2acce1dc3fb08cd7207 100644
--- a/dbrepo-ui/components/JumboBox.vue
+++ b/dbrepo-ui/components/JumboBox.vue
@@ -21,6 +21,7 @@
     </v-row>
   </div>
 </template>
+
 <script>
 export default {
   props: {
diff --git a/dbrepo-ui/components/Loading.vue b/dbrepo-ui/components/Loading.vue
index 743701ab6724dba40d6baa0cb0cfafcb26061556..84094bfef8773aa306d977e6f0f7cbb4cca1dde9 100644
--- a/dbrepo-ui/components/Loading.vue
+++ b/dbrepo-ui/components/Loading.vue
@@ -7,6 +7,7 @@
       indeterminate />
   </v-list-item-title>
 </template>
+
 <script>
 export default {
   props: {
diff --git a/dbrepo-ui/components/OntologiesList.vue b/dbrepo-ui/components/OntologiesList.vue
deleted file mode 100644
index 432d26e428eed1085d2806ed371342b445822599..0000000000000000000000000000000000000000
--- a/dbrepo-ui/components/OntologiesList.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-<template>
-  <div>
-    <v-card
-      v-for="(ontology, idx) in ontologies"
-      :key="idx"
-      :to="`/semantic/ontology/${ontology.id}`"
-      variant="flat"
-      rounded="0">
-      <v-divider
-        class="mx-4" />
-      <v-card-title>
-        {{ ontology.prefix }}
-      </v-card-title>
-      <v-card-subtitle>
-        {{ ontology.uri }}
-      </v-card-subtitle>
-      <v-card-text>
-        <div
-          class="db-tags">
-          <v-chip
-            v-if="ontology.sparql"
-            size="small"
-            color="success"
-            text="SPARQL"
-            variant="outlined" />
-          <v-chip
-            v-if="ontology.rdf"
-            size="small"
-            text="RDF"
-            variant="outlined" />
-        </div>
-      </v-card-text>
-    </v-card>
-  </div>
-</template>
-
-<script setup>
-</script>
-<script>
-import { useCacheStore } from '@/stores/cache.js'
-
-export default {
-  data () {
-    return {
-      cacheStore: useCacheStore()
-    }
-  },
-  computed: {
-    ontologies () {
-      return []
-    }
-  },
-  mounted () {
-  },
-  methods: {
-  }
-}
-</script>
-
-<style>
-.db-tags .v-chip:not(:first-child) {
-  margin-left: 4px;
-}
-</style>
diff --git a/dbrepo-ui/components/ResourceStatus.vue b/dbrepo-ui/components/ResourceStatus.vue
index 5167d899ea6e73c150db478f8fc3b063a3ba1e12..d766f37660ade64b0a74e7b9b74ca5fa334360a8 100644
--- a/dbrepo-ui/components/ResourceStatus.vue
+++ b/dbrepo-ui/components/ResourceStatus.vue
@@ -14,6 +14,7 @@
     </span>
   </span>
 </template>
+
 <script>
 export default {
   props: {
diff --git a/dbrepo-ui/components/database/DatabaseToolbar.vue b/dbrepo-ui/components/database/DatabaseToolbar.vue
index 9d43b262e3c3b67cfe748fcb13168d17362af1d0..a606bfd2dc3ca24f920a41f1551342f33b0afed0 100644
--- a/dbrepo-ui/components/database/DatabaseToolbar.vue
+++ b/dbrepo-ui/components/database/DatabaseToolbar.vue
@@ -81,13 +81,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import { useCacheStore } from '@/stores/cache.js'
 import ResourceStatus from '@/components/ResourceStatus.vue'
@@ -110,6 +103,12 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
     isContrastTheme () {
       return this.$vuetify.theme.global.name.toLowerCase().endsWith('contrast')
     },
@@ -140,12 +139,6 @@ export default {
       }
       return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
     },
-    canImportCsv () {
-      if (!this.user || !this.hasWriteAccess) {
-        return false
-      }
-      return this.roles.includes('insert-table-data')
-    },
     canCreateSubset () {
       if (!this.database) {
         return false
@@ -156,22 +149,22 @@ export default {
       return this.hasReadAccess
     },
     canCreateView () {
-      if (!this.user || !this.isOwner) {
+      if (!this.cacheUser || !this.isOwner) {
         return false
       }
       return this.roles.includes('create-database-view')
     },
     canCreateTable () {
-      if (!this.user || !this.hasWriteAccess) {
+      if (!this.cacheUser || !this.hasWriteAccess) {
         return false
       }
       return this.roles.includes('create-table')
     },
     isOwner () {
-      if (!this.database || !this.user) {
+      if (!this.database || !this.cacheUser) {
         return false
       }
-      return this.database.owner.id === this.userInfo.uid
+      return this.database.owner.id === this.cacheUser.uid
     },
     buttonVariant () {
       const runtimeConfig = useRuntimeConfig()
diff --git a/dbrepo-ui/components/identifier/Banner.vue b/dbrepo-ui/components/identifier/Banner.vue
index 1450347c412727830e07f4fc1e11b857ab22c346..7c77a1b28ba3b4d4df3649dc4ed9e4f4f5028b21 100644
--- a/dbrepo-ui/components/identifier/Banner.vue
+++ b/dbrepo-ui/components/identifier/Banner.vue
@@ -3,6 +3,7 @@
     {{ prefix }}: <a :href="href">{{ displayName }}</a>
   </div>
 </template>
+
 <script>
 export default {
   props: {
diff --git a/dbrepo-ui/components/identifier/Persist.vue b/dbrepo-ui/components/identifier/Persist.vue
index 408d7e8265b667a6f1ab2b8a8e5c966bfa8e7028..b02ff09b76190889f393fd644141d1b061b08a1a 100644
--- a/dbrepo-ui/components/identifier/Persist.vue
+++ b/dbrepo-ui/components/identifier/Persist.vue
@@ -827,13 +827,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import { formatYearUTC, formatMonthUTC, formatDayUTC, languages } from '@/utils'
 import { useCacheStore } from '@/stores/cache.js'
@@ -972,6 +965,12 @@ export default {
     }
   },
   computed: {
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     isSubset () {
       return this.type === 'subset'
     },
@@ -1045,19 +1044,19 @@ export default {
       }
     },
     canInsertSelf () {
-      if (!this.user) {
+      if (!this.cacheUser) {
         return false
       }
-      return this.user.given_name || this.user.family_name || this.user.attributes.affiliation || this.user.attributes.orcid
+      return this.cacheUser.given_name || this.cacheUser.family_name || this.cacheUser.attributes.affiliation || this.cacheUser.attributes.orcid
     },
     isCreator () {
-      if (!this.user || !this.identifier) {
+      if (!this.cacheUser || !this.identifier) {
         return false
       }
-      if (!this.identifier.creator) {
+      if (!this.identifier.owner) {
         return true
       }
-      return this.identifier.creator.id === this.user.id
+      return this.identifier.owner.id === this.cacheUser.uid
     },
     formValid () {
       /* somehow Vue3/Vuetify3 validation form is broken for arrays */
@@ -1119,10 +1118,10 @@ export default {
       return this.roles.includes('create-identifier') && !this.isPublished
     },
     canRemove () {
-      if (!this.roles || !this.identifier || !this.identifier.creator || !this.user) {
+      if (!this.roles || !this.identifier || !this.identifier.owner || !this.cacheUser) {
         return false
       }
-      return this.roles.includes('delete-identifier') && this.identifier.creator.id === this.user.id && !this.isPublished
+      return this.roles.includes('delete-identifier') && this.identifier.owner.id === this.cacheUser.uid && !this.isPublished
     },
     canPublish () {
       if (!this.roles || !this.identifier || !this.roles.includes('publish-identifier') || this.isPublished || !this.identifier.id) {
@@ -1490,15 +1489,15 @@ export default {
       if (this.isPublished) {
         return false
       }
-      if (this.user.attributes.orcid) {
-        creator.name_identifier = this.user.attributes.orcid
+      if (this.cacheUser.attributes.orcid) {
+        creator.name_identifier = this.cacheUser.attributes.orcid
         this.retrieveCreator(creator)
         return
       }
-      creator.firstname = this.user.given_name
-      creator.lastname = this.user.family_name
+      creator.firstname = this.cacheUser.given_name
+      creator.lastname = this.cacheUser.family_name
       creator.creator_name = (creator.lastname ? creator.lastname + ', ' : '') + creator.firstname
-      creator.affiliation = this.user.attributes.affiliation
+      creator.affiliation = this.cacheUser.attributes.affiliation
     },
     canShiftUp (creator, idx) {
       if (this.isPublished) {
diff --git a/dbrepo-ui/components/identifier/Select.vue b/dbrepo-ui/components/identifier/Select.vue
index 84f87e321fcb81c7d7e233cedd4a79ad45b21271..ca5f3ce21ea995a6cffcd8caa10b6524de0d4d29 100644
--- a/dbrepo-ui/components/identifier/Select.vue
+++ b/dbrepo-ui/components/identifier/Select.vue
@@ -41,16 +41,8 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Banner from '@/components/identifier/Banner.vue'
-import { formatTimestampUTCLabel } from '@/utils'
 import { useCacheStore } from '@/stores/cache.js'
 
 export default {
@@ -82,10 +74,10 @@ export default {
       if (!this.identifiers) {
         return []
       }
-      if (!this.user) {
+      if (!this.userInfo) {
         return this.identifiers.filter(i => i.status === 'published')
       }
-      return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.user.id)
+      return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.userInfo.uid)
     },
     listVariant () {
       const runtimeConfig = useRuntimeConfig()
@@ -104,7 +96,6 @@ export default {
     this.init()
   },
   methods: {
-    formatTimestampUTCLabel,
     href (identifier) {
       if (identifier.status === 'published') {
         return `/pid/${identifier.id}`
diff --git a/dbrepo-ui/components/subset/Builder.vue b/dbrepo-ui/components/subset/Builder.vue
index ae7df2768370f472a85c1dd5cbe673773c92cac1..4261b098b666d3f2498f51d3c10f2c41f25cdf13 100644
--- a/dbrepo-ui/components/subset/Builder.vue
+++ b/dbrepo-ui/components/subset/Builder.vue
@@ -304,11 +304,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-</script>
 <script>
 import TimeDrift from '@/components/TimeDrift.vue'
 import Raw from '@/components/subset/Raw.vue'
diff --git a/dbrepo-ui/components/subset/SubsetToolbar.vue b/dbrepo-ui/components/subset/SubsetToolbar.vue
index 45ca7626289965f57d5771afaed4c1159fd0f414..61e26e99677c55e281fdaf62a79a1d3194ccb8f7 100644
--- a/dbrepo-ui/components/subset/SubsetToolbar.vue
+++ b/dbrepo-ui/components/subset/SubsetToolbar.vue
@@ -55,12 +55,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-</script>
 <script>
 import DownloadButton from '@/components/identifier/DownloadButton.vue'
 import { formatTimestampUTCLabel } from '@/utils'
@@ -95,6 +89,9 @@ export default {
     subset () {
       return this.cacheStore.getSubset
     },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
     identifiers () {
       if (!this.subset) {
         return []
@@ -152,10 +149,10 @@ export default {
       return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
     },
     canGetPid () {
-      if (!this.userInfo || !this.subset || !this.database) {
+      if (!this.cacheUser || !this.subset || !this.database) {
         return false
       }
-      return this.database.owner.id === this.userInfo.uid || (this.subset.owner.id === this.userInfo.uid && this.hasReadAccess)
+      return this.database.owner.id === this.cacheUser.uid || (this.subset.owner.id === this.cacheUser.uid && this.hasReadAccess)
     },
     title () {
       if (!this.identifier) {
diff --git a/dbrepo-ui/components/table/TableList.vue b/dbrepo-ui/components/table/TableList.vue
index d34483422d232292b6d108a3a5aa4a13e4a16ac4..71106f7c655491ed474e7c4182433eabe5a3bc2c 100644
--- a/dbrepo-ui/components/table/TableList.vue
+++ b/dbrepo-ui/components/table/TableList.vue
@@ -38,13 +38,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import { formatTimestampUTCLabel } from '@/utils'
 import { useCacheStore } from '@/stores/cache.js'
diff --git a/dbrepo-ui/components/table/TableToolbar.vue b/dbrepo-ui/components/table/TableToolbar.vue
index 9aee22348ffc55c1b11c385592f685314a7b5e20..e09cd67cba31e8d3aaec7e9055078fa354bd4ded 100644
--- a/dbrepo-ui/components/table/TableToolbar.vue
+++ b/dbrepo-ui/components/table/TableToolbar.vue
@@ -77,13 +77,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import EditTuple from '@/components/dialogs/EditTuple.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -112,31 +105,40 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     hasReadAccess () {
       if (!this.access) {
         return false
       }
-      return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access)
     },
     canUpdateTable () {
-      if (!this.roles || !this.user || !this.table) {
+      if (!this.roles || !this.cacheUser || !this.table) {
         return false
       }
-      return this.roles.includes('update-table') && this.table.owner.id === this.userInfo.uid
+      return this.roles.includes('update-table') && this.table.owner.id === this.cacheUser.uid
     },
     canExecuteQuery () {
-      if (!this.roles || !this.table || !this.user) {
+      if (!this.roles || !this.table || !this.cacheUser) {
         return false
       }
-      const userService = useUserService()
-      return userService.hasReadAccess(this.access) && this.roles.includes('execute-query')
+      return this.hasReadAccess && this.roles.includes('execute-query')
+    },
+    isOwner () {
+      const databaseService = useDatabaseService()
+      return databaseService.isOwner(this.database, this.cacheUser)
     },
     canCreateView () {
-      if (!this.roles || !this.table || !this.user) {
+      if (!this.roles || !this.table || !this.cacheUser) {
         return false
       }
-      const databaseService = useDatabaseService()
-      return databaseService.isOwner(this.database, this.user) && this.roles.includes('create-database-view')
+      return this.isOwner && this.roles.includes('create-database-view')
     },
     canViewData () {
       if (!this.table) {
@@ -145,10 +147,10 @@ export default {
       if (this.table.is_public) {
         return true
       }
-      if (!this.user) {
+      if (!this.cacheUser) {
         return false
       }
-      return this.hasReadAccess || this.table.owner.id === this.userInfo.uid || this.database.owner.id === this.userInfo.uid
+      return this.hasReadAccess || this.table.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid
     },
     canViewSchema () {
       if (!this.table) {
@@ -157,22 +159,22 @@ export default {
       if (this.table.is_schema_public) {
         return true
       }
-      if (!this.user) {
+      if (!this.cacheUser) {
         return false
       }
-      return this.hasReadAccess || this.table.owner.id === this.userInfo.uid || this.database.owner.id === this.userInfo.uid
+      return this.hasReadAccess || this.table.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid
     },
     canImportCsv () {
-      if (!this.roles || !this.table || !this.user) {
+      if (!this.roles || !this.table || !this.cacheUser) {
         return false
       }
       return this.roles.includes('insert-table-data')
     },
     canGetPid () {
-      if (!this.user || !this.table || !this.database) {
+      if (!this.cacheUser || !this.table || !this.database) {
         return false
       }
-      return this.database.owner.id === this.userInfo.uid || this.table.owner.id === this.userInfo.uid
+      return this.hasReadAccess && this.database.owner.id === this.cacheUser.uid || this.table.owner.id === this.cacheUser.uid
     },
     buttonVariant () {
       const runtimeConfig = useRuntimeConfig()
diff --git a/dbrepo-ui/components/user/UserToolbar.vue b/dbrepo-ui/components/user/UserToolbar.vue
index 868bab88a94123ae28aa2702f543ddab3f54dc0d..54210130d32f9c1cbe73378138e6c0db28c8cc88 100644
--- a/dbrepo-ui/components/user/UserToolbar.vue
+++ b/dbrepo-ui/components/user/UserToolbar.vue
@@ -21,7 +21,7 @@
 </template>
 
 <script setup>
-const { loggedIn, user, login, logout } = useOidcAuth()
+const { loggedIn } = useOidcAuth()
 </script>
 <script>
 export default {
diff --git a/dbrepo-ui/components/view/ViewToolbar.vue b/dbrepo-ui/components/view/ViewToolbar.vue
index 74eac9dedf5d7e446585dd01a5e5e4a107f1ae29..d9e0bfb6bf6740c19aac53f6b3ac8cc374be7011 100644
--- a/dbrepo-ui/components/view/ViewToolbar.vue
+++ b/dbrepo-ui/components/view/ViewToolbar.vue
@@ -56,13 +56,6 @@
   </v-toolbar>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import { useCacheStore } from '@/stores/cache.js'
 import CreateOntology from '@/components/dialogs/CreateOntology.vue'
@@ -96,6 +89,12 @@ export default {
     view () {
       return this.cacheStore.getView
     },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     canViewData () {
       if (!this.view) {
         return false
@@ -103,10 +102,10 @@ export default {
       if (this.view.is_public) {
         return true
       }
-      if (!this.user) {
+      if (!this.cacheUser) {
         return false
       }
-      return this.hasReadAccess || this.view.owner.id === this.userInfo.id || this.database.owner.id === this.userInfo.id
+      return this.hasReadAccess || this.view.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid
     },
     canViewSchema () {
       if (!this.view) {
@@ -115,23 +114,23 @@ export default {
       if (this.view.is_schema_public) {
         return true
       }
-      if (!this.user) {
+      if (!this.cacheUser) {
         return false
       }
-      return this.hasReadAccess || this.view.owner.id === this.userInfo.id || this.database.owner.id === this.userInfo.id
+      return this.hasReadAccess || this.view.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid
     },
     canViewSettings () {
-      if (!this.user || !this.view) {
+      if (!this.cacheUser || !this.view) {
         return false
       }
-      return this.view.owner.id === this.userInfo.id
+      return this.view.owner.id === this.cacheUser.uid
     },
     canCreatePid () {
-      if (!this.roles || !this.user || !this.view) {
+      if (!this.roles || !this.cacheUser || !this.view) {
         return false
       }
-      const userService = useUserService()
-      return this.roles.includes('create-identifier') && userService.hasReadAccess(this.access)
+      const cacheUserService = useUserService()
+      return cacheUserService.hasReadAccess(this.access) && this.roles.includes('create-identifier')
     },
     access () {
       return this.cacheStore.getAccess
diff --git a/dbrepo-ui/composables/user-service.ts b/dbrepo-ui/composables/user-service.ts
index 5381fee565a0953fec4b7b523b425a54f1e99229..3425dbaa5c7d77d927798914b8a4fdac6123c166 100644
--- a/dbrepo-ui/composables/user-service.ts
+++ b/dbrepo-ui/composables/user-service.ts
@@ -141,13 +141,13 @@ export const useUserService = (): any => {
   }
 
   function hasWriteAccess(table: TableDto, access: DatabaseAccessDto, user: UserDto): boolean {
-    if (!table || !access) {
+    if (!table || !access || !user) {
       return false
     }
     if (access.type === 'write_all') {
       return true
     }
-    return access.type === 'write_own' && table.owner.id === user.id
+    return access.type === 'write_own' && table.owner.id === user.uid
   }
 
   return {
@@ -156,7 +156,6 @@ export const useUserService = (): any => {
     update,
     create,
     updatePassword,
-    refreshToken,
     nameIdentifierToNameIdentifierScheme,
     userToFullName,
     hasReadAccess,
diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue
index a08f6f70f52f1cc39ce0383950b0f3fc8a6d2813..816d74c26afcd018101ea48d054115adfe196837 100644
--- a/dbrepo-ui/layouts/default.vue
+++ b/dbrepo-ui/layouts/default.vue
@@ -105,10 +105,10 @@
           {{ $t('navigation.login') }}
         </v-btn>
         <v-btn
-          v-if="loggedIn"
+          v-if="cacheUser"
           to="/user"
           variant="plain"
-          :text="userInfo.preferred_username" />
+          :text="cacheUser.preferred_username" />
         <v-menu
           v-if="loggedIn"
           location="bottom">
@@ -119,19 +119,18 @@
           </template>
           <v-list>
             <v-list-item
-              v-if="user"
+              v-if="cacheUser"
               exact
-              :to="`/search?type=database&owner.username=${user.username}`">
+              :to="`/search?type=database&owner.username=${cacheUser.username}`">
               {{ $t('navigation.databases') + ' ' + $t('navigation.mine')}}
             </v-list-item>
             <v-list-item
-              v-if="user"
+              v-if="cacheUser"
               exact
-              :to="`/search?type=identifier&identifiers.creator.username=${user.username}`">
+              :to="`/search?type=identifier&identifiers.creator.username=${cacheUser.username}`">
               {{ $t('navigation.identifiers') + ' ' + $t('navigation.mine') }}
             </v-list-item>
             <v-list-item
-              v-if="user"
               @click="logout()">
               {{ $t('navigation.logout') }}
             </v-list-item>
@@ -154,10 +153,12 @@
 
 <script setup>
 import { ref } from 'vue'
+import { useCacheStore } from '@/stores/cache.js'
 
 const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
+const cacheStore = useCacheStore()
+cacheStore.setUser(loggedIn ? user.value?.userInfo : null)
+cacheStore.setRoles(loggedIn ? user.value?.claims?.realm_access?.roles : [])
 const runtimeConfig = useRuntimeConfig()
 const config = ref(runtimeConfig)
 useServerHead({
@@ -173,7 +174,6 @@ import JumboBox from '@/components/JumboBox.vue'
 import { useCacheStore } from '@/stores/cache.js'
 import { errorCodeKey, makeError } from '@/utils'
 
-
 export default {
   components: {
     JumboBox
@@ -211,6 +211,12 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    access () {
+      return this.cacheStore.getAccess
+    },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
     resource () {
       if (!this.$route.params.database_id) {
         return null
@@ -248,13 +254,13 @@ export default {
       if (!this.user) {
         return null
       }
-      if (this.table && !this.table.is_public && !this.table.is_schema_public && this.table.owner.id !== this.user.id) {
+      if (this.table && !this.table.is_public && !this.table.is_schema_public && this.table.owner.id !== this.cacheUser.uid) {
         return makeError(403, null, null)
       }
-      if (this.view && !this.view.is_public && !this.view.is_schema_public && this.view.owner.id !== this.user.id) {
+      if (this.view && !this.view.is_public && !this.view.is_schema_public && this.view.owner.id !== this.cacheUser.uid) {
         return makeError(403, null, null)
       }
-      if (this.subset && !this.subset.is_public && !this.subset.is_schema_public && this.subset.owner.id !== this.user.id) {
+      if (this.subset && !this.subset.is_public && !this.subset.is_schema_public && this.subset.owner.id !== this.cacheUser.uid) {
         return makeError(403, null, null)
       }
       return null
@@ -266,10 +272,7 @@ export default {
       return this.roles.includes('list-ontologies')
     },
     canListContainers () {
-      if (!this.roles) {
-        return false
-      }
-      return this.roles.includes('list-containers')
+      return this.cacheUser
     },
     logo () {
       return this.$config.public.logo
@@ -291,19 +294,18 @@ export default {
           this.cacheStore.setTable(null)
           this.cacheStore.setView(null)
           this.cacheStore.setSubset(null)
+          this.cacheStore.setAccess(null)
           return
         }
         if (import.meta.server) {
           return
         }
         /* load database and optional access */
+        this.cacheStore.setRouteAccess(newObj.database_id, this.cacheUser?.uid)
         this.cacheStore.setRouteDatabase(newObj.database_id)
           .catch((error) => {
             this.databaseError = error
           })
-        if (this.userInfo) {
-          this.cacheStore.setRouteAccess(newObj.database_id, this.userInfo.uid)
-        }
         /* load table */
         if (newObj.table_id) {
           this.cacheStore.setRouteTable(newObj.database_id, newObj.table_id)
@@ -328,14 +330,14 @@ export default {
     }
   },
   mounted () {
-    this.initEnvironment()
     if (this.$route.query && this.$route.query.q) {
       this.search = this.$route.query.q
     }
-    if (!this.user) {
+    if (!this.cacheUser) {
       return
     }
     this.setTheme()
+    this.setLocale()
     this.cacheStore.reloadMessages()
   },
   methods: {
@@ -343,7 +345,7 @@ export default {
       console.debug('performing fuzzy search')
       this.$router.push({ path: '/search', query: { q: this.search } })
     },
-    initEnvironment () {
+    setLocale () {
       if (!this.locale) {
         this.cacheStore.setLocale('en')
         return
@@ -351,7 +353,10 @@ export default {
       this.$i18n.locale = this.locale
     },
     setTheme () {
-      switch (this.user.attributes.theme) {
+      if (!this.cacheUser?.attributes?.theme) {
+        return
+      }
+      switch (this.cacheUser.attributes.theme) {
         case 'dark':
           this.$vuetify.theme.global.name = 'tuwThemeDark'
           break
@@ -365,10 +370,6 @@ export default {
           this.$vuetify.theme.global.name = 'tuwThemeDarkContrast'
           break
       }
-    },
-    setLocale (code) {
-      this.cacheStore.setLocale(code)
-      this.$i18n.locale = this.locale
     }
   }
 }
diff --git a/dbrepo-ui/nuxt.config.ts b/dbrepo-ui/nuxt.config.ts
index 305a753d9e295975cdd6c055c9d83b7f7fa423a7..0f2099a387ea727425de40a0c4d092768071697c 100644
--- a/dbrepo-ui/nuxt.config.ts
+++ b/dbrepo-ui/nuxt.config.ts
@@ -3,19 +3,19 @@ import vuetify from 'vite-plugin-vuetify'
 
 const proxy: any = {}
 
-/* proxies the backend calls, >>NOT<< the frontend calls (clicking) */
-if (process.env.NODE_ENV === 'development') {
-  const api = 'http://localhost'
-  proxy['/api'] = api
-  proxy['/pid'] = {
-    target: api + '/api',
-    changeOrigin: true,
-    pathRewrite: {
-      '^/pid': '/pid'
-    }
-  }
-  process.env.NUXT_PUBLIC_API_SERVER = api
-}
+// /* proxies the backend calls, >>NOT<< the frontend calls (clicking) */
+// if (process.env.NODE_ENV === 'development') {
+//   const api = 'http://localhost'
+//   proxy['/api'] = api
+//   proxy['/pid'] = {
+//     target: api + '/api',
+//     changeOrigin: true,
+//     pathRewrite: {
+//       '^/pid': '/pid'
+//     }
+//   }
+//   process.env.NUXT_PUBLIC_API_SERVER = api
+// }
 
 /**
  * https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering
@@ -116,10 +116,10 @@ export default defineNuxtConfig({
         clientSecret: '', // inject on runtime
         scope: ['openid', 'roles'],
         optionalClaims: ['realm_access'],
-        redirectUri: 'http://localhost/auth/keycloak/callback',
+        redirectUri: 'http://localhost:3001/auth/keycloak/callback',
         userNameClaim: 'preferred_username',
         exposeAccessToken: true,
-        logoutRedirectUri: 'http://localhost',
+        logoutRedirectUri: 'http://localhost:3001',
       },
     },
     middleware: {
diff --git a/dbrepo-ui/package.json b/dbrepo-ui/package.json
index ec3ae1e6a44710998f0642760cf1e506b1d546d3..7110d273f2a67f7a1a441e261dcde634b10298e8 100644
--- a/dbrepo-ui/package.json
+++ b/dbrepo-ui/package.json
@@ -4,7 +4,7 @@
   "type": "module",
   "scripts": {
     "build": "nuxt build",
-    "dev": "VERSION=bun-dev NODE_ENV=development nuxt dev",
+    "dev": "VERSION=bun-dev NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG NODE_ENV=development nuxt dev",
     "generate": "nuxt generate",
     "preview": "nuxt preview",
     "postinstall": "nuxt prepare",
diff --git a/dbrepo-ui/pages/container/index.vue b/dbrepo-ui/pages/container/index.vue
index ec2149372e509c064d45e0ee684a60824bf17520..20fed36801c24184664744ccf8b06eecba358c33 100644
--- a/dbrepo-ui/pages/container/index.vue
+++ b/dbrepo-ui/pages/container/index.vue
@@ -1,5 +1,6 @@
 <template>
-  <div>
+  <div
+    v-if="loggedIn">
     <v-toolbar
       flat
       :title="$t('pages.container.title')">
@@ -11,6 +12,9 @@
   </div>
 </template>
 
+<script setup>
+const { loggedIn } = useOidcAuth()
+</script>
 <script>
 import ContainerList from '@/components/container/ContainerList.vue'
 
diff --git a/dbrepo-ui/pages/database/[database_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/info.vue
index 33d63b29a938d7cb9fa5015605846a9a42d85a17..9da8daab62a2f2c98572df67865d84660c038e03 100644
--- a/dbrepo-ui/pages/database/[database_id]/info.vue
+++ b/dbrepo-ui/pages/database/[database_id]/info.vue
@@ -242,7 +242,7 @@ export default {
       if (!this.user) {
         return this.identifiers.filter(i => i.status === 'published')
       }
-      return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.user.id)
+      return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.userInfo.uid)
     },
     identifier () {
       if (this.pid) {
@@ -336,7 +336,10 @@ export default {
       if (this.error) {
         return false
       }
-      return this.database
+      if (!this.database) {
+        return false
+      }
+      return this.database.is_schema_public
     }
   }
 }
diff --git a/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue
index 2c2e5ef120a044b4d2f551e0508fd842678aa7a9..75f267944f7f9f91daaddefcc46d8ce4e4dd4374 100644
--- a/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue
@@ -8,12 +8,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Persist from '@/components/identifier/Persist.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -51,6 +45,12 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
     canCreateIdentifier () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-ui/pages/database/[database_id]/persist/index.vue b/dbrepo-ui/pages/database/[database_id]/persist/index.vue
index a3581c0c828aec8b076151d306bd5a15ab69e16a..570c5d9da57943bc6555aa3562ae58d8d43a4c4b 100644
--- a/dbrepo-ui/pages/database/[database_id]/persist/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/persist/index.vue
@@ -8,13 +8,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Persist from '@/components/identifier/Persist.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -48,6 +41,9 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
     hasIdentifier () {
       if (this.database && 'identifier' in this.database && this.database.identifier) {
         return 'id' in this.database.identifier
@@ -55,10 +51,10 @@ export default {
       return false
     },
     isOwner () {
-      if (!this.database || !this.userInfo) {
+      if (!this.database || !this.cacheUser) {
         return false
       }
-      return this.database.owner.id === this.userInfo.uid
+      return this.database.owner.id === this.cacheUser.uid
     },
     canCreateIdentifier () {
       if (!this.roles || this.hasIdentifier) {
diff --git a/dbrepo-ui/pages/database/[database_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/settings.vue
index 5b0aa2a4537a69cd943cf6528b12ee14f94e44b3..1d71474805123a41956bbe032fa5dd9f3ab96336 100644
--- a/dbrepo-ui/pages/database/[database_id]/settings.vue
+++ b/dbrepo-ui/pages/database/[database_id]/settings.vue
@@ -349,16 +349,16 @@ export default {
       if (!this.database || !this.user) {
         return false
       }
-      if (this.database.owner.id === null || this.user.id === null) {
+      if (this.database.owner.id === null || this.userInfo.uid === null) {
         return false
       }
-      return this.database.owner.id === this.user.id
+      return this.database.owner.id === this.userInfo.uid
     },
     isSameOwner () {
-      if (!this.modifyOwner || !this.user) {
+      if (!this.modifyOwner || !this.userInfo) {
         return false
       }
-      return this.modifyOwner.id === this.user.id
+      return this.modifyOwner.id === this.userInfo.uid
     },
     isSameVisibility () {
       if (!this.modifyVisibility || !this.database) {
@@ -406,7 +406,13 @@ export default {
       if (this.error) {
         return false
       }
-      return this.database
+      if (!this.database) {
+        return false
+      }
+      if (!this.cacheUser) {
+        return false
+      }
+      return this.database.owner.id === this.cacheUser.uid
     },
     previewImage () {
       if (this.file) {
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue
index e9719cd0efe49369d3735ab7f9d5a0e2acd22070..ee6d25eda74fbad4cf063a094b01397f6d370399 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue
@@ -139,10 +139,6 @@ export default {
           this.loadingSubset = false
         })
     },
-    loadResult () {
-      if (this.subset) {
-      }
-    },
     download () {
       this.downloadLoading = true
       const queryService = useQueryService()
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue
index a9956278d100eae3c66f50ad0ca2b8e461a4588d..eeb0a70c3e8d05ae29ccc5ac76d9796232dba593 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue
@@ -50,7 +50,9 @@
             v-if="subset.creator"
             :title="$t('pages.subset.creator.title')"
             density="compact">
-            <UserBadge :user="subset.creator" :other-user="user" />
+            <UserBadge
+              :user="subset.creator"
+              :other-user="cacheUser" />
           </v-list-item>
           <v-list-item
             :title="$t('pages.subset.query.title')"
@@ -143,8 +145,8 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
-    access () {
-      return this.cacheStore.getAccess
+    cacheUser () {
+      return this.cacheStore.getUser
     },
     subset () {
       return this.cacheStore.getSubset
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue
index 0e1dac8c7e7fef9dfa3d4b50bad535af3f4ddfbc..65154f38a508506fb823223bd01959e285526bc1 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue
@@ -8,12 +8,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Persist from '@/components/identifier/Persist.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -59,6 +53,9 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     canCreateIdentifier () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue
index cc0dbf495865c2276d15411b2d8f05bd69c5cefb..82a4ba5f70c4176f7f707f54bdd3c6dcc027ef0d 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue
@@ -9,12 +9,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Persist from '@/components/identifier/Persist.vue'
 import { useCacheStore } from '@/stores/cache.js'
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/create.vue b/dbrepo-ui/pages/database/[database_id]/subset/create.vue
index 2ea1c5022a9932dab4a655f0ebd19a9d522e9ba1..94fd8e8ec9755f410dbb6295472968f09770cca1 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/create.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/create.vue
@@ -6,12 +6,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Builder from '@/components/subset/Builder.vue'
 import {useCacheStore} from '@/stores/cache.js'
@@ -51,12 +45,6 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
-    hasReadAccess () {
-      if (!this.access) {
-        return false
-      }
-      return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
-    },
     canCreateSubset () {
       if (!this.database) {
         return false
@@ -64,7 +52,8 @@ export default {
       if (this.database.is_public) {
         return true
       }
-      return this.hasReadAccess
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access)
     }
   }
 }
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/index.vue b/dbrepo-ui/pages/database/[database_id]/subset/index.vue
index 2f68604881a0e222dbd280a5c54ff375ca8c0825..93be3df02455d2de5b4f2a4381893e7aa1d0b4a7 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/index.vue
@@ -43,7 +43,10 @@ export default {
       if (this.error) {
         return false
       }
-      return this.database
+      if (!this.database) {
+        return false
+      }
+      return this.database.is_schema_public
     }
   }
 }
diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue
index ca120e89f737ffc602c80378cc2bd27bb15fed89..cf304cbf71d9802fd044ac292a711fb4f34a9d33 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue
@@ -107,11 +107,7 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
+const { loggedIn } = useOidcAuth()
 </script>
 <script>
 import TableHistory from '@/components/table/TableHistory.vue'
@@ -197,15 +193,12 @@ export default {
     table () {
       return this.cacheStore.getTable
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     access () {
       return this.cacheStore.getAccess
     },
-    hasReadAccess () {
-      if (!this.access) {
-        return false
-      }
-      return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
-    },
     title () {
       return (this.version ? this.$t('toolbars.database.history') : this.$t('toolbars.database.current')) + ' ' + this.versionFormatted
     },
@@ -230,15 +223,6 @@ export default {
       }
       return this.version.substring(0, 10) + 'T' + this.version.substring(11, 19) + 'Z'
     },
-    canModify () {
-      if (!this.userInfo || !this.access || !this.table) {
-        return false
-      }
-      if (this.access.type === 'write_own' && this.table.owner.id === this.userInfo.uid) {
-        return true
-      }
-      return this.access.type === 'write_all'
-    },
     primaryKeyColumns () {
       if (!this.table) {
         return []
@@ -258,7 +242,11 @@ export default {
       if (!this.roles || !this.roles.includes('view-table-data')) {
         return false
       }
-      return this.hasReadAccess
+      if (!this.access) {
+        return false
+      }
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access)
     },
     canAddTuple () {
       if (!this.roles) {
diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue
index 46eb7106fd8449b93e4403abc2b2866280e3403b..1b54076c6550a0c890167dff05b180c6c5f63926 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue
@@ -28,13 +28,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import TableImport from '@/components/table/TableImport.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -82,6 +75,9 @@ export default {
     table () {
       return this.cacheStore.getTable
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     title () {
       if (!this.table) {
         return this.$t('pages.table.import.title')
diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue
index ca295a558743451b37ea415691861c864b0bbdbc..6ab884a826beecf12d6b711fd9dcf4000b3d6d9d 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue
@@ -64,7 +64,7 @@
             :title="$t('pages.table.owner.title')">
             <UserBadge
               :user="table.owner"
-              :other-user="user" />
+              :other-user="cacheUser" />
           </v-list-item>
         </v-list>
       </v-card-text>
@@ -118,13 +118,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import TableToolbar from '@/components/table/TableToolbar.vue'
 import Select from '@/components/identifier/Select.vue'
@@ -184,14 +177,21 @@ export default {
     table () {
       return this.cacheStore.getTable
     },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     canRead () {
       if (this.database && this.database.is_public) {
         return true
       }
-      if (!this.user || !this.access) {
+      if (!this.access) {
         return false
       }
-      return this.access.type === 'read' || this.access.type === 'write_own' || this.access.type === 'write_all'
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access)
     },
     canViewSchema () {
       if (this.error) {
@@ -203,16 +203,15 @@ export default {
       if (this.table.is_schema_public || this.table.is_public) {
         return true
       }
-      if (!this.userInfo) {
+      if (!this.cacheUser) {
         return false
       }
-      return this.hasReadAccess || this.table.owner.id === this.userInfo.uid || this.database.owner.id === this.userInfo.uid
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access) || this.table.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid
     },
     canWrite () {
-      if (!this.table || !this.user || !this.access) {
-        return false
-      }
-      return (this.access.type === 'write_own' && this.table.owned_by === this.userInfo.uid) || this.access.type === 'write_all'
+      const userService = useUserService()
+      return userService.hasWriteAccess(this.table, this.access, this.cacheUser)
     },
     access () {
       return this.cacheStore.getAccess
@@ -236,10 +235,10 @@ export default {
       if (!this.identifiers) {
         return []
       }
-      if (!this.userInfo) {
+      if (!this.cacheUser) {
         return this.identifiers.filter(i => i.status === 'published')
       }
-      return this.identifiers.filter(i => i.status === 'published' || i.owned_by === this.userInfo.uid)
+      return this.identifiers.filter(i => i.status === 'published' || i.owned_by === this.cacheUser.uid)
     },
     identifier () {
       if (this.pid) {
diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue
index 0e82a2210beba8d7bce5865bf12234e2c43a279a..50c06f569a21f3d2bb7f3f3630b7191f1629fc5c 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue
@@ -6,12 +6,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Persist from '@/components/identifier/Persist.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -57,6 +51,9 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     canCreateIdentifier () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue
index 4cbb8d37d1abfd1c88b5daebd579e403a5545705..32a6dd9dad20f34bebff8c3b1130618848d863c0 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue
@@ -123,9 +123,7 @@
 <script setup>
 import { ref } from 'vue'
 
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
+const { loggedIn } = useOidcAuth()
 </script>
 <script>
 import TableToolbar from '@/components/table/TableToolbar.vue'
@@ -187,6 +185,12 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     hasReadAccess () {
       if (!this.access) {
         return false
@@ -203,16 +207,17 @@ export default {
       if (this.table.is_schema_public) {
         return true
       }
-      if (!this.userInfo) {
+      if (!this.cacheUser) {
         return false
       }
-      return this.hasReadAccess || this.table.owner.id === this.userInfo.uid || this.database.owner.id === this.userInfo.uid
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access) || this.table.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid
     },
     primaryKeysColumns () {
       return this.table.constraints.primary_key.map(pk => pk.column.internal_name).join(', ')
     },
     canAssignSemanticInformation () {
-      if (!this.userInfo) {
+      if (!this.cacheUser) {
         return false
       }
       if (this.roles.includes('modify-foreign-table-column-semantics')) {
@@ -221,7 +226,7 @@ export default {
       if (!this.access) {
         return false
       }
-      return this.roles.includes('modify-table-column-semantics') && (this.access.type === 'write_all' || this.table.owner.id === this.userInfo.uid)
+      return this.roles.includes('modify-table-column-semantics') && (this.access.type === 'write_all' || this.table.owner.id === this.cacheUser.uid)
     },
     inputVariant () {
       const runtimeConfig = useRuntimeConfig()
diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue
index ddf319328ca039f0fbe1230117b6dc89eff31646..a2ac279f2e2eaab959759837c4adfd9617632d15 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue
@@ -3,7 +3,6 @@
     v-if="canUpdateTable">
     <TableToolbar />
     <v-window
-      v-if="loggedIn"
       v-model="tab">
       <v-window-item>
         <v-form
@@ -114,13 +113,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import TableToolbar from '@/components/table/TableToolbar.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -194,11 +186,11 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
-    hasReadAccess () {
-      if (!this.access) {
-        return false
-      }
-      return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
+    cacheUser () {
+      return this.cacheStore.getUser
+    },
+    roles () {
+      return this.cacheStore.getRoles
     },
     isChange () {
       if (!this.table) {
@@ -210,26 +202,20 @@ export default {
       return this.table.is_schema_public !== this.modify.is_schema_public
     },
     canUpdateTable () {
-      if (!this.roles || !this.userInfo || !this.table) {
-        return false
-      }
-      return this.roles.includes('update-table') && this.table.owner.id === this.userInfo.uid
-    },
-    canModifyVisibility () {
-      if (!this.roles || !this.userInfo || !this.table) {
+      if (!this.roles || !this.cacheUser || !this.table) {
         return false
       }
-      return this.roles.includes('update-table') && this.table.owner.id === this.userInfo.uid
+      return this.roles.includes('update-table') && this.table.owner.id === this.cacheUser.uid
     },
     canDropTable () {
-      if (!this.roles || !this.table || !this.userInfo) {
+      if (!this.roles || !this.table || !this.cacheUser) {
         return false
       }
       if (this.roles.includes('delete-foreign-table')) {
         return true
       }
       const tableService = useTableService()
-      return tableService.isOwner(this.table, this.userInfo) && this.roles.includes('delete-table') && this.table.identifiers.length === 0
+      return tableService.isOwner(this.table, this.cacheUser) && this.roles.includes('delete-table') && this.table.identifiers.length === 0
     },
     inputVariant () {
       const runtimeConfig = useRuntimeConfig()
diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue
index 78bd1367513474e92efdc02efdeb93a537819729..50eb6305d77b39ff8e0e60ea32dda2ef6bf3e5b9 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue
@@ -219,12 +219,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import TableSchema from '@/components/table/TableSchema.vue'
 import { notEmpty } from '@/utils'
@@ -323,6 +317,9 @@ export default {
     database() {
       return this.cacheStore.getDatabase
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     generatedTableName() {
       if (!this.tableCreate.name) {
         return null
diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue b/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue
index cf8de848de793631ee2064bd84ad41010a0a0f17..d6bd4414df9e65e2392a090c0f630aa095740e0d 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue
@@ -185,12 +185,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import TableSchema from '@/components/table/TableSchema.vue'
 import { notEmpty } from '@/utils'
@@ -266,6 +260,9 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     canCreateTable () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-ui/pages/database/[database_id]/table/index.vue b/dbrepo-ui/pages/database/[database_id]/table/index.vue
index ae3e3c13f1b173b62514e1ee8887fd648e3f65a1..95fdf1643ee56a1e11e72283c4cda011c68186c7 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/index.vue
@@ -52,7 +52,10 @@ export default {
       if (this.error) {
         return false
       }
-      return this.database
+      if (!this.database) {
+        return false
+      }
+      return this.database.is_schema_public
     }
   }
 }
diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue
index 0b0caa3c4fc82b414b91c48bed401ebc239d0351..bb3d953d767a8066bce9274007997e8851799fde 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue
@@ -38,7 +38,7 @@
 import { ref } from 'vue'
 
 const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
+const cacheUser = ref(loggedIn ? user.value?.cacheUser : null)
 </script>
 <script>
 import TimeDrift from '@/components/TimeDrift.vue'
@@ -88,11 +88,8 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
-    hasReadAccess () {
-      if (!this.access) {
-        return false
-      }
-      return this.access.type === 'read' ||  this.access.type === 'write_own' ||  this.access.type === 'write_all'
+    cacheUser () {
+      return this.cacheStore.getUser
     },
     canReadData () {
       if (!this.view) {
@@ -101,10 +98,14 @@ export default {
       if (this.view.is_public) {
         return true
       }
-      if (!this.userInfo) {
+      if (!this.access) {
+        return false
+      }
+      if (!this.cacheUser) {
         return false
       }
-      return this.view.owner.id === this.userInfo.uid || this.hasReadAccess
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access) || this.database.owner.id === this.cacheUser.uid
     },
   },
   mounted () {
diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue
index 0ed006c4bef542f4bf5f4f51eeb2fd760f004acc..5864740846679c0e71f43c1c945d07b5651a7c78 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue
@@ -59,12 +59,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-</script>
 <script>
 import ViewToolbar from '@/components/view/ViewToolbar.vue'
 import Summary from '@/components/identifier/Summary.vue'
@@ -121,11 +115,11 @@ export default {
     view () {
       return this.cacheStore.getView
     },
-    hasReadAccess () {
-      if (!this.access) {
-        return false
-      }
-      return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
+    roles () {
+      return this.cacheStore.getRoles
+    },
+    cacheUser () {
+      return this.cacheStore.getUser
     },
     identifiers () {
       if (!this.view) {
@@ -137,10 +131,10 @@ export default {
       if (!this.identifiers) {
         return []
       }
-      if (!this.userInfo) {
+      if (!this.cacheUser) {
         return this.identifiers.filter(i => i.status === 'published')
       }
-      return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.userInfo.uid)
+      return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.cacheUser.uid)
     },
     identifier () {
       if (this.pid) {
@@ -177,10 +171,14 @@ export default {
       if (this.view.is_public) {
         return true
       }
-      if (!this.userInfo) {
+      if (!this.access) {
         return false
       }
-      return this.hasReadAccess || this.view.owner.id === this.userInfo.uid || this.database.owner.id === this.userInfo.uid
+      if (!this.cacheUser) {
+        return false
+      }
+      const userService = useUserService()
+      return userService.hasReadAcess(this.access) || this.database.owner.id === this.cacheUser.uid
     }
   },
   methods: {
diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue
index f528c86675b9d48f1d7d0a2a68cfd614b946442b..691336be2aa7010f8f510a060fac679f75675ead 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue
@@ -8,12 +8,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Persist from '@/components/identifier/Persist.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -59,6 +53,9 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    roles () {
+      return this.cacheStore.getRoles
+    },
     canCreateIdentifier () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue
index c5082c3be9bd10250df6be5957c620d813f73326..6351650736330720f2f69961c5a61ef3b26e2fe0 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue
@@ -51,15 +51,15 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    access () {
+      return this.cacheStore.getAccess
+    },
     view () {
       if (!this.database) {
         return null
       }
       return this.database.views.filter(v => v.id === Number(this.$route.params.view_id))[0]
     },
-    access () {
-      return this.cacheStore.getAccess
-    },
     canPersistView () {
       if (!this.view) {
         return false
diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue
index 5bd1ff5f9cf6019d6e36e4dd316ee9b43848a8d1..2cc851a41c94c9ff7167aa69023e1d98756579a0 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue
@@ -51,12 +51,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-</script>
 <script>
 import TableToolbar from '@/components/table/TableToolbar.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -113,11 +107,11 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
-    hasReadAccess () {
-      if (!this.access) {
-        return false
-      }
-      return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
+    roles () {
+      return this.cacheStore.getRoles
+    },
+    cacheUser () {
+      return this.cacheStore.getUser
     },
     canViewSchema () {
       if (!this.view) {
@@ -126,10 +120,14 @@ export default {
       if (this.view.is_schema_public) {
         return true
       }
-      if (!this.userInfo) {
+      if (!this.access) {
+        return false
+      }
+      if (!this.cacheUser) {
         return false
       }
-      return this.hasReadAccess || this.view.owner.id === this.userInfo.uid || this.database.owner.id === this.userInfo.uid
+      const userService = useUserService()
+      return userService.hasReadAccess(this.access) || this.database.owner.id === this.cacheUser.uid
     },
     inputVariant () {
       const runtimeConfig = useRuntimeConfig()
diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue
index 575e5b5f27d484a248ef7df71f9ff1c013baefc5..8d77881cec2cb9e4aaa1bccf3f9634f45aa885c2 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue
@@ -90,13 +90,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import ViewToolbar from '@/components/view/ViewToolbar.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -167,11 +160,11 @@ export default {
     access () {
       return this.cacheStore.getAccess
     },
-    hasReadAccess () {
-      if (!this.access) {
-        return false
-      }
-      return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own'
+    roles () {
+      return this.cacheStore.getRoles
+    },
+    cacheUser () {
+      return this.cacheStore.getUser
     },
     isChange () {
       if (!this.view) {
@@ -183,22 +176,22 @@ export default {
       return this.view.is_schema_public !== this.modify.is_schema_public
     },
     canUpdateVisibility () {
-      if (!this.roles || !this.userInfo || !this.view) {
+      if (!this.roles || !this.cacheUser || !this.view) {
         return false
       }
-      return this.roles.includes('modify-view-visibility') && this.view.owner.id === this.userInfo.uid
+      return this.roles.includes('modify-view-visibility') && this.view.owner.id === this.cacheUser.uid
     },
     canDeleteView () {
-      if (!this.roles || !this.userInfo || !this.view) {
+      if (!this.roles || !this.cacheUser || !this.view) {
         return false
       }
-      return this.roles.includes('delete-database-view') && this.view.owner.id === this.userInfo.uid
+      return this.roles.includes('delete-database-view') && this.view.owner.id === this.cacheUser.uid
     },
     canViewSettings () {
-      if (!this.userInfo || !this.view) {
+      if (!this.cacheUser || !this.view) {
         return false
       }
-      return this.view.owner.id === this.userInfo.uid
+      return this.view.owner.id === this.cacheUser.uid
     },
     inputVariant () {
       const runtimeConfig = useRuntimeConfig()
diff --git a/dbrepo-ui/pages/database/[database_id]/view/create.vue b/dbrepo-ui/pages/database/[database_id]/view/create.vue
index b9d4a684d764de219014e7f840c422b98a2d4c75..ab52fd2405ab22e3fffe225236ada04f09e817b2 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/create.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/create.vue
@@ -6,12 +6,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import Builder from '@/components/subset/Builder.vue'
 
@@ -43,6 +37,9 @@ export default {
     }
   },
   computed: {
+    roles () {
+      return this.cacheStore.getRoles
+    },
     canCreateView () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-ui/pages/database/[database_id]/view/index.vue b/dbrepo-ui/pages/database/[database_id]/view/index.vue
index 64f777dce3f905f19d2ff8f16e5e4b3de80fd277..8c3ab4b0e019cc5fc28d9e739fcc5d6496160602 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/index.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/index.vue
@@ -52,7 +52,10 @@ export default {
       if (this.error) {
         return false
       }
-      return this.database
+      if (!this.database) {
+        return false
+      }
+      return this.database.is_schema_public
     }
   }
 }
diff --git a/dbrepo-ui/pages/index.vue b/dbrepo-ui/pages/index.vue
index 16cbbb283fd3a86e14dfb4865c4d61477ad2cf8e..b6c225025e7f0e9a14cd996199b89d5fea28b845 100644
--- a/dbrepo-ui/pages/index.vue
+++ b/dbrepo-ui/pages/index.vue
@@ -27,9 +27,6 @@
   </div>
 </template>
 
-<script setup>
-const { loggedIn, user, login, logout } = useOidcAuth()
-</script>
 <script>
 import DatabaseList from '@/components/database/DatabaseList.vue'
 import DatabaseCreate from '@/components/database/DatabaseCreate.vue'
@@ -47,17 +44,8 @@ export default {
     }
   },
   computed: {
-    userInfo () {
-      if (!this.user) {
-        return null
-      }
-      return this.user.userInfo
-    },
     roles () {
-      if (!this.user) {
-        return []
-      }
-      return []
+      return this.cacheStore.getRoles
     },
     canCreateDatabase () {
       if (!this.roles) {
diff --git a/dbrepo-ui/pages/search.vue b/dbrepo-ui/pages/search.vue
index ca80b1efda6c185a0e39323cb66c13d0a131e97b..507f81b731407a3059e61f7956368d25481de9a0 100644
--- a/dbrepo-ui/pages/search.vue
+++ b/dbrepo-ui/pages/search.vue
@@ -63,12 +63,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import AdvancedSearch from '@/components/search/AdvancedSearch.vue'
 
@@ -93,12 +87,6 @@ export default {
     header () {
       return `${this.results.length} ${this.results.length !== 1 ? this.$t('toolbars.search.results') : this.$t('toolbars.search.result')}`
     },
-    canCreateDatabase () {
-      if (!this.roles) {
-        return false
-      }
-      return this.roles.includes('create-database')
-    },
     isDatabaseSearch () {
       return this.type === 'database'
     }
diff --git a/dbrepo-ui/pages/user/authentication.vue b/dbrepo-ui/pages/user/authentication.vue
index 03c40e5d82f9ac2a787a663eab1e6b7fb2f89699..64d76f75350424bed90d5db922eb2ec5aec508e7 100644
--- a/dbrepo-ui/pages/user/authentication.vue
+++ b/dbrepo-ui/pages/user/authentication.vue
@@ -61,11 +61,7 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
+const { loggedIn } = useOidcAuth()
 </script>
 <script>
 import UserToolbar from '@/components/user/UserToolbar.vue'
diff --git a/dbrepo-ui/pages/user/index.vue b/dbrepo-ui/pages/user/index.vue
index 1d76677059d6dbc26ad41ac48bfaf88d3ef6acb2..be3fe8cf673afb38ba7beffc22b5ca8a28d9388d 100644
--- a/dbrepo-ui/pages/user/index.vue
+++ b/dbrepo-ui/pages/user/index.vue
@@ -2,9 +2,6 @@
   <div />
 </template>
 
-<script setup>
-const { loggedIn, user, login, logout } = useOidcAuth()
-</script>
 <script>
 export default {
   mounted () {
diff --git a/dbrepo-ui/pages/user/info.vue b/dbrepo-ui/pages/user/info.vue
index 58e265b59ffe78ce7627c572df60e91b67e24df3..d8739fbab99a01e6c513d34e4b42a7918b1260e0 100644
--- a/dbrepo-ui/pages/user/info.vue
+++ b/dbrepo-ui/pages/user/info.vue
@@ -123,13 +123,6 @@
   </div>
 </template>
 
-<script setup>
-import { ref } from 'vue'
-
-const { loggedIn, user, login, logout } = useOidcAuth()
-const userInfo = ref(loggedIn ? user.value?.userInfo : null)
-const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : [])
-</script>
 <script>
 import UserToolbar from '@/components/user/UserToolbar.vue'
 import { useCacheStore } from '@/stores/cache.js'
@@ -184,8 +177,11 @@ export default {
     locale () {
       return this.cacheStore.getLocale
     },
-    canModifyTheme () {
-      return this.roles.includes('modify-user-theme')
+    roles () {
+      return this.cacheStore.getRoles
+    },
+    cacheUser () {
+      return this.cacheStore.getUser
     },
     canModifyInformation () {
       return this.roles.includes('modify-user-information')
@@ -216,7 +212,7 @@ export default {
         language: this.model.language,
       }
       const userService = useUserService()
-      userService.update(this.userInfo.id, payload)
+      userService.update(this.cacheUser.uid, payload)
         .then((user) => {
           console.info('Updated user information')
           const toast = useToastInstance()
@@ -252,14 +248,14 @@ export default {
         return
       }
       this.model = {
-        id: this.userInfo.id,
-        username: this.userInfo.username,
-        firstname: this.userInfo.given_name,
-        lastname: this.userInfo.family_name,
-        orcid: this.userInfo.attributes.orcid,
-        affiliation: this.userInfo.attributes.affiliation,
-        theme: this.userInfo.attributes.theme,
-        language: this.userInfo.attributes.language
+        id: this.cacheUser.uid,
+        username: this.cacheUser.username,
+        firstname: this.cacheUser.given_name,
+        lastname: this.cacheUser.family_name,
+        orcid: this.cacheUser.attributes.orcid,
+        affiliation: this.cacheUser.attributes.affiliation,
+        theme: this.cacheUser.attributes.theme,
+        language: this.cacheUser.attributes.language
       }
     },
     retrieve () {
diff --git a/dbrepo-ui/stores/cache.js b/dbrepo-ui/stores/cache.js
index 4582dce19945e18b962b1ee5a5f4da7d368ed80b..8ba0d2702ffaa048fb4bf54fc31ad1c0e346a58e 100644
--- a/dbrepo-ui/stores/cache.js
+++ b/dbrepo-ui/stores/cache.js
@@ -12,6 +12,8 @@ export const useCacheStore = defineStore('cache', {
       locale: null,
       ontologies: [],
       messages: [],
+      user: null,
+      roles: [],
       uploadProgress: null
     }
   },
@@ -24,6 +26,8 @@ export const useCacheStore = defineStore('cache', {
     getLocale: (state) => state.locale,
     getOntologies: (state) => state.ontologies,
     getMessages: (state) => state.messages,
+    getUser: (state) => state.user,
+    getRoles: (state) => state.roles,
     getUploadProgress: (state) => state.uploadProgress,
   },
   actions: {
@@ -48,6 +52,12 @@ export const useCacheStore = defineStore('cache', {
     setOntologies(ontologies) {
       this.ontologies = ontologies
     },
+    setUser(user) {
+      this.user = user
+    },
+    setRoles(roles) {
+      this.roles = roles
+    },
     setUploadProgress(uploadProgress) {
       this.uploadProgress = uploadProgress
     },
@@ -120,7 +130,6 @@ export const useCacheStore = defineStore('cache', {
     setRouteTable(databaseId, tableId) {
       if (!databaseId || !tableId) {
         this.table = null
-        console.error('Cannot set route table: missing database id', databaseId, 'or table id', tableId)
         return
       }
       const tableService = useTableService()
@@ -130,7 +139,6 @@ export const useCacheStore = defineStore('cache', {
     setRouteAccess(databaseId, userId) {
       if (!databaseId || !userId) {
         this.access = null
-        console.error('Cannot set route access: missing database id', databaseId, 'or user id', userId)
         return
       }
       const accessService = useAccessService()
@@ -140,7 +148,6 @@ export const useCacheStore = defineStore('cache', {
     setRouteView(databaseId, viewId) {
       if (!databaseId || !viewId) {
         this.view = null
-        console.error('Cannot set route view: database view id', databaseId, 'or view id', viewId)
         return
       }
       const viewService = useViewService()
@@ -150,7 +157,6 @@ export const useCacheStore = defineStore('cache', {
     setRouteSubset(databaseId, subsetId) {
       if (!databaseId || !subsetId) {
         this.subset = null
-        console.error('Cannot set route subset: missing database id', databaseId, 'or subset id', subsetId)
         return
       }
       const subsetService = useQueryService()