diff --git a/apps/web/src/app/App.tsx b/apps/web/src/app/App.tsx
index 8384d11a825191e1da7bd594f09382bea1b5a7bd..17355b18515c817eda3e5f0c0d4f859ee51ac3d7 100644
--- a/apps/web/src/app/App.tsx
+++ b/apps/web/src/app/App.tsx
@@ -1,7 +1,7 @@
 import React, { useEffect, useState } from 'react';
 import {
   useAppDispatch,
-  useAuthorizationCache,
+  useAuthCache,
   useML,
   useQuerybuilderGraph,
   useQuerybuilderSettings,
@@ -11,11 +11,10 @@ import { addError, setCurrentTheme } from '@graphpolaris/shared/lib/data-access/
 import { resetGraphQueryResults, queryingBackend } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice';
 import { Query2BackendQuery, QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder';
 import { Navbar } from '../components/navbar/navbar';
-import { Resizable } from '@graphpolaris/shared/lib/components/layout';
-import { DashboardAlerts } from '@graphpolaris/shared/lib/data-access/authorization/dashboardAlerts';
+import { FrozenOverlay, Resizable } from '@graphpolaris/shared/lib/components/layout';
+import { DashboardAlerts } from '@graphpolaris/shared/lib/data-access/security/dashboardAlerts';
 import { EventBus } from '@graphpolaris/shared/lib/data-access/api/eventBus';
 import { Onboarding } from '../components/onboarding/onboarding';
-import { wsQueryRequest } from '@graphpolaris/shared/lib/data-access/broker';
 import { URLParams, setParam } from '@graphpolaris/shared/lib/data-access/api/url';
 import { VisualizationPanel } from '@graphpolaris/shared/lib/vis';
 import { QueryBuilder } from '@graphpolaris/shared/lib/querybuilder';
@@ -24,6 +23,7 @@ import { InspectorPanel } from '@graphpolaris/shared/lib/inspector';
 import { SearchBar } from '@graphpolaris/shared/lib/sidebar/search/SearchBar';
 import { Schema } from '@graphpolaris/shared/lib/schema/panel';
 import { InsightDialog } from '@graphpolaris/shared/lib/insight-sharing';
+import { wsQueryRequest } from '@graphpolaris/shared/lib/data-access/broker';
 import { ErrorBoundary } from '@graphpolaris/shared/lib/components/errorBoundary';
 
 export type App = {
@@ -31,7 +31,7 @@ export type App = {
 };
 
 export function App(props: App) {
-  const auth = useAuthorizationCache();
+  const auth = useAuthCache();
   const query = useQuerybuilderGraph() as QueryMultiGraph;
   const ml = useML();
   const session = useSessionCache();
@@ -76,7 +76,7 @@ export function App(props: App) {
         <>
           <Onboarding />
           <DashboardAlerts />
-          <div className={'h-screen w-screen ' + (!auth.authorized ? 'blur-sm pointer-events-none ' : '')}>
+          <div className={'h-screen w-screen '}>
             <div className="flex flex-col h-screen max-h-screen relative">
               <aside className="absolute w-full h-12">
                 <Navbar />
@@ -139,6 +139,12 @@ export function App(props: App) {
               </main>
             </div>
           </div>
+          <FrozenOverlay>
+            {!auth.authentication?.authenticated && <span>Not Authenticated</span>}
+            {!auth.authorization.savestate.W && !session.currentSaveState && (
+              <span>Viewer account not authorized. Please load a shared exploration.</span>
+            )}
+          </FrozenOverlay>
         </>
       )}
     </div>
diff --git a/apps/web/src/components/navbar/DatabaseManagement/dbConnectionSelector.tsx b/apps/web/src/components/navbar/DatabaseManagement/dbConnectionSelector.tsx
index 1aa68725524b790b99fd55dec268996fb154fa5a..fabd61ac9c089f7ad3d63a1a99962577bee90c1e 100644
--- a/apps/web/src/components/navbar/DatabaseManagement/dbConnectionSelector.tsx
+++ b/apps/web/src/components/navbar/DatabaseManagement/dbConnectionSelector.tsx
@@ -1,11 +1,5 @@
 import React, { useEffect, useState, useCallback } from 'react';
-import {
-  useAppDispatch,
-  useSchemaGraph,
-  useSessionCache,
-  useAuthorizationCache,
-  useCheckPermissionPolicy,
-} from '@graphpolaris/shared/lib/data-access';
+import { useAppDispatch, useSchemaGraph, useSessionCache, useAuthCache } from '@graphpolaris/shared/lib/data-access';
 import { deleteSaveState, selectSaveState } from '@graphpolaris/shared/lib/data-access/store/sessionSlice';
 import { SettingsForm } from './forms/settings';
 import { LoadingSpinner } from '@graphpolaris/shared/lib/components/LoadingSpinner';
@@ -21,7 +15,7 @@ export default function DatabaseSelector({}) {
   const dispatch = useAppDispatch();
   const session = useSessionCache();
   const schemaGraph = useSchemaGraph();
-  const authCache = useAuthorizationCache();
+  const authCache = useAuthCache();
   const [hovered, setHovered] = useState<string | null>(null);
   const [connecting, setConnecting] = useState<boolean>(false);
   const [dbSelectionMenuOpen, setDbSelectionMenuOpen] = useState<boolean>(false);
@@ -61,33 +55,10 @@ export default function DatabaseSelector({}) {
     };
   }, [connecting]);
 
-  const { canRead, canWrite } = useCheckPermissionPolicy();
-  const [readAllowed, setReadAllowed] = useState(false);
-  const [writeAllowed, setWriteAllowed] = useState(false);
-  const resource = 'database';
-
-  const checkReadPermission = useCallback(async () => {
-    const result = await canRead(resource);
-    setReadAllowed(result);
-  }, [canRead]);
-
-  const checkWritePermission = useCallback(async () => {
-    const result = await canWrite(resource);
-    setWriteAllowed(result);
-  }, [canWrite]);
-
-  useEffect(() => {
-    checkReadPermission();
-  }, [checkReadPermission]);
-
-  useEffect(() => {
-    checkWritePermission();
-  }, [checkWritePermission]);
-
   return (
     <div className="menu-walkthrough">
       <TooltipProvider delayDuration={1000}>
-        {settingsMenuOpen !== undefined && (
+        {settingsMenuOpen !== undefined && authCache.authorization.savestate.W && (
           <SettingsForm
             open={settingsMenuOpen}
             saveState={settingsMenuOpen === 'update' ? selectedSaveState : null}
@@ -113,14 +84,23 @@ export default function DatabaseSelector({}) {
         >
           <DropdownTrigger
             onClick={() => {
-              if (connecting || authCache.authorized === false || !!authCache.roomID || writeAllowed) {
-                console.debug('User blocked from editing query due to being a viewer');
+              if (
+                connecting ||
+                authCache.authentication?.authenticated === false ||
+                !!authCache.authentication?.roomID ||
+                authCache.authorization.savestate.W
+              ) {
                 setDbSelectionMenuOpen(!dbSelectionMenuOpen);
               }
             }}
             className="w-[18rem]"
             size="md"
-            disabled={connecting || authCache.authorized === false || !!authCache.roomID || !writeAllowed}
+            noDropdownArrow={
+              connecting ||
+              authCache.authentication?.authenticated === false ||
+              !!authCache.authentication?.roomID ||
+              !authCache.authorization.savestate.W
+            }
             title={
               <div className="flex items-center">
                 {connecting && session.currentSaveState && session.currentSaveState in session.saveStates ? (
diff --git a/apps/web/src/components/navbar/DatabaseManagement/forms/settings.tsx b/apps/web/src/components/navbar/DatabaseManagement/forms/settings.tsx
index 48a7112228f77189b8c69cf8cf9f6bedbf157e5c..1877544da7e7c934c7252469724a619c85cb17e1 100644
--- a/apps/web/src/components/navbar/DatabaseManagement/forms/settings.tsx
+++ b/apps/web/src/components/navbar/DatabaseManagement/forms/settings.tsx
@@ -5,7 +5,7 @@ import {
   wsUpdateState,
   wsTestDatabaseConnection,
   wsCreateState,
-  useAuthorizationCache,
+  useAuthCache,
   nilUUID,
 } from '@graphpolaris/shared/lib/data-access';
 import { Dialog, DialogContent } from '@graphpolaris/shared/lib/components/layout';
@@ -25,9 +25,9 @@ type Connection = {
 export const SettingsForm = (props: { onClose(): void; open: 'add' | 'update'; saveState: SaveStateI | null; disableCancel?: boolean }) => {
   const dispatch = useAppDispatch();
   const ref = useRef<HTMLDialogElement>(null);
-  const auth = useAuthorizationCache();
+  const auth = useAuthCache();
   const [formData, setFormData] = useImmer(
-    props.saveState && props.open === 'update' ? props.saveState : { ...INITIAL_SAVE_STATE, user_id: auth.userID || '' },
+    props.saveState && props.open === 'update' ? props.saveState : { ...INITIAL_SAVE_STATE, user_id: auth.authentication?.userID || '' },
   );
   const [hasError, setHasError] = useState(false);
   const [sampleDataPanel, setSampleDataPanel] = useState<boolean | null>(false);
@@ -60,9 +60,13 @@ export const SettingsForm = (props: { onClose(): void; open: 'add' | 'update'; s
         console.error('formData is null');
         return;
       }
-      if (saveStateData.user_id !== auth.userID && auth.userID) {
+      if (!auth.authentication) {
+        console.error('auth is null');
+        return;
+      }
+      if (saveStateData.user_id !== auth.authentication.userID && auth.authentication.userID) {
         console.error('user_id is not equal to auth.userID');
-        saveStateData.user_id = auth.userID;
+        saveStateData.user_id = auth.authentication.userID;
       }
       if (data && data.status === 'success') {
         setConnection((prevState) => ({
@@ -107,7 +111,7 @@ export const SettingsForm = (props: { onClose(): void; open: 'add' | 'update'; s
       status: null,
       verified: null,
     });
-    setFormData({ ...INITIAL_SAVE_STATE, user_id: auth.userID || '' });
+    setFormData({ ...INITIAL_SAVE_STATE, user_id: auth.authentication?.userID || '' });
     ref.current?.close();
     props.onClose();
   }
@@ -143,7 +147,7 @@ export const SettingsForm = (props: { onClose(): void; open: 'add' | 'update'; s
             <SampleDatabaseSelector
               onClick={(data) => {
                 setHasError(false);
-                handleSubmit({ ...data, user_id: auth.userID || '' });
+                handleSubmit({ ...data, user_id: auth.authentication?.userID || '' });
               }}
             />
           ) : (
diff --git a/apps/web/src/components/navbar/navbar.tsx b/apps/web/src/components/navbar/navbar.tsx
index ab2cbcfa2e880ef155e8084a15434e0af8a36fa1..435a06ecad03130790e262a6ea736dcfc10c890a 100644
--- a/apps/web/src/components/navbar/navbar.tsx
+++ b/apps/web/src/components/navbar/navbar.tsx
@@ -9,7 +9,7 @@
  * We do not test components/renderfunctions/styling files.
  * See testing plan for more details.*/
 import React, { useState, useRef, useEffect, useCallback } from 'react';
-import { useAuthorizationCache, useAuth, useCheckPermissionPolicy } from '@graphpolaris/shared/lib/data-access';
+import { useAuthCache, useAuthentication } from '@graphpolaris/shared/lib/data-access';
 import DatabaseSelector from './DatabaseManagement/dbConnectionSelector';
 import { DropdownItem } from '@graphpolaris/shared/lib/components/dropdowns';
 import GpLogo from './gp-logo';
@@ -22,8 +22,8 @@ import { showManagePermissions, showSharableExploration } from 'config';
 
 export const Navbar = () => {
   const dropdownRef = useRef<HTMLDivElement>(null);
-  const auth = useAuth();
-  const authCache = useAuthorizationCache();
+  const auth = useAuthentication();
+  const authCache = useAuthCache();
   const [menuOpen, setMenuOpen] = useState(false);
   const dispatch = useDispatch();
   const buildInfo = import.meta.env.GRAPHPOLARIS_VERSION;
@@ -40,28 +40,28 @@ export const Navbar = () => {
     };
   }, [menuOpen]);
 
-  const { canRead, canWrite } = useCheckPermissionPolicy();
+  // const { canRead, canWrite } = useCheckPermissionPolicy();
   const [readAllowed, setReadAllowed] = useState(false);
   const [writeAllowed, setWriteAllowed] = useState(false);
-  const resource = 'policy';
+  // const resource = 'policy';
 
-  const checkReadPermission = useCallback(async () => {
-    const result = await canRead(resource);
-    setReadAllowed(result);
-  }, [canRead]);
+  // const checkReadPermission = useCallback(async () => {
+  //   const result = await canRead(resource);
+  //   setReadAllowed(result);
+  // }, [canRead]);
 
-  const checkWritePermission = useCallback(async () => {
-    const result = await canWrite(resource);
-    setWriteAllowed(result);
-  }, [canWrite]);
+  // const checkWritePermission = useCallback(async () => {
+  //   const result = await canWrite(resource);
+  //   setWriteAllowed(result);
+  // }, [canWrite]);
 
-  useEffect(() => {
-    checkReadPermission();
-  }, [checkReadPermission]);
+  // useEffect(() => {
+  //   checkReadPermission();
+  // }, [checkReadPermission]);
 
-  useEffect(() => {
-    checkWritePermission();
-  }, [checkWritePermission]);
+  // useEffect(() => {
+  //   checkWritePermission();
+  // }, [checkWritePermission]);
 
   const handleConfirmUsers = (users: { name: string; email: string; type: string }[]) => {
     //TODO !FIXME: when the user clicks on confirm, users state is ready to be sent to backend
@@ -85,17 +85,17 @@ export const Navbar = () => {
                 className="relative inline-flex items-center justify-center w-8 h-8 overflow-hidden bg-secondary-500 rounded-full hover:bg-secondary-600 transition-colors duration-150 ease-in-out cursor-pointer"
                 onClick={() => setMenuOpen(!menuOpen)}
               >
-                <span className="font-medium text-light">{authCache.username?.slice(0, 2).toUpperCase()}</span>
+                <span className="font-medium text-light">{authCache.authentication?.username?.slice(0, 2).toUpperCase()}</span>
               </div>
             </PopoverTrigger>
 
             <PopoverContent className="w-56 z-30 bg-light rounded-sm border-[1px] outline-none">
               <div className="p-2 text-sm border-b">
-                <h2 className="font-bold">user: {authCache.username}</h2>
-                <h3 className="text-xs break-words">session: {authCache.sessionID}</h3>
+                <h2 className="font-bold">user: {authCache.authentication?.username}</h2>
+                <h3 className="text-xs break-words">session: {authCache.authentication?.sessionID}</h3>
                 <h3 className="text-xs break-words">license: Creator</h3>
               </div>
-              {authCache.authorized ? (
+              {authCache.authentication?.authenticated ? (
                 <>
                   {showSharableExploration() && (
                     <DropdownItem
@@ -115,9 +115,9 @@ export const Navbar = () => {
                   <DropdownItem value="Login" onClick={() => {}} />
                 </>
               )}
-              {authCache?.roomID && (
+              {authCache.authentication?.roomID && (
                 <div className="p-2 border-b">
-                  <h3 className="text-xs break-words">Share ID: {authCache.roomID}</h3>
+                  <h3 className="text-xs break-words">Share ID: {authCache.authentication?.roomID}</h3>
                 </div>
               )}
               <div className="p-2 border-t">
@@ -129,7 +129,7 @@ export const Navbar = () => {
                     <DialogTrigger className="ml-2 text-sm hover:bg-secondary-200">Manage Viewers Permission</DialogTrigger>
                     <DialogContent>
                       <UserManagementContent
-                        sessionId={authCache.sessionID ?? ''}
+                        sessionId={authCache.authentication?.sessionID ?? ''}
                         onConfirm={handleConfirmUsers}
                         onClickShareLink={handleClickShareLink}
                       />
diff --git a/apps/web/src/components/onboarding/onboarding.tsx b/apps/web/src/components/onboarding/onboarding.tsx
index 285cdebeecc87810c5165bd470d6628bb3229240..3327615ceaa543b2eed7d4604b6ffe676953151b 100644
--- a/apps/web/src/components/onboarding/onboarding.tsx
+++ b/apps/web/src/components/onboarding/onboarding.tsx
@@ -3,7 +3,7 @@ import Joyride, { ACTIONS, EVENTS, STATUS, Step } from 'react-joyride';
 import { useLocation } from 'react-router-dom';
 import { Button } from '@graphpolaris/shared/lib/components/buttons';
 import { useCases } from './use-cases';
-import { useAuthorizationCache } from '@graphpolaris/shared/lib/data-access';
+import { useAuthCache } from '@graphpolaris/shared/lib/data-access';
 
 interface OnboardingState {
   run?: boolean;
@@ -12,7 +12,7 @@ interface OnboardingState {
 
 export function Onboarding({}) {
   const location = useLocation();
-  const auth = useAuthorizationCache();
+  const auth = useAuthCache();
   const [showWalkthrough, setShowWalkthrough] = useState<boolean>(false);
   const [onboarding, setOnboarding] = useState<OnboardingState>({
     run: false,
diff --git a/libs/shared/lib/components/buttons/Button.tsx b/libs/shared/lib/components/buttons/Button.tsx
index 79422a12dde0ff169650ec65fc91770b981728c1..639e7f9c6573916df649effc04a19b0252611512 100644
--- a/libs/shared/lib/components/buttons/Button.tsx
+++ b/libs/shared/lib/components/buttons/Button.tsx
@@ -139,6 +139,8 @@ export const Button = React.forwardRef<HTMLButtonElement | HTMLAnchorElement | H
       [iconComponent, label, children],
     );
 
+    const disabledClass = useMemo(() => (disabled ? 'cursor-not-allowed' : 'cursor-pointer'), [disabled]);
+
     const ButtonComponent = as;
 
     const isAnchor = as === 'a';
@@ -148,8 +150,8 @@ export const Button = React.forwardRef<HTMLButtonElement | HTMLAnchorElement | H
         {tooltip && <TooltipContent>{tooltip}</TooltipContent>}
         <TooltipTrigger>
           <ButtonComponent
-            className={`${styles.btn} ${typeClass} ${variantClass} ${sizeClass} ${blockClass} ${roundedClass} ${iconOnlyClass} ${className ? className : ''}`}
-            onClick={onClick}
+            className={`${styles.btn} ${typeClass} ${variantClass} ${sizeClass} ${blockClass} ${roundedClass} ${iconOnlyClass} ${disabledClass} ${className ? className : ''}`}
+            onClick={disabled ? undefined : onClick}
             disabled={disabled}
             aria-label={ariaLabel}
             href={isAnchor ? href : undefined}
diff --git a/libs/shared/lib/components/dropdowns/index.tsx b/libs/shared/lib/components/dropdowns/index.tsx
index 47f82156b32113805b40914e5dda9fbc027a10ed..3bbc861cb2d15cc0dd74820264704cc80f06663b 100644
--- a/libs/shared/lib/components/dropdowns/index.tsx
+++ b/libs/shared/lib/components/dropdowns/index.tsx
@@ -19,6 +19,7 @@ type DropdownTriggerProps = {
   popover?: boolean;
   onClick?: () => void;
   children?: ReactNode;
+  noDropdownArrow?: boolean;
 };
 
 export function DropdownTrigger({
@@ -28,23 +29,30 @@ export function DropdownTrigger({
   variant,
   className,
   onClick,
+  noDropdownArrow = false,
   popover = true,
   children = undefined,
 }: DropdownTriggerProps) {
   const paddingClass = size === 'xs' ? 'py-0' : size === 'sm' ? 'px-1 py-1' : size === 'md' ? 'px-2 py-1' : 'px-4 py-2';
   const textSizeClass = size === 'xs' ? 'text-xs' : size === 'sm' ? 'text-sm' : size === 'md' ? 'text-base' : 'text-lg';
+
+  const disabledClass = disabled ? 'cursor-not-allowed' : 'cursor-pointer';
   const variantClass =
     variant === 'primary' || !variant
       ? 'border bg-light rounded'
       : variant === 'ghost'
         ? 'bg-transparent shadow-none'
         : 'border rounded bg-transparent';
-  const inner = children || (
+  const inner = children ? (
+    React.cloneElement(children as React.ReactElement, {
+      disabled: disabled,
+    })
+  ) : (
     <div
-      className={`inline-flex w-full truncate justify-between items-center gap-x-1.5 ${variantClass} ${textSizeClass} ${paddingClass} text-secondary-900 shadow-sm ${disabled ? ` cursor-not-allowed text-secondary-400 bg-secondary-100` : 'cursor-pointer'}  pl-1 truncate`}
+      className={`inline-flex w-full truncate justify-between items-center gap-x-1.5 ${variantClass} ${textSizeClass} ${paddingClass} text-secondary-900 shadow-sm ${noDropdownArrow ? `pointer-events-none cursor-default` : ''} ${disabled ? ` cursor-not-allowed text-secondary-400 bg-secondary-100` : 'cursor-pointer'}  pl-1 truncate`}
     >
       <span className={`text-${size}`}>{title}</span>
-      <Icon component="icon-[ic--baseline-arrow-drop-down]" size={16} />
+      {!noDropdownArrow && <Icon component="icon-[ic--baseline-arrow-drop-down]" size={16} />}
     </div>
   );
 
diff --git a/libs/shared/lib/components/inputs/index.tsx b/libs/shared/lib/components/inputs/index.tsx
index 7d4a98f33ae1dfcb04be07f471192f5e6e85a57b..0bf99b5541b30bdebcc9cca3a0f3e6d3ea0d1f95 100644
--- a/libs/shared/lib/components/inputs/index.tsx
+++ b/libs/shared/lib/components/inputs/index.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react';
+import React, { MouseEventHandler, useEffect, useState } from 'react';
 import styles from './inputs.module.scss';
 import { DropdownTrigger, DropdownContainer, DropdownItem, DropdownItemContainer } from '../dropdowns';
 import Info from '../info';
@@ -34,7 +34,7 @@ type TextProps = {
   className?: string;
   validate?: (value: any) => boolean;
   onChange?: (value: string) => void;
-  onClick?: (e: Event) => void;
+  onClick?: (e: any) => void;
 };
 
 type NumberProps = {
diff --git a/libs/shared/lib/components/layout/FrozenOverlay.tsx b/libs/shared/lib/components/layout/FrozenOverlay.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..92bf9fc14ed9e440458a5b1fb508f4b9e67dc1a6
--- /dev/null
+++ b/libs/shared/lib/components/layout/FrozenOverlay.tsx
@@ -0,0 +1,9 @@
+export const FrozenOverlay = (props: { children: React.ReactNode; enabled?: boolean }) => {
+  if (!props.enabled || !props.children || props.children === '') return null;
+
+  return (
+    <div className="absolute h-screen w-screen left-0 top-0 flex justify-center items-center blur-sm pointer-events-none z-50">
+      <div className="text-3xl font-bold">{props.children}</div>
+    </div>
+  );
+};
diff --git a/libs/shared/lib/components/layout/index.ts b/libs/shared/lib/components/layout/index.ts
index 93c40e5237fe125e95be4abf2d400f68187b8ea8..e2a065262500480e40025f26d1fa3babaf49de48 100644
--- a/libs/shared/lib/components/layout/index.ts
+++ b/libs/shared/lib/components/layout/index.ts
@@ -1,3 +1,4 @@
 export * from './Dialog';
 export * from './Panel';
 export * from './Resizable';
+export * from './FrozenOverlay';
diff --git a/libs/shared/lib/data-access/api/eventBus.tsx b/libs/shared/lib/data-access/api/eventBus.tsx
index 4a5df9196bb36eee511d364291969ecc565f9206..283f07dd8ce57c9caa1962fd9761f327e4e06635 100644
--- a/libs/shared/lib/data-access/api/eventBus.tsx
+++ b/libs/shared/lib/data-access/api/eventBus.tsx
@@ -1,6 +1,6 @@
 import {
-  useAuth,
-  useAuthorizationCache,
+  useAuthentication,
+  useAuthCache,
   useAppDispatch,
   useSessionCache,
   useQuerybuilderHash,
@@ -32,6 +32,7 @@ import {
   wsGetStateSubscription,
   wsSelectStateSubscription,
   wsTestSaveStateConnectionSubscription,
+  wsStateGetPolicy,
 } from '../broker/wsState';
 import {
   addSaveState,
@@ -40,6 +41,7 @@ import {
   updateSaveStateList,
   updateSelectedSaveState,
   setFetchingSaveStates,
+  setStateAuthorization,
 } from '../store/sessionSlice';
 import { URLParams, getParam, deleteParam } from './url';
 import { VisState, setVisualizationState } from '../store/visualizationSlice';
@@ -48,10 +50,12 @@ import { setSchemaAttributeDimensions, setSchemaAttributeInformation } from '../
 import { addError } from '@graphpolaris/shared/lib/data-access/store/configSlice';
 import { unSelect } from '../store/interactionSlice';
 import { SchemaGraphStats } from '../../schema';
+import { wsUserGetPolicy, wsUserPolicyCheck } from '../broker/wsUser';
+import { authorized } from '../store/authSlice';
 
 export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }) => {
-  const { login } = useAuth();
-  const auth = useAuthorizationCache();
+  const { login } = useAuthentication();
+  const auth = useAuthCache();
   const dispatch = useAppDispatch();
   const session = useSessionCache();
   const queryHash = useQuerybuilderHash();
@@ -134,6 +138,13 @@ export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }
         dispatch(updateSaveStateList(data));
         const d = Object.fromEntries(data.map((x) => [x.id, x]));
         loadSaveState(session.currentSaveState, d);
+        data.forEach((ss) => {
+          if (session.saveStatesAuthorization?.[ss.id] === undefined) {
+            wsStateGetPolicy(ss.id, (ret) => {
+              dispatch(setStateAuthorization({ id: ss.id, authorization: ret }));
+            });
+          }
+        });
       }),
     );
 
@@ -143,6 +154,9 @@ export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }
           dispatch(addSaveState(data));
           dispatch(selectSaveState(data.id));
           loadSaveState(data.id, session.saveStates);
+          wsStateGetPolicy(data.id, (ret) => {
+            dispatch(setStateAuthorization({ id: data.id, authorization: ret }));
+          });
         }
       }),
     );
@@ -217,11 +231,12 @@ export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }
   }, [session.currentSaveState]);
 
   useEffect(() => {
+    // debugger;
     // Newly (un)authorized
-    if (auth.authorized && auth.jwt) {
+    if (auth.authentication?.authenticated && auth.authentication?.jwt) {
       props.onAuthorized();
       Broker.instance()
-        .useAuth(auth)
+        .useAuth(auth.authentication)
         .connect(() => {
           console.debug('WS connected', session.currentSaveState, window.location.search);
 
@@ -233,6 +248,12 @@ export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }
           }
 
           dispatch(setFetchingSaveStates(true));
+
+          // check authorizations
+          wsUserGetPolicy((res) => {
+            dispatch(authorized(res));
+          });
+
           wsGetStates((data) => {
             dispatch(setFetchingSaveStates(false));
             return true;
@@ -247,7 +268,7 @@ export const EventBus = (props: { onRunQuery: Function; onAuthorized: Function }
     } else {
       // dispatch(logout());
     }
-  }, [auth]);
+  }, [auth.authentication]);
 
   useEffect(() => {
     if (!queryBuilder.ignoreReactivity) {
diff --git a/libs/shared/lib/data-access/authorization/index.ts b/libs/shared/lib/data-access/authorization/index.ts
deleted file mode 100644
index a9af457e957878d170b5ce0b9cdca1327e8aa9df..0000000000000000000000000000000000000000
--- a/libs/shared/lib/data-access/authorization/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './useAuth';
-export * from './useResourcesPolicy';
diff --git a/libs/shared/lib/data-access/authorization/useResourcesPolicy.tsx b/libs/shared/lib/data-access/authorization/useResourcesPolicy.tsx
deleted file mode 100644
index d7390ba3a6c4f5b186c2d3633d3fc738d70cb290..0000000000000000000000000000000000000000
--- a/libs/shared/lib/data-access/authorization/useResourcesPolicy.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { useResourcesPolicy } from '@graphpolaris/shared/lib/data-access';
-import { useMemo } from 'react';
-//import casbinjs from 'casbin.js';
-import { Authorizer } from 'casbin.js';
-export const useCheckPermissionPolicy = () => {
-  const policyPermissions = useResourcesPolicy();
-
-  const authorizer = useMemo(() => {
-    // docs tell to go this way, but it doesn't work
-    //const auth = new casbinjs.Authorizer('manual');
-    const auth = new Authorizer('manual');
-
-    const permission = {
-      read: policyPermissions.read,
-      write: policyPermissions.write,
-    };
-
-    auth.setPermission(permission);
-
-    return auth;
-  }, [policyPermissions]);
-
-  const canRead = async (resource: string) => {
-    return await authorizer.can('read', resource);
-  };
-
-  const canWrite = async (resource: string) => {
-    return await authorizer.can('write', resource);
-  };
-
-  return {
-    canRead,
-    canWrite,
-  };
-};
diff --git a/libs/shared/lib/data-access/broker/broker.tsx b/libs/shared/lib/data-access/broker/broker.tsx
index c8059b644abb4f35aa9d14dd3ab4adb0407ae154..ab9739aad520ef4d7c2341d20b0929ca98fb1d15 100644
--- a/libs/shared/lib/data-access/broker/broker.tsx
+++ b/libs/shared/lib/data-access/broker/broker.tsx
@@ -125,7 +125,11 @@ export class Broker {
    */
   public connect(onOpen: () => void): void {
     // If there already is already a current websocket connection, close it first.
-    if (this.webSocket) this.close();
+    console.debug('WS connection! Connecting to ' + this.url);
+    if (this.webSocket) {
+      console.warn('Closing old websocket connection');
+      this.close();
+    }
 
     const params = new URLSearchParams(window.location.search);
     // Most of these parameters are only really used in DEV
@@ -146,6 +150,7 @@ export class Broker {
 
   /** Closes the current websocket connection. */
   public close = (): void => {
+    console.warn('Closing WS for some reason');
     if (this.webSocket) this.webSocket.close();
     this.connected = false;
     this.webSocket = undefined;
diff --git a/libs/shared/lib/data-access/broker/types.ts b/libs/shared/lib/data-access/broker/types.ts
index 804715a37f1f0cce55001b47e41d7b64a5b7b1f1..883b2b111a08a7338550f49b9fecbeaac3a40885 100644
--- a/libs/shared/lib/data-access/broker/types.ts
+++ b/libs/shared/lib/data-access/broker/types.ts
@@ -19,7 +19,7 @@ type QueryOrchestratorMessage = {
   queryID: string;
 };
 
-export type keyTypeI = 'broadcastState' | 'dbConnection' | 'schema' | 'query' | 'state';
+export type keyTypeI = 'broadcastState' | 'dbConnection' | 'schema' | 'query' | 'state' | 'user';
 export type subKeyTypeI =
   // Crud
   | 'create'
@@ -37,7 +37,9 @@ export type subKeyTypeI =
   | 'testConnection'
   | 'getSchema'
   | 'getSchemaStats'
-  | 'runQuery';
+  | 'runQuery'
+  | 'getPolicy'
+  | 'policyCheck';
 
 export type SendMessageI = {
   key: keyTypeI;
diff --git a/libs/shared/lib/data-access/broker/wsState.tsx b/libs/shared/lib/data-access/broker/wsState.tsx
index 477121dff1e7f6f17c0555f55ff381cf7f6153a3..d938c9f2a17d142fe2e8567ec95d576cd52b039e 100644
--- a/libs/shared/lib/data-access/broker/wsState.tsx
+++ b/libs/shared/lib/data-access/broker/wsState.tsx
@@ -3,6 +3,7 @@ import { URLParams, setParam } from '../api/url';
 import { Broker } from './broker';
 import { DateStringStatement } from '../../querybuilder/model/logic/general';
 import { VisState } from '../store/visualizationSlice';
+import { AuthorizationOperations } from '../store/authSlice';
 
 export const databaseNameMapping: string[] = ['arangodb', 'neo4j'];
 export const databaseProtocolMapping: string[] = ['neo4j://', 'neo4j+s://', 'bolt://', 'bolt+s://'];
@@ -28,6 +29,15 @@ export type DatabaseInfo = {
   type: number;
 };
 
+export const SaveStateAuthorizationObjectsArray = ['database', 'visualization', 'query', 'schema'] as const;
+export type SaveStateAuthorizationObjects = (typeof SaveStateAuthorizationObjectsArray)[number];
+
+export type SaveStateAuthorizationHeaders = {
+  [id in SaveStateAuthorizationObjects]: {
+    [id in AuthorizationOperations]: boolean;
+  };
+};
+
 export const nilUUID = '00000000-0000-0000-0000-000000000000';
 
 export type SaveStateI = {
@@ -168,3 +178,15 @@ export function wsTestDatabaseConnection(dbConnection: DatabaseInfo, callback?:
     callback,
   );
 }
+
+type StateGetPolicyResponse = (data: SaveStateAuthorizationHeaders) => void;
+export function wsStateGetPolicy(saveStateID: string, callback?: StateGetPolicyResponse) {
+  Broker.instance().sendMessage(
+    {
+      key: 'state',
+      subKey: 'getPolicy',
+      body: { SaveStateID: saveStateID },
+    },
+    callback,
+  );
+}
diff --git a/libs/shared/lib/data-access/broker/wsUser.tsx b/libs/shared/lib/data-access/broker/wsUser.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..9b6e50a6a91cc5a1e82133a992ee48001c8de9eb
--- /dev/null
+++ b/libs/shared/lib/data-access/broker/wsUser.tsx
@@ -0,0 +1,26 @@
+import { UserAuthorizationHeaders } from '../store/authSlice';
+import { Broker } from './broker';
+
+type UserPolicyCheckResponse = (data: boolean) => void;
+export function wsUserPolicyCheck(policyCheck: { object: string; operation: string }, callback?: UserPolicyCheckResponse) {
+  Broker.instance().sendMessage(
+    {
+      key: 'user',
+      subKey: 'policyCheck',
+      body: policyCheck, //messageTypePolicyCheck
+    },
+    callback,
+  );
+}
+
+type UserGetPolicyResponse = (data: UserAuthorizationHeaders) => void;
+export function wsUserGetPolicy(callback?: UserGetPolicyResponse) {
+  Broker.instance().sendMessage(
+    {
+      key: 'user',
+      subKey: 'getPolicy',
+      body: {},
+    },
+    callback,
+  );
+}
diff --git a/libs/shared/lib/data-access/index.ts b/libs/shared/lib/data-access/index.ts
index 1084b2e70f182f2f4be6541f0baef9ea070439f7..59d9138a5504188f287e18abdaf04104209303ee 100644
--- a/libs/shared/lib/data-access/index.ts
+++ b/libs/shared/lib/data-access/index.ts
@@ -1,3 +1,3 @@
 export * from './api';
-export * from './authorization';
+export * from './security';
 export * from './store';
diff --git a/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx b/libs/shared/lib/data-access/security/dashboardAlerts.tsx
similarity index 100%
rename from libs/shared/lib/data-access/authorization/dashboardAlerts.tsx
rename to libs/shared/lib/data-access/security/dashboardAlerts.tsx
diff --git a/libs/shared/lib/data-access/security/index.ts b/libs/shared/lib/data-access/security/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0015f2acd5a8c4e4ec89b9094df959308e04d4ec
--- /dev/null
+++ b/libs/shared/lib/data-access/security/index.ts
@@ -0,0 +1 @@
+export * from './useAuthentication';
diff --git a/libs/shared/lib/data-access/authorization/useAuth.tsx b/libs/shared/lib/data-access/security/useAuthentication.tsx
similarity index 60%
rename from libs/shared/lib/data-access/authorization/useAuth.tsx
rename to libs/shared/lib/data-access/security/useAuthentication.tsx
index 44f631b38ce472a0a7f108bb4d8f892cdcbc319f..f4718b51ca472c82b2a0323db6a396078a285cb7 100644
--- a/libs/shared/lib/data-access/authorization/useAuth.tsx
+++ b/libs/shared/lib/data-access/security/useAuthentication.tsx
@@ -1,17 +1,8 @@
-import { useEffect, useRef, useState } from 'react';
-import { useAppDispatch, useAuthorizationCache } from '../store';
-import { authorized, changeRoom } from '../store/authSlice';
-
-export type AuthenticationHeader = {
-  username: string;
-  userID: string;
-  sessionID: string;
-  roomID: string;
-  jwt: string;
-};
+import { useAppDispatch, useAuthCache } from '../store';
+import { authenticated, changeRoom, UserAuthenticationHeader } from '../store/authSlice';
 
 const domain = import.meta.env.BACKEND_URL;
-const useruri = import.meta.env.BACKEND_USER;
+const userURI = import.meta.env.BACKEND_USER;
 
 export const fetchSettings: RequestInit = {
   method: 'GET',
@@ -19,27 +10,28 @@ export const fetchSettings: RequestInit = {
   redirect: 'follow',
 };
 
-export const useAuth = () => {
+export const useAuthentication = () => {
   const dispatch = useAppDispatch();
-  const auth = useAuthorizationCache();
+  const auth = useAuthCache();
 
   const handleError = (err: any) => {
     console.error(err);
   };
 
   const login = () => {
-    fetch(`${domain}${useruri}/headers`, fetchSettings)
+    fetch(`${domain}${userURI}/headers`, fetchSettings)
       .then((res) =>
         res
           .json()
-          .then((res: AuthenticationHeader) => {
+          .then((res: UserAuthenticationHeader) => {
             dispatch(
-              authorized({
+              authenticated({
                 username: res.username,
                 userID: res.userID,
                 sessionID: res.sessionID,
                 jwt: res.jwt,
-                authorized: true,
+                authenticated: true,
+                roomID: res.roomID,
               }),
             );
           })
@@ -49,7 +41,7 @@ export const useAuth = () => {
   };
 
   const newShareRoom = () => {
-    fetch(`${domain}${useruri}/share`, { ...fetchSettings, method: 'POST' })
+    fetch(`${domain}${userURI}/share`, { ...fetchSettings, method: 'POST' })
       .then((res) =>
         res
           .json()
@@ -64,4 +56,3 @@ export const useAuth = () => {
 
   return { login, newShareRoom };
 };
-// export useAuth;
diff --git a/libs/shared/lib/data-access/store/authSlice.ts b/libs/shared/lib/data-access/store/authSlice.ts
index c89b16d6e340ef1bef8e1e04fed68cd61ed32899..160ca557c476fdd26542f48e60fd3298ffd4b12c 100644
--- a/libs/shared/lib/data-access/store/authSlice.ts
+++ b/libs/shared/lib/data-access/store/authSlice.ts
@@ -1,26 +1,55 @@
 import { createSlice, PayloadAction } from '@reduxjs/toolkit';
 import type { RootState } from './store';
+import { cloneDeep } from 'lodash-es';
+
+export const UserAuthorizationObjectsArray = ['savestate'] as const;
+export type UserAuthorizationObjects = (typeof UserAuthorizationObjectsArray)[number];
+
+export const AuthorizationOperationsArray = ['R', 'W'] as const;
+export type AuthorizationOperations = (typeof AuthorizationOperationsArray)[number];
+
+export type UserAuthorizationHeaders = {
+  [id in UserAuthorizationObjects]: {
+    [id in AuthorizationOperations]: boolean;
+  };
+};
+
+export const UserAuthorizationHeadersDefaults: UserAuthorizationHeaders = {
+  savestate: {
+    R: false,
+    W: false,
+  },
+};
+
+export type UserAuthenticationHeader = {
+  username: string;
+  userID: string;
+  sessionID: string;
+  roomID: string;
+  jwt: string;
+};
 
 export type UseIsAuthorizedState = SingleIsAuthorizedState & {
   roomID: string | undefined;
 };
 
 export type SingleIsAuthorizedState = {
-  authorized: boolean | undefined;
-  jwt: string | undefined;
-  sessionID: string | undefined;
-  userID: string | undefined;
-  username: string | undefined;
+  authenticated: boolean;
+  jwt: string;
+  sessionID: string;
+  userID: string;
+  username: string;
+  roomID: string | undefined;
 };
 
-// Define the initial state using that type
-export const initialState: UseIsAuthorizedState = {
-  authorized: undefined,
-  jwt: undefined,
-  sessionID: undefined,
-  roomID: undefined,
-  userID: undefined,
-  username: undefined,
+export type AuthSliceState = {
+  authentication: SingleIsAuthorizedState | undefined;
+  authorization: UserAuthorizationHeaders;
+};
+
+export const initialState: AuthSliceState = {
+  authentication: undefined,
+  authorization: cloneDeep(UserAuthorizationHeadersDefaults),
 };
 
 export const authSlice = createSlice({
@@ -28,17 +57,23 @@ export const authSlice = createSlice({
   // `createSlice` will infer the state type from the `initialState` argument
   initialState,
   reducers: {
-    authorized(state, action: PayloadAction<SingleIsAuthorizedState>) {
-      console.info('%cAuthorized ', 'background-color: blue', action.payload);
-      state.authorized = action.payload.authorized;
-      state.jwt = action.payload.jwt;
-      state.userID = action.payload.userID;
-      state.sessionID = action.payload.sessionID;
-      state.username = action.payload.username;
+    authenticated(state, action: PayloadAction<SingleIsAuthorizedState>) {
+      console.info('%cAuthenticated ', 'background-color: blue', action.payload);
+      state.authentication = action.payload;
+      state.authorization = cloneDeep(UserAuthorizationHeadersDefaults);
+    },
+    authorized(state, action: PayloadAction<UserAuthorizationHeaders>) {
+      console.info(`%cAuthorized Result: `, 'background-color: green', action.payload);
+      state.authorization = action.payload;
     },
     changeRoom(state, action: PayloadAction<string | undefined>) {
+      if (state.authentication === undefined) {
+        console.warn('Not authenticated');
+        return;
+      }
+
       console.info('Changing Room to', action.payload);
-      state.roomID = action.payload;
+      state.authentication.roomID = action.payload;
       const query = new URLSearchParams(window.location.search);
       if (!!action?.payload) {
         query.set('roomID', action?.payload || 'null');
@@ -50,26 +85,22 @@ export const authSlice = createSlice({
     },
     logout(state) {
       console.info('Logging out');
-      state.authorized = undefined;
-      state.jwt = undefined;
-      state.sessionID = undefined;
-      state.userID = undefined;
-      state.username = undefined;
-      const query = new URLSearchParams(window.location.search);
-      query.delete('roomID');
-      history.pushState(null, '', '?' + query.toString());
-    },
-    unauthorized(state) {
-      console.warn('Unauthorized');
-      state.authorized = false;
+      state = cloneDeep(initialState);
       const query = new URLSearchParams(window.location.search);
       query.delete('roomID');
       history.pushState(null, '', '?' + query.toString());
     },
+    // unauthorized(state) {
+    //   console.warn('Unauthorized');
+    //   state.authentication.authenticated = false;
+    //   const query = new URLSearchParams(window.location.search);
+    //   query.delete('roomID');
+    //   history.pushState(null, '', '?' + query.toString());
+    // },
   },
 });
 
-export const { authorized, unauthorized, logout, changeRoom } = authSlice.actions;
+export const { authorized, authenticated, logout, changeRoom } = authSlice.actions;
 
 // Other code such as selectors can use the imported `RootState` type
 export const authState = (state: RootState) => state.auth;
diff --git a/libs/shared/lib/data-access/store/hooks.ts b/libs/shared/lib/data-access/store/hooks.ts
index 9680186eda78820aa1ba510c73e91d0010b0e6ec..2c57d5045c2a1be3ab4868cdc1007f6741e216f0 100644
--- a/libs/shared/lib/data-access/store/hooks.ts
+++ b/libs/shared/lib/data-access/store/hooks.ts
@@ -19,8 +19,8 @@ import {
   selectQuerybuilderGraph,
   selectQuerybuilderHash,
 } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
-import { SessionCacheI, sessionCacheState } from './sessionSlice';
-import { UseIsAuthorizedState, authState } from './authSlice';
+import { activeSaveState, activeSaveStateAuthorization, SessionCacheI, sessionCacheState } from './sessionSlice';
+import { AuthSliceState, UseIsAuthorizedState, authState } from './authSlice';
 import { visualizationState, VisState, visualizationActive } from './visualizationSlice';
 import { ML, allMLEnabled, selectML } from './mlSlice';
 import {
@@ -40,6 +40,7 @@ import { SelectionStateI, FocusStateI, focusState, selectionState } from './inte
 import { VisualizationSettingsType } from '../../vis/common';
 import { PolicyUsersState, selectPolicyState } from './authorizationUsersSlice';
 import { PolicyResourcesState, selectResourcesPolicyState } from './authorizationResourcesSlice';
+import { SaveStateAuthorizationHeaders, SaveStateI } from '..';
 
 // Use throughout your app instead of plain `useDispatch` and `useSelector`
 export const useAppDispatch: () => AppDispatch = useDispatch;
@@ -67,7 +68,9 @@ export const useQuerybuilderAttributesShown: () => QueryGraphEdgeHandle[] = () =
 // Overall Configuration of the app
 export const useConfig: () => ConfigStateI = () => useAppSelector(configState);
 export const useSessionCache: () => SessionCacheI = () => useAppSelector(sessionCacheState);
-export const useAuthorizationCache: () => UseIsAuthorizedState = () => useAppSelector(authState);
+export const useActiveSaveState: () => SaveStateI = () => useAppSelector(activeSaveState);
+export const useActiveSaveStateAuthorization: () => SaveStateAuthorizationHeaders = () => useAppSelector(activeSaveStateAuthorization);
+export const useAuthCache: () => AuthSliceState = () => useAppSelector(authState);
 
 // Machine Learning Slices
 export const useML: () => ML = () => useAppSelector(selectML);
diff --git a/libs/shared/lib/data-access/store/querybuilderSlice.ts b/libs/shared/lib/data-access/store/querybuilderSlice.ts
index fb9e71062326c9c0aae94db64461dd9b2dbfaebf..df417947af928f0c66ed2b874afcb56b8c795315 100644
--- a/libs/shared/lib/data-access/store/querybuilderSlice.ts
+++ b/libs/shared/lib/data-access/store/querybuilderSlice.ts
@@ -46,7 +46,7 @@ export const initialState: QueryBuilderState = {
   },
   attributesBeingShown: [],
   // schemaLayout: 'Graphology_noverlap',
-};
+} as QueryBuilderState;
 
 //@ts-ignore(2589)
 export const querybuilderSlice = createSlice({
@@ -86,8 +86,8 @@ export const querybuilderSlice = createSlice({
   },
 });
 
-export const queryBuilderState = (state: RootState) => state.querybuilder;
-export const queryBuilderSettingsState = (state: RootState) => state.querybuilder.settings;
+export const queryBuilderState = (state: RootState): QueryBuilderState => state.querybuilder;
+export const queryBuilderSettingsState = (state: RootState): QueryBuilderSettings => state.querybuilder.settings;
 
 export const setQuerybuilderGraphology = (payload: QueryGraphology) => {
   return querybuilderSlice.actions.setQuerybuilderGraph(payload.export());
diff --git a/libs/shared/lib/data-access/store/sessionSlice.ts b/libs/shared/lib/data-access/store/sessionSlice.ts
index b061b17eeb3a199e6a3cb671e6bfcdfc137342cf..650e0e62982ddeb9d4b55bf20b91893e1f8fabfa 100644
--- a/libs/shared/lib/data-access/store/sessionSlice.ts
+++ b/libs/shared/lib/data-access/store/sessionSlice.ts
@@ -1,7 +1,9 @@
 import { createSlice, PayloadAction } from '@reduxjs/toolkit';
 import type { RootState } from './store';
-import { DatabaseStatus, SaveStateI } from '../broker/wsState';
+import { DatabaseStatus, SaveStateAuthorizationHeaders, SaveStateAuthorizationObjectsArray, SaveStateI } from '../broker/wsState';
 import { getParam, URLParams } from '../api/url';
+import { AuthorizationOperations } from './authSlice';
+import { cloneDeep } from 'lodash-es';
 
 /** Message format of the error message from the backend */
 export type ErrorMessage = {
@@ -13,14 +15,23 @@ export type ErrorMessage = {
 export type SessionCacheI = {
   currentSaveState?: string; // id of the current save state
   saveStates: Record<string, SaveStateI>;
+  saveStatesAuthorization: Record<string, SaveStateAuthorizationHeaders>;
   fetchingSaveStates: boolean;
   testedSaveState: Record<string, DatabaseStatus>;
 };
 
+const defaultStateAuthorizationHeaders: SaveStateAuthorizationHeaders = {
+  query: { W: false, R: false },
+  database: { W: false, R: false },
+  visualization: { W: false, R: false },
+  schema: { W: false, R: false },
+};
+
 // Define the initial state using that type
 export const initialState: SessionCacheI = {
   currentSaveState: undefined,
   saveStates: {},
+  saveStatesAuthorization: {},
   fetchingSaveStates: true, // default to true to prevent flashing of the UI
   testedSaveState: {},
 };
@@ -79,9 +90,13 @@ export const sessionSlice = createSlice({
       if (state.saveStates === undefined) state.saveStates = {};
       state.saveStates[action.payload.id] = action.payload;
       state.currentSaveState = action.payload.id;
+      if (!state.saveStatesAuthorization[action.payload.id]) {
+        state.saveStatesAuthorization[action.payload.id] = cloneDeep(defaultStateAuthorizationHeaders);
+      }
     },
     deleteSaveState: (state: SessionCacheI, action: PayloadAction<string>) => {
       delete state.saveStates[action.payload];
+      delete state.saveStatesAuthorization[action.payload];
       if (state.currentSaveState === action.payload) {
         if (Object.keys(state.saveStates).length > 0) state.currentSaveState = Object.keys(state.saveStates)[0];
         else state.currentSaveState = undefined;
@@ -90,6 +105,12 @@ export const sessionSlice = createSlice({
     testedSaveState: (state: SessionCacheI, action: PayloadAction<string>) => {
       state.testedSaveState = { ...state.testedSaveState, [action.payload]: DatabaseStatus.tested };
     },
+    setStateAuthorization: (state: SessionCacheI, action: PayloadAction<{ id: string; authorization: SaveStateAuthorizationHeaders }>) => {
+      state.saveStatesAuthorization[action.payload.id] = action.payload.authorization;
+    },
+    deleteAuthorization: (state: SessionCacheI, action: PayloadAction<string>) => {
+      delete state.saveStatesAuthorization[action.payload];
+    },
   },
 });
 
@@ -102,9 +123,14 @@ export const {
   testedSaveState,
   setFetchingSaveStates,
   updateSelectedSaveState,
+  setStateAuthorization,
+  deleteAuthorization,
 } = sessionSlice.actions;
 
 // Other code such as selectors can use the imported `RootState` type
 export const sessionCacheState = (state: RootState) => state.sessionCache;
+export const activeSaveState = (state: RootState): SaveStateI => state.sessionCache.saveStates?.[state.sessionCache.currentSaveState!];
+export const activeSaveStateAuthorization = (state: RootState): SaveStateAuthorizationHeaders =>
+  state.sessionCache.saveStatesAuthorization?.[state.sessionCache.currentSaveState!] || defaultStateAuthorizationHeaders;
 
 export default sessionSlice.reducer;
diff --git a/libs/shared/lib/inspector/InspectorPanel.tsx b/libs/shared/lib/inspector/InspectorPanel.tsx
index 84257549e272407a47c7a21b345685e3311ee656..a803dd5cc4ad3125eeea16f0b678eeee7b7cf8ce 100644
--- a/libs/shared/lib/inspector/InspectorPanel.tsx
+++ b/libs/shared/lib/inspector/InspectorPanel.tsx
@@ -20,7 +20,7 @@ export function InspectorPanel(props: { children?: React.ReactNode }) {
   const inspector = useMemo(() => {
     if (selection) return <SelectionConfig />;
     // if (!focus) return <ConnectionInspector />;
-    // if (activeVisualizationIndex !== -1) return <ConnectionInspector />;
+    // if (activeVisualizationIndex !== -1) return <ConnectionInspector  />;
     return <VisualizationSettings />;
     // if (focus.focusType === 'visualization') return <VisualizationConfigPanel />;
     // else if (focus.focusType === 'schema') return <SchemaDialog />;
diff --git a/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx b/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx
index 7bb306349e0948bd7e5044250ed590d0cfe9515d..c1087cd3fad253d5743201c3e0f697751e2bbede 100644
--- a/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx
+++ b/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx
@@ -1,4 +1,6 @@
 import {
+  useActiveSaveStateAuthorization,
+  useAppDispatch,
   useConfig,
   useQuerybuilderGraph,
   useQuerybuilderHash,
@@ -7,10 +9,8 @@ import {
   useSchemaInference,
   useSearchResultQB,
 } from '@graphpolaris/shared/lib/data-access/store';
-import { useCheckPermissionPolicy } from '@graphpolaris/shared/lib/data-access';
 import { setQuerybuilderGraphology, toQuerybuilderGraphology } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
 import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import { useDispatch } from 'react-redux';
 import ReactFlow, {
   Background,
   Connection,
@@ -52,6 +52,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
   const [toggleSettings, setToggleSettings] = useState<QueryBuilderToggleSettings>();
   const reactFlowWrapper = useRef<HTMLDivElement>(null);
   const queryBuilderSettings = useQuerybuilderSettings();
+  const saveStateAuthorization = useActiveSaveStateAuthorization();
 
   var nodeTypes = useMemo(
     () => ({
@@ -63,14 +64,13 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
   );
 
   var edgeTypes = useMemo(() => ({ connection: ConnectionLine, attribute_connection: ConnectionLine }), []);
-
   const schemaGraph = useSchemaGraph();
   const schemaInference = useSchemaInference();
   const schema = useMemo(() => toSchemaGraphology(schemaGraph), [schemaGraph]);
   const graph = useQuerybuilderGraph();
   const qbHash = useQuerybuilderHash();
   const config = useConfig();
-  const dispatch = useDispatch();
+  const dispatch = useAppDispatch();
   const isDraggingPill = useRef(false);
   const connectingNodeId = useRef<ConnectingNodeDataI | null>(null);
   const editLogicNode = useRef<SchemaReactflowLogicNode | undefined>(undefined);
@@ -82,28 +82,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
   const searchResults = useSearchResultQB();
   const reactFlowInstanceRef = useRef<ReactFlowInstance | null>(null);
   const [allowZoom, setAllowZoom] = useState(true);
-  const { canRead, canWrite } = useCheckPermissionPolicy();
-  const [readAllowed, setReadAllowed] = useState(false);
-  const [writeAllowed, setWriteAllowed] = useState(false);
-  const resource = 'query';
-
-  const checkReadPermission = useCallback(async () => {
-    const result = await canRead(resource);
-    setReadAllowed(result);
-  }, [canRead]);
-
-  const checkWritePermission = useCallback(async () => {
-    const result = await canWrite(resource);
-    setWriteAllowed(result);
-  }, [canWrite]);
-
-  useEffect(() => {
-    checkReadPermission();
-  }, [checkReadPermission]);
-
-  useEffect(() => {
-    checkWritePermission();
-  }, [checkWritePermission]);
 
   useEffect(() => {
     const searchResultKeys = new Set([...searchResults.nodes.map((node) => node.key), ...searchResults.edges.map((edge) => edge.key)]);
@@ -129,6 +107,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
    *  TODO: only works if the node is clicked and not moved (maybe use onSelectionChange)
    */
   function onNodesDelete(nodes: Node[]) {
+    if (!saveStateAuthorization.query.W) return;
     nodes.forEach((n) => {
       graphologyGraph.dropNode(n.id);
     });
@@ -242,12 +221,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
    * @param event Drag event.
    */
   const onDrop = (event: React.DragEvent<HTMLDivElement>): void => {
-    if (!writeAllowed) {
-      console.debug('User blocked from editing query due to being a viewer');
-      event.preventDefault();
-      return;
-    }
-
     event.preventDefault();
 
     // The dropped element should be a valid reactflow element
@@ -612,17 +585,19 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
             reactFlowInstanceRef.current = reactFlowInstance;
             onInit(reactFlowInstance);
           }}
-          onNodesChange={onNodesChange}
-          onDragOver={onDragOver}
-          onConnect={onConnect}
-          onConnectStart={onConnectStart}
-          onConnectEnd={onConnectEnd}
+          onNodesChange={saveStateAuthorization.query.W ? onNodesChange : () => {}}
+          onDragOver={saveStateAuthorization.query.W ? onDragOver : () => {}}
+          onConnect={saveStateAuthorization.query.W ? onConnect : () => {}}
+          onConnectStart={saveStateAuthorization.query.W ? onConnectStart : () => {}}
+          onConnectEnd={saveStateAuthorization.query.W ? onConnectEnd : () => {}}
           // onNodeMouseEnter={onNodeMouseEnter}
           // onNodeMouseLeave={onNodeMouseLeave}
-          onEdgeUpdate={onEdgeUpdate}
-          onEdgeUpdateStart={onEdgeUpdateStart}
-          onEdgeUpdateEnd={onEdgeUpdateEnd}
-          onDrop={onDrop}
+          onEdgeUpdate={saveStateAuthorization.query.W ? onEdgeUpdate : () => {}}
+          onEdgeUpdateStart={saveStateAuthorization.query.W ? onEdgeUpdateStart : () => {}}
+          onEdgeUpdateEnd={saveStateAuthorization.query.W ? onEdgeUpdateEnd : () => {}}
+          onDrop={saveStateAuthorization.query.W ? onDrop : () => {}}
+          // onContextMenu={onContextMenu}
+          // onNodeContextMenu={saveStateAuthorization.query.W ? onNodeContextMenu : () => {}}
           // onNodesDelete={onNodesDelete}
           // onNodesChange={onNodesChange}
           deleteKeyCode="Backspace"
diff --git a/libs/shared/lib/querybuilder/panel/QueryBuilderNav.tsx b/libs/shared/lib/querybuilder/panel/QueryBuilderNav.tsx
index fd592f0475798c15cc95ae9d72df061bfdb067a4..bd4149ef43afa7781459304ae570b42d444b308e 100644
--- a/libs/shared/lib/querybuilder/panel/QueryBuilderNav.tsx
+++ b/libs/shared/lib/querybuilder/panel/QueryBuilderNav.tsx
@@ -1,7 +1,7 @@
 import React, { useMemo } from 'react';
 import { ControlContainer, TooltipProvider, Tooltip, TooltipTrigger, Button, TooltipContent, Input } from '../../components';
 import { Popover, PopoverTrigger, PopoverContent } from '../../components/layout/Popover';
-import { useAppDispatch, useGraphQueryResult, useML, useQuerybuilderSettings } from '../../data-access';
+import { useActiveSaveStateAuthorization, useAppDispatch, useGraphQueryResult, useML, useQuerybuilderSettings } from '../../data-access';
 import { clearQB, setQuerybuilderSettings } from '../../data-access/store/querybuilderSlice';
 import { QueryMLDialog } from './querysidepanel/QueryMLDialog';
 import { QuerySettings } from './querysidepanel/QuerySettings';
@@ -23,6 +23,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
   const result = useGraphQueryResult();
   const resultSize = useMemo(() => (result ? result.edges.length : 0), [result]);
   const ml = useML();
+  const saveStateAuthorization = useActiveSaveStateAuthorization();
 
   /**
    * Clears all nodes in the graph.
@@ -61,8 +62,11 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                   variantType="secondary"
                   variant="ghost"
                   size="xs"
+                  disabled={!saveStateAuthorization.query.W}
                   iconComponent="icon-[ic--baseline-delete]"
-                  onClick={() => clearAllNodes()}
+                  onClick={() => {
+                    if (saveStateAuthorization.query.W) clearAllNodes();
+                  }}
                 />
               </TooltipTrigger>
               <TooltipContent>
@@ -105,6 +109,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                       variantType="secondary"
                       variant="ghost"
                       size="xs"
+                      disabled={!saveStateAuthorization.query.W}
                       iconComponent="icon-[ic--baseline-settings]"
                       className="query-settings"
                     />
@@ -138,6 +143,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                   variantType="secondary"
                   variant="ghost"
                   size="xs"
+                  disabled={!saveStateAuthorization.query.W}
                   iconComponent="icon-[ic--baseline-difference]"
                   onClick={props.onLogic}
                 />
@@ -154,6 +160,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                       variantType={mlEnabled ? 'primary' : 'secondary'}
                       variant="ghost"
                       size="xs"
+                      disabled={!saveStateAuthorization.query.W}
                       iconComponent="icon-[ic--baseline-lightbulb]"
                       className={mlEnabled ? 'border-primary-600' : ''}
                     />
@@ -231,6 +238,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                       variantType={qb.limit <= resultSize ? 'primary' : 'secondary'}
                       variant="ghost"
                       size="xs"
+                      disabled={!saveStateAuthorization.query.W}
                       iconComponent="icon-[ic--baseline-filter-alt]"
                       className={qb.limit <= resultSize ? 'border-primary-600' : ''}
                     />
diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/QueryEntityPill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/QueryEntityPill.tsx
index abdd1f8412325eea4c5e4481e5f34ecc4203f4c1..1485784c10f6f8cd6981714d70e2b20485ff9e11 100644
--- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/QueryEntityPill.tsx
+++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/QueryEntityPill.tsx
@@ -1,5 +1,4 @@
-import { useCheckPermissionPolicy, useQuerybuilderGraph, useQuerybuilderHash } from '@graphpolaris/shared/lib/data-access';
-import { setQuerybuilderGraphology, toQuerybuilderGraphology, attributeShownToggle } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
+import { useQuerybuilderAttributesShown, useQuerybuilderGraph, useQuerybuilderHash } from '@graphpolaris/shared/lib/data-access';
 import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
 import { Button } from '@graphpolaris/shared/lib/components/buttons';
 import { Icon } from '@graphpolaris/shared/lib/components/icon';
@@ -10,9 +9,13 @@ import { NodeAttribute, SchemaReactflowEntityNode, toHandleId } from '../../../m
 import { PillAttributes } from '../../pillattributes/PillAttributes';
 import { DropdownTrigger, DropdownContainer, DropdownItemContainer, DropdownItem } from '@graphpolaris/shared/lib/components/dropdowns';
 import { PopoverContext } from '@graphpolaris/shared/lib/components/layout/Popover';
-import { useDispatch } from 'react-redux';
-import { useQuerybuilderAttributesShown } from '@graphpolaris/shared/lib/data-access/store';
+import {
+  toQuerybuilderGraphology,
+  setQuerybuilderGraphology,
+  attributeShownToggle,
+} from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
 import { isEqual } from 'lodash-es';
+import { useDispatch } from 'react-redux';
 
 /**
  * Component to render an entity flow element
@@ -41,30 +44,9 @@ export const QueryEntityPill = React.memo((node: SchemaReactflowEntityNode) => {
   };
 
   const [openDropdown, setOpenDropdown] = useState(false);
-  const { canRead, canWrite } = useCheckPermissionPolicy();
-  const [readAllowed, setReadAllowed] = useState(false);
-  const [writeAllowed, setWriteAllowed] = useState(false);
   const [filter, setFilter] = useState<string>('');
   const resource = 'query';
 
-  const checkReadPermission = useCallback(async () => {
-    const result = await canRead(resource);
-    setReadAllowed(result);
-  }, [canRead]);
-
-  const checkWritePermission = useCallback(async () => {
-    const result = await canWrite(resource);
-    setWriteAllowed(result);
-  }, [canWrite]);
-
-  useEffect(() => {
-    checkReadPermission();
-  }, [checkReadPermission]);
-
-  useEffect(() => {
-    checkWritePermission();
-  }, [checkWritePermission]);
-
   const filteredAttributes = useMemo(() => {
     if (filter == null || filter.length == 0) return data.attributes;
 
@@ -88,7 +70,7 @@ export const QueryEntityPill = React.memo((node: SchemaReactflowEntityNode) => {
 
   const attributesBeingShown = useQuerybuilderAttributesShown();
   function isAttributeAdded(attribute: NodeAttribute): boolean {
-    return attributesBeingShown.some((x) => isEqual(x, attribute.handleData))
+    return attributesBeingShown.some((x) => isEqual(x, attribute.handleData));
   }
 
   return (
@@ -111,34 +93,45 @@ export const QueryEntityPill = React.memo((node: SchemaReactflowEntityNode) => {
 
               <DropdownItemContainer>
                 <PopoverContext.Consumer>
-                  {popover => <DropdownItem value={'Add/remove attribute'} onClick={(e) => {
-                    popover?.setOpen(false);
-                    setOpenDropdown(false);
-                  }} submenu={
-                    [
-                      <TextInput 
-                        type={'text'} 
-                        placeholder="Filter" 
-                        size="xs" 
-                        className="mb-1 min-w-40 rounded-sm" 
-                        value={filter}
-                        onClick={(e) => e.stopPropagation()}
-                        onChange={(v) => setFilter(v)} />,
-
-                      filteredAttributes.map(attr => 
-                        <DropdownItem 
-                          key={attr.handleData.attributeName + attr.handleData.nodeId}
-                          value={attr.handleData.attributeName ?? ''} 
-                          selected={isAttributeAdded(attr)}
-                          onClick={(_) => addAttribute(attr)}>
-                            <Icon component={attr?.handleData?.attributeDimension != null ? IconMap[attr.handleData.attributeDimension] : undefined} className="ms-2 float-end" size={16} />
-                        </DropdownItem>
-                      )
-                    ]
-                  } />}
+                  {(popover) => (
+                    <DropdownItem
+                      value={'Add/remove attribute'}
+                      onClick={(e) => {
+                        popover?.setOpen(false);
+                        setOpenDropdown(false);
+                      }}
+                      submenu={[
+                        <TextInput
+                          type={'text'}
+                          placeholder="Filter"
+                          size="xs"
+                          className="mb-1 min-w-40 rounded-sm"
+                          value={filter}
+                          onClick={(e) => e.stopPropagation()}
+                          onChange={(v) => setFilter(v)}
+                        />,
+
+                        filteredAttributes.map((attr) => (
+                          <DropdownItem
+                            key={attr.handleData.attributeName + attr.handleData.nodeId}
+                            value={attr.handleData.attributeName ?? ''}
+                            selected={isAttributeAdded(attr)}
+                            onClick={(_) => addAttribute(attr)}
+                          >
+                            <Icon
+                              component={
+                                attr?.handleData?.attributeDimension != null ? IconMap[attr.handleData.attributeDimension] : undefined
+                              }
+                              className="ms-2 float-end"
+                              size={16}
+                            />
+                          </DropdownItem>
+                        )),
+                      ]}
+                    />
+                  )}
                 </PopoverContext.Consumer>
                 <DropdownItem value="Remove" className="text-danger" onClick={(e) => removeNode()} />
-                
               </DropdownItemContainer>
             </DropdownContainer>
           </div>
@@ -151,7 +144,7 @@ export const QueryEntityPill = React.memo((node: SchemaReactflowEntityNode) => {
             className={'!rounded-none !bg-transparent !w-full !h-full !border-0 !right-0 !left-0'}
             type="target"
             style={{
-              pointerEvents: writeAllowed ? 'auto' : 'none',
+              pointerEvents: false ? 'auto' : 'none',
             }}
           ></Handle>
         }
@@ -163,17 +156,13 @@ export const QueryEntityPill = React.memo((node: SchemaReactflowEntityNode) => {
             className={'!rounded-none !bg-transparent !w-full !h-full !border-0 !right-0 !left-0'}
             type="source"
             style={{
-              pointerEvents: writeAllowed ? 'auto' : 'none',
+              pointerEvents: false ? 'auto' : 'none',
             }}
           ></Handle>
         }
       >
         {data?.attributes && (
-          <PillAttributes
-            node={node}
-            attributes={data.attributes}
-            attributeEdges={attributeEdges.map((edge) => edge?.attributes)}
-          />
+          <PillAttributes node={node} attributes={data.attributes} attributeEdges={attributeEdges.map((edge) => edge?.attributes)} />
         )}
       </EntityPill>
     </div>
diff --git a/libs/shared/lib/vis/components/VisualizationTabBar.tsx b/libs/shared/lib/vis/components/VisualizationTabBar.tsx
index 35a69a8adc86a533fb4e7d30ad10f2259e400763..9d229a1a142c1438efe5abcfbabec66ed79189d9 100644
--- a/libs/shared/lib/vis/components/VisualizationTabBar.tsx
+++ b/libs/shared/lib/vis/components/VisualizationTabBar.tsx
@@ -3,38 +3,16 @@ import { Button, DropdownContainer, DropdownItem, DropdownItemContainer, Dropdow
 import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../components/tooltip';
 import { ControlContainer } from '../../components/controls';
 import { Tabs, Tab } from '../../components/tabs';
-import { useAppDispatch, useVisualization, useCheckPermissionPolicy } from '../../data-access';
+import { useActiveSaveState, useActiveSaveStateAuthorization, useAppDispatch, useSessionCache, useVisualization } from '../../data-access';
 import { addVisualization, removeVisualization, reorderVisState, setActiveVisualization } from '../../data-access/store/visualizationSlice';
 import { Visualizations } from './VisualizationPanel';
 
 export default function VisualizationTabBar(props: { fullSize: () => void; exportImage: () => void }) {
   const { activeVisualizationIndex, openVisualizationArray } = useVisualization();
+  const saveStateAuthorization = useActiveSaveStateAuthorization();
   const [open, setOpen] = useState(false);
   const dispatch = useAppDispatch();
 
-  const { canRead, canWrite } = useCheckPermissionPolicy();
-  const [readAllowed, setReadAllowed] = useState(false);
-  const [writeAllowed, setWriteAllowed] = useState(false);
-  const resource = 'visualization';
-
-  const checkReadPermission = useCallback(async () => {
-    const result = await canRead(resource);
-    setReadAllowed(result);
-  }, [canRead]);
-
-  const checkWritePermission = useCallback(async () => {
-    const result = await canWrite(resource);
-    setWriteAllowed(result);
-  }, [canWrite]);
-
-  useEffect(() => {
-    checkReadPermission();
-  }, [checkReadPermission]);
-
-  useEffect(() => {
-    checkWritePermission();
-  }, [checkWritePermission]);
-
   const handleDragStart = (e: React.DragEvent<HTMLDivElement>, i: number) => {
     e.dataTransfer.setData('text/plain', i.toString());
   };
@@ -96,6 +74,7 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
               <Button
                 variantType="secondary"
                 variant="ghost"
+                disabled={!saveStateAuthorization.database.W}
                 rounded
                 size="2xs"
                 iconComponent="icon-[ic--baseline-close]"
@@ -113,16 +92,14 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
           <Tooltip>
             <TooltipTrigger>
               <DropdownContainer open={open} onOpenChange={setOpen}>
-                <DropdownTrigger disabled={!writeAllowed} onClick={() => setOpen((v) => !v)}>
+                <DropdownTrigger disabled={!saveStateAuthorization.database.W} onClick={() => setOpen((v) => !v)}>
                   <Button
                     as={'a'}
                     variantType="secondary"
                     variant="ghost"
                     size="xs"
-                    disabled={true}
                     iconComponent="icon-[ic--baseline-add]"
                     onClick={() => {}}
-                    className={`${writeAllowed ? 'cursor-pointer' : 'cursor-not-allowed'}`}
                   />
                 </DropdownTrigger>
                 <DropdownItemContainer>
diff --git a/libs/shared/lib/vis/views/Recommender.tsx b/libs/shared/lib/vis/views/Recommender.tsx
index 9417884364098bcdf6edea448cd496d105d1895a..93682640b2da431b9ee579b9ba0e75d104cfcf53 100644
--- a/libs/shared/lib/vis/views/Recommender.tsx
+++ b/libs/shared/lib/vis/views/Recommender.tsx
@@ -1,7 +1,7 @@
 import React, { useEffect, useState, useCallback } from 'react';
 import Info from '../../components/info';
 import { addVisualization } from '../../data-access/store/visualizationSlice';
-import { useAppDispatch, useCheckPermissionPolicy } from '../../data-access';
+import { useActiveSaveStateAuthorization, useAppDispatch } from '../../data-access';
 import { Visualizations } from '../components/VisualizationPanel';
 import { isVisualizationReleased } from 'config';
 
@@ -13,31 +13,9 @@ type VisualizationDescription = {
 
 export function Recommender() {
   const dispatch = useAppDispatch();
+  const saveStateAuthorization = useActiveSaveStateAuthorization();
   const [visualizationDescriptions, setVisualizationDescriptions] = useState<VisualizationDescription[]>([]);
 
-  const { canRead, canWrite } = useCheckPermissionPolicy();
-  const [readAllowed, setReadAllowed] = useState(false);
-  const [writeAllowed, setWriteAllowed] = useState(false);
-  const resource = 'visualization';
-
-  const checkReadPermission = useCallback(async () => {
-    const result = await canRead(resource);
-    setReadAllowed(result);
-  }, [canRead]);
-
-  const checkWritePermission = useCallback(async () => {
-    const result = await canWrite(resource);
-    setWriteAllowed(result);
-  }, [canWrite]);
-
-  useEffect(() => {
-    checkReadPermission();
-  }, [checkReadPermission]);
-
-  useEffect(() => {
-    checkWritePermission();
-  }, [checkWritePermission]);
-
   useEffect(() => {
     const loadVisualizations = async () => {
       const descriptions = await Promise.all(
@@ -64,10 +42,10 @@ export function Recommender() {
         {visualizationDescriptions.map(({ name, displayName, description }) => (
           <div
             key={name}
-            className={`p-4 border ${writeAllowed ? 'cursor-pointer hover:bg-secondary-100' : 'cursor-not-allowed opacity-50'}`}
+            className={`p-4 border ${saveStateAuthorization.visualization.W ? 'cursor-pointer hover:bg-secondary-100' : 'cursor-not-allowed opacity-50'}`}
             onClick={async (e) => {
               e.preventDefault();
-              if (!writeAllowed) {
+              if (!saveStateAuthorization.visualization.W) {
                 console.debug('User blocked from editing query due to being a viewer');
                 return;
               }