fix: enforce strict RBAC - deny access for users without groups

Security fix: Previously users with no OAuth groups or unrecognized
groups would default to READ_ONLY access. Now:
- Empty groups = no permissions (denied access to all tools)
- Unrecognized groups = no permissions (denied access)

Also adds missing restart_service mapping to FULL_ADMIN permission.
This commit is contained in:
Ryan Malloy 2025-12-27 08:10:01 -07:00
parent 6159098963
commit 00857b1840

View File

@ -120,10 +120,11 @@ TOOL_PERMISSIONS: dict[str, PermissionLevel] = {
"configure_ntp": PermissionLevel.HOST_ADMIN,
"set_service_policy": PermissionLevel.HOST_ADMIN,
# ═══════════════════════════════════════════════════════════════════════
# FULL_ADMIN - Everything including guest OS and service control (10 tools)
# FULL_ADMIN - Everything including guest OS and service control (11 tools)
# ═══════════════════════════════════════════════════════════════════════
"start_service": PermissionLevel.FULL_ADMIN,
"stop_service": PermissionLevel.FULL_ADMIN,
"restart_service": PermissionLevel.FULL_ADMIN,
# Guest OS operations (requires guest credentials, high privilege)
"run_command_in_guest": PermissionLevel.FULL_ADMIN,
"list_guest_processes": PermissionLevel.FULL_ADMIN,
@ -191,9 +192,10 @@ def get_user_permissions(groups: list[str] | None) -> set[PermissionLevel]:
Returns:
Set of granted permission levels (union of all group permissions).
Returns empty set if no recognized groups (deny all access).
"""
if not groups:
return {PermissionLevel.READ_ONLY}
return set() # No groups = no permissions (enforces RBAC)
permissions: set[PermissionLevel] = set()
@ -201,10 +203,7 @@ def get_user_permissions(groups: list[str] | None) -> set[PermissionLevel]:
if group in GROUP_PERMISSIONS:
permissions.update(GROUP_PERMISSIONS[group])
# Default to read-only if no recognized groups
if not permissions:
permissions.add(PermissionLevel.READ_ONLY)
# No fallback - unrecognized groups get no permissions
return permissions