diff --git a/ui/src/auth/OrgResolver.tsx b/ui/src/auth/OrgResolver.tsx index e60e3db..aa53373 100644 --- a/ui/src/auth/OrgResolver.tsx +++ b/ui/src/auth/OrgResolver.tsx @@ -66,12 +66,21 @@ export function OrgResolver({ children }: { children?: React.ReactNode }) { }; try { - const token = await (currentOrgId - ? getAccessToken(config.logtoResource, currentOrgId) - : getAccessToken(config.logtoResource) - ).catch(() => undefined); + // Always fetch the global (non-org) token — it contains global role scopes + // like platform:admin from the saas-vendor role. + const globalToken = await getAccessToken(config.logtoResource).catch(() => undefined); + const globalScopes = extractScopes(globalToken); - setScopes(new Set(extractScopes(token))); + // If an org is selected, also fetch org-scoped token for org-level scopes + // (tenant:manage, apps:manage, etc.) + let orgScopes: string[] = []; + if (currentOrgId) { + const orgToken = await getAccessToken(config.logtoResource, currentOrgId).catch(() => undefined); + orgScopes = extractScopes(orgToken); + } + + // Merge both scope sets + setScopes(new Set([...globalScopes, ...orgScopes])); } catch { setScopes(new Set()); }