diff --git a/core/auth.py b/core/auth.py
index 3c7669de4..ed083b008 100644
--- a/core/auth.py
+++ b/core/auth.py
@@ -30,10 +30,12 @@ DEFAULT_PRIVILEGES = {
"can_manage_memory": True,
"max_messages_per_day": 0,
"allowed_models": [],
+ "allowed_models_restricted": False,
}
# Admins get everything
ADMIN_PRIVILEGES = {k: (True if isinstance(v, bool) else (0 if isinstance(v, int) else [])) for k, v in DEFAULT_PRIVILEGES.items()}
+ADMIN_PRIVILEGES["allowed_models_restricted"] = False
DEFAULT_AUTH_PATH = os.path.join(
Path(__file__).parent.parent, "data", "auth.json"
diff --git a/routes/chat_helpers.py b/routes/chat_helpers.py
index 0929b699d..c62d3452d 100644
--- a/routes/chat_helpers.py
+++ b/routes/chat_helpers.py
@@ -75,7 +75,7 @@ def _enforce_chat_privileges(request, sess) -> None:
allowlist, or HTTPException(429) if the user has hit their daily message
cap. No-op for unauthenticated callers or when auth_manager is absent
(single-user mode). Admins receive ADMIN_PRIVILEGES from get_privileges,
- which means empty allowed_models / zero cap → no-op for them.
+ which means unrestricted allowed_models / zero cap -> no-op for them.
"""
try:
user = get_current_user(request)
@@ -88,8 +88,10 @@ def _enforce_chat_privileges(request, sess) -> None:
return
privs = auth_manager.get_privileges(user) or {}
- allowed = privs.get("allowed_models") or []
- if allowed and sess.model and sess.model not in allowed:
+ allowed_raw = privs.get("allowed_models")
+ allowed = allowed_raw if isinstance(allowed_raw, list) else []
+ restricted = bool(privs.get("allowed_models_restricted")) or bool(allowed)
+ if restricted and sess.model and sess.model not in allowed:
raise HTTPException(403, f"Your account is not allowed to use model '{sess.model}'.")
cap = int(privs.get("max_messages_per_day") or 0)
diff --git a/static/js/admin.js b/static/js/admin.js
index 5019096af..5211bf62d 100644
--- a/static/js/admin.js
+++ b/static/js/admin.js
@@ -87,8 +87,11 @@ async function loadUsers() {
`;
// Allowed models — checkbox list
- const allowedSet = new Set((u.privileges && u.privileges.allowed_models) || []);
- const allEmpty = allowedSet.size === 0;
+ const allowedModels = Array.isArray(u.privileges && u.privileges.allowed_models)
+ ? u.privileges.allowed_models
+ : [];
+ const allowedSet = new Set(allowedModels);
+ const modelsRestricted = !!(u.privileges && u.privileges.allowed_models_restricted);
html += `