The role column was a pre-RBAC artifact. All authorization now flows
through explicit group membership and permission grants:
- Everyone group: all users added on creation (no implicit membership)
- Admins group: grants surface.admin.access + all platform permissions
- JWT claims, login response, profile: role field removed
- OIDC: isIdPAdmin() maps IdP claims → Admins group (no role writes)
- Admin UI: role dropdown removed, admin managed through groups
- Middleware cache simplified to isActive only
28 files changed, -79 lines net. Zero magic roles.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provider-era cruft: token_budget_daily, token_budget_monthly, and
allowed_models columns removed from groups table (both dialects).
ResolveTokenBudget() and ResolveModelAllowlist() deleted. GroupPatch
trimmed to name/description/permissions. Admin groups UI simplified
to permissions-only. -283 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
surface.admin.access permission + seeded Admins system group replaces
hardcoded role == "admin" middleware checks. Admin bypass removed from
RequirePermission — all permissions flow through group membership.
Bootstrap, seed, OIDC, and admin handlers sync group membership on
role changes. Demotion/deletion safeguards use group member count.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>