diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py
index aacc9f525b..58f48412ca 100644
--- a/litellm/proxy/_types.py
+++ b/litellm/proxy/_types.py
@@ -432,6 +432,7 @@ class LiteLLMRoutes(enum.Enum):
"/model/new",
"/model/update",
"/model/delete",
+ "/user/daily/activity",
] # routes that manage their own allowed/disallowed logic
## Org Admin Routes ##
diff --git a/litellm/proxy/management_endpoints/internal_user_endpoints.py b/litellm/proxy/management_endpoints/internal_user_endpoints.py
index 5ecd210d3e..fe5c1bacab 100644
--- a/litellm/proxy/management_endpoints/internal_user_endpoints.py
+++ b/litellm/proxy/management_endpoints/internal_user_endpoints.py
@@ -1480,6 +1480,14 @@ async def get_user_daily_activity(
if api_key:
where_conditions["api_key"] = api_key
+ if (
+ user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN
+ and user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY
+ ):
+ where_conditions[
+ "user_id"
+ ] = user_api_key_dict.user_id # only allow access to own data
+
# Get total count for pagination
total_count = await prisma_client.db.litellm_dailyuserspend.count(
where=where_conditions
diff --git a/ui/litellm-dashboard/src/components/leftnav.tsx b/ui/litellm-dashboard/src/components/leftnav.tsx
index 8879ba6eef..f58f60db33 100644
--- a/ui/litellm-dashboard/src/components/leftnav.tsx
+++ b/ui/litellm-dashboard/src/components/leftnav.tsx
@@ -23,7 +23,7 @@ import {
LockOutlined,
ToolOutlined,
} from '@ant-design/icons';
-import { old_admin_roles, v2_admin_role_names, all_admin_roles, rolesAllowedToSeeUsage, rolesWithWriteAccess } from '../utils/roles';
+import { old_admin_roles, v2_admin_role_names, all_admin_roles, rolesAllowedToSeeUsage, rolesWithWriteAccess, internalUserRoles } from '../utils/roles';
const { Sider } = Layout;
@@ -44,55 +44,55 @@ interface MenuItem {
icon?: React.ReactNode;
}
-// Note: If a menu item does not have a role, it is visible to all roles.
-const menuItems: MenuItem[] = [
- { key: "1", page: "api-keys", label: "Virtual Keys", icon: },
- { key: "3", page: "llm-playground", label: "Test Key", icon: , roles: rolesWithWriteAccess },
- { key: "2", page: "models", label: "Models", icon: , roles: rolesWithWriteAccess },
- { key: "4", page: "usage", label: "Usage", icon: },
- { key: "6", page: "teams", label: "Teams", icon: },
- { key: "17", page: "organizations", label: "Organizations", icon: , roles: all_admin_roles },
- { key: "5", page: "users", label: "Internal Users", icon: , roles: all_admin_roles },
- { key: "14", page: "api_ref", label: "API Reference", icon: },
- { key: "16", page: "model-hub", label: "Model Hub", icon: },
- { key: "15", page: "logs", label: "Logs", icon: },
-
-
- {
- key: "experimental",
- page: "experimental",
- label: "Experimental",
- icon: ,
- roles: all_admin_roles,
- children: [
- { key: "9", page: "caching", label: "Caching", icon: , roles: all_admin_roles },
- { key: "10", page: "budgets", label: "Budgets", icon: , roles: all_admin_roles },
- { key: "11", page: "guardrails", label: "Guardrails", icon: , roles: all_admin_roles },
- { key: "12", page: "new_usage", label: "New Usage", icon: , roles: all_admin_roles },
- { key: "18", page: "mcp-tools", label: "MCP Tools", icon: , roles: all_admin_roles },
- ]
- },
- {
- key: "settings",
- page: "settings",
- label: "Settings",
- icon: ,
- roles: all_admin_roles,
- children: [
- { key: "11", page: "general-settings", label: "Router Settings", icon: , roles: all_admin_roles },
- { key: "12", page: "pass-through-settings", label: "Pass-Through", icon: , roles: all_admin_roles },
- { key: "8", page: "settings", label: "Logging & Alerts", icon: , roles: all_admin_roles },
- { key: "13", page: "admin-panel", label: "Admin Settings", icon: , roles: all_admin_roles },
- ]
- }
-];
const Sidebar: React.FC = ({
setPage,
userRole,
defaultSelectedKey,
}) => {
+ // Note: If a menu item does not have a role, it is visible to all roles.
+ const menuItems: MenuItem[] = [
+ { key: "1", page: "api-keys", label: "Virtual Keys", icon: },
+ { key: "3", page: "llm-playground", label: "Test Key", icon: , roles: rolesWithWriteAccess },
+ { key: "2", page: "models", label: "Models", icon: , roles: rolesWithWriteAccess },
+ { key: "4", page: "usage", label: "Usage", icon: },
+ { key: "6", page: "teams", label: "Teams", icon: },
+ { key: "17", page: "organizations", label: "Organizations", icon: , roles: all_admin_roles },
+ { key: "5", page: "users", label: "Internal Users", icon: , roles: all_admin_roles },
+ { key: "14", page: "api_ref", label: "API Reference", icon: },
+ { key: "16", page: "model-hub", label: "Model Hub", icon: },
+ { key: "15", page: "logs", label: "Logs", icon: },
+
+
+
+ {
+ key: "experimental",
+ page: "experimental",
+ label: "Experimental",
+ icon: ,
+ children: [
+ { key: "9", page: "caching", label: "Caching", icon: , roles: all_admin_roles },
+ { key: "10", page: "budgets", label: "Budgets", icon: , roles: all_admin_roles },
+ { key: "11", page: "guardrails", label: "Guardrails", icon: , roles: all_admin_roles },
+ { key: "12", page: "new_usage", label: "New Usage", icon: , roles: [...all_admin_roles, ...internalUserRoles] },
+ { key: "18", page: "mcp-tools", label: "MCP Tools", icon: , roles: all_admin_roles },
+ ]
+ },
+ {
+ key: "settings",
+ page: "settings",
+ label: "Settings",
+ icon: ,
+ roles: all_admin_roles,
+ children: [
+ { key: "11", page: "general-settings", label: "Router Settings", icon: , roles: all_admin_roles },
+ { key: "12", page: "pass-through-settings", label: "Pass-Through", icon: , roles: all_admin_roles },
+ { key: "8", page: "settings", label: "Logging & Alerts", icon: , roles: all_admin_roles },
+ { key: "13", page: "admin-panel", label: "Admin Settings", icon: , roles: all_admin_roles },
+ ]
+ }
+ ];
// Find the menu item that matches the default page, including in submenus
const findMenuItemKey = (page: string): string => {
// Check top-level items
@@ -111,9 +111,22 @@ const Sidebar: React.FC = ({
const selectedMenuKey = findMenuItemKey(defaultSelectedKey);
- const filteredMenuItems = menuItems.filter(item =>
- !item.roles || item.roles.includes(userRole)
- );
+ const filteredMenuItems = menuItems.filter(item => {
+ // Check if parent item has roles and user has access
+ const hasParentAccess = !item.roles || item.roles.includes(userRole);
+
+ if (!hasParentAccess) return false;
+
+ // Filter children if they exist
+ if (item.children) {
+ item.children = item.children.filter(child =>
+ !child.roles || child.roles.includes(userRole)
+ );
+ }
+
+ return true;
+ });
+
return (