Purpose
One simple role model reused across tools.
The standard
Roles are strings in
profiles.role:viewer,editor,admin. Add tool-specific roles only via ADR.viewer — read; editor — create/edit content; admin — manage users and settings.
Roles are enforced in the database (RLS, 08.03) and reflected in the UI. UI checks are for convenience; RLS is the security.
A
current_role()SQL helper (security definer) is the single place RLS reads the role.Admins cannot demote themselves; the last admin cannot be removed.
Role changes are logged in
role_changes(who,whom,from,to,at) for tools with more than a handful of users.
Anti-patterns
Checking role only in middleware; storing role in JWT claims without a revocation plan; per-user permission flags scattered across tables.
Owner: Matt · Last reviewed: 2026-09