diff --git a/internal/api/admin_users_handlers.go b/internal/api/admin_users_handlers.go index 501253d..dad523e 100644 --- a/internal/api/admin_users_handlers.go +++ b/internal/api/admin_users_handlers.go @@ -155,14 +155,17 @@ func (s *Server) handleUpdateUser(w http.ResponseWriter, r *http.Request) { // SEC-01: Privilege escalation check — caller must not assign a role // at or above their own level, and must not modify users at or above - // their own level. - if roleLevel(target.Role) >= roleLevel(sess.Role) { - writeError(w, http.StatusForbidden, "insufficient privileges to modify this user") - return - } - if req.Role != nil && roleLevel(*req.Role) >= roleLevel(sess.Role) { - writeError(w, http.StatusForbidden, "insufficient privileges to assign this role") - return + // their own level. Superadmin is the top level, so peer (same-level) + // checks would otherwise block superadmin-vs-superadmin management. + if sess.Role != userstore.RoleSuperAdmin { + if roleLevel(target.Role) >= roleLevel(sess.Role) { + writeError(w, http.StatusForbidden, "insufficient privileges to modify this user") + return + } + if req.Role != nil && roleLevel(*req.Role) >= roleLevel(sess.Role) { + writeError(w, http.StatusForbidden, "insufficient privileges to assign this role") + return + } } updated, err := s.users.Update(id, userstore.UpdateUserRequest{