diff --git a/ui/web/src/api/ws-client.ts b/ui/web/src/api/ws-client.ts
index e18d178f..11231ae9 100644
--- a/ui/web/src/api/ws-client.ts
+++ b/ui/web/src/api/ws-client.ts
@@ -282,7 +282,10 @@ export class WsClient {
pending.resolve(frame.payload);
} else {
const err = frame.error as ErrorShape;
- if (err.code === "UNAUTHORIZED" || err.code === "TENANT_ACCESS_REVOKED") {
+ // Only force logout on tenant revocation (session-level invalidation).
+ // UNAUTHORIZED from a method call means "insufficient permission for this action",
+ // not "session expired" — let the caller handle it via the rejected promise.
+ if (err.code === "TENANT_ACCESS_REVOKED") {
this.onAuthFailure?.();
}
pending.reject(
diff --git a/ui/web/src/components/layout/sidebar.tsx b/ui/web/src/components/layout/sidebar.tsx
index 33fb6d4c..7f47af26 100644
--- a/ui/web/src/components/layout/sidebar.tsx
+++ b/ui/web/src/components/layout/sidebar.tsx
@@ -101,7 +101,9 @@ export function Sidebar({ collapsed, onNavItemClick }: SidebarProps) {
-
+ {isOwner && (
+
+ )}
diff --git a/ui/web/src/routes.tsx b/ui/web/src/routes.tsx
index 26dd7b94..f10bb741 100644
--- a/ui/web/src/routes.tsx
+++ b/ui/web/src/routes.tsx
@@ -173,7 +173,7 @@ export function AppRoutes() {
} />
} />
} />
- } />
+ } />
} />
} />
} />