User Roles (Admin)
The User Roles section lets admins manage the third RBAC layer in Lumio — the set of user-scope permissions that controls what authenticated users can do across community features like the Ideas Hub. This is distinct from the account-scope roles (which control dashboard access within a streaming account) and from admin roles (which control access to the admin panel itself).
Where to Find It
Admin sidebar → User Roles (/user-roles). The whole role editor is a dialog on that one page — there are no /user-roles/\{id\} detail routes. Per-user role assignments and permission overrides are managed from the user detail page at /users/\{id\}. Per-account permission overrides are managed from the account detail page at /accounts/\{id\}.
Role List
The list at /user-roles shows all user roles.
Columns
| Column | Description |
|---|---|
| Name | Role display name, with the description underneath |
| Permissions | Count of permissions assigned to the role |
| Type | System, Default, or Custom badge |
| Actions | Edit (pencil) button, shown when the caller holds user-roles:edit |
The slug is not a list column — it appears in the edit dialog header under the role name.
Three roles are seeded as system roles (is_system = true) and cannot be deleted:
| Slug | Name | Permissions |
|---|---|---|
member | Member | The default role for every user: ideas:read, ideas:create, ideas:edit, ideas:delete, ideas:vote, ideas:comment_read, ideas:comment_create, ideas:comment_edit, ideas:comment_delete, ideas:comment_vote |
restricted | Restricted | Read-only: ideas:read, ideas:comment_read |
moderator | Moderator | Everything member has, plus ideas:moderate_status, ideas:moderate_edit, ideas:moderate_delete, ideas:moderate_comment |
member is also flagged is_default, so it carries the Default badge.
Role Editor
Clicking a row (or the pencil) opens the Edit Role dialog. There is no read-only detail view — the dialog is the only editor.
Creating a Custom Role
Click Create Role (requires user-roles:create). The dialog fields are:
| Field | Required | Notes |
|---|---|---|
| Name | Yes | Display name, max 100 characters |
| Slug | Yes | Auto-derived from the name; editable before saving |
| Description | No | Shown under the name in the role list |
| Permissions | No | Checkbox picker grouped by category (see Permission Categories) |
Save to create the role. It becomes immediately available in the per-user role picker.
Editing a Role
The dialog exposes name, description, the permission picker, a Members section, and a Danger Zone. Save Changes stays disabled until something actually changed, and it sends only the changed fields as a PATCH.
For system roles the dialog opens read-only: an italic note reads "System roles are read-only and cannot be modified", the name/description inputs are disabled, and Save is disabled. The pencil is still shown — the block happens inside the dialog, not on the row.
Deleting a Custom Role
The Danger Zone block at the bottom of the edit dialog carries Delete Role, gated on user-roles:delete and rendered only for non-system roles. A confirmation dialog follows. The server also refuses to delete a system role.
Members
The edit dialog contains a Members section: a list of the users holding this role (name, email, avatar), a debounced user search to add more, and a remove button per member. The list is served by GET /api/user-roles/\{id\}/members (backed by the userRoleMembers query, gated on user-roles:read); adding and removing members go through PUT / DELETE /api/user-roles/\{id\}/members/\{userId\} (backed by assignUserRole / removeUserRole, gated on user-roles:edit). The search field and the per-member remove button are gated on user-roles:edit. You can also assign and remove roles from the Roles card on the user detail page.
Permission Categories
The role editor's permission picker offers a fixed set of user-scope permissions, grouped into two categories:
| Category | Permissions |
|---|---|
| Ideas | ideas:read, ideas:create, ideas:edit, ideas:delete, ideas:vote |
| Comments | ideas:comment_read, ideas:comment_create, ideas:comment_edit, ideas:comment_delete, ideas:comment_vote |
Each category header has a tri-state checkbox that selects or clears the whole group.
The ideas:moderate_* permissions are not offered by the picker: idea moderation is an admin-scope capability and cannot be assigned to a custom user role. The seeded moderator system role carries them server-side (it is immutable and not edited through this picker).
Per-User Role Assignments
From the user detail page at /users/\{id\}, the Roles card lists the user's assignments. A user can hold several roles, and the card mixes both RBAC layers:
- User roles — badged
User, plusSystem/Defaultbadges where applicable. Removing one requiresuser-roles:edit. - Admin roles — badged
Admin. Removing one requiresadmin-roles:edit.
A single grouped dropdown at the bottom of the card assigns either kind, with User Roles and Admin Roles option groups.
Per-User Permission Overrides
From the user detail page, the Permission Overrides card shows all explicit overrides for that user.
Each override row shows:
- The permission string (e.g.,
ideas:create). - Status — a Granted or Denied badge.
- Reason — the free-text reason recorded with the override, or
—. - Set — when the override was created.
- A remove button.
To add an override, use the Add Override form under the table: pick a permission from the dropdown (populated from /api/assignable-permissions, which mirrors the backend permission registry so the picker cannot drift), choose grant or deny, optionally give a reason, and save.
Overrides layer on top of the role: granting a permission gives it to the user even if their role does not include it; denying removes it even if the role does include it. Per-user overrides are applied before account-level overrides in the resolution chain.
Per-user overrides are gated on user-roles:read (list) and user-roles:edit (set / remove) — not on the per-account override permissions (accounts:overrides-read / accounts:overrides-edit).
Per-Account Permission Overrides
From the account detail page at /accounts/\{id\}, the Permission Overrides card shows the user-scope overrides applied to all users who have that account as their active account when making requests.
The interface mirrors the per-user override UI: each row shows the permission, granted/denied state, and a remove button. Add new overrides via Add Override.
Account overrides are the last layer in the permission resolution chain — they can grant permissions that the user's role and individual overrides do not provide, or deny permissions that they would otherwise have.
Reading the overrides requires accounts:overrides-read; setting or removing them requires accounts:overrides-edit.
Effective Permissions View
The user detail page renders an Effective Permissions card directly (no button, no modal). It shows the fully-resolved permission set for that user — role permissions merged with user overrides and account overrides — grouped by permission category. Any permission that an override contributed is highlighted in amber with an Overridden badge, which makes it easy to see why a user has (or lacks) access.
Permissions
All actions in this section require admin:access (the dashboard-entry gate). In addition:
| Action | Permission |
|---|---|
| View role list, role members, user override lists, resolved permissions | user-roles:read |
| Create a role (UI button gate) | user-roles:create |
| Delete a role (UI button gate) | user-roles:delete |
| Create / update / delete roles, assign & unassign roles, set & remove per-user permission overrides (server-side gate) | user-roles:edit |
| Read per-account permission overrides | accounts:overrides-read |
| Set or remove per-account permission overrides | accounts:overrides-edit |
user-roles:create and user-roles:delete exist in the admin permission registry and gate the corresponding buttons in the admin UI, but the API enforces user-roles:edit on every user-role mutation, including create and delete. Grant user-roles:edit alongside them.
System admins implicitly have all permissions.
API
User-role endpoints are not under the /v1/admin prefix — they sit at the /v1 root and are guarded by admin permissions.
| UI Action | GraphQL | REST |
|---|---|---|
| List user roles | userRoles | GET /v1/user-roles |
| Create role | createUserRole(input: CreateUserRoleInput!) | POST /v1/user-roles |
| Update role | updateUserRole(id: UUID!, input: UpdateUserRoleInput!) | PATCH /v1/user-roles/\{id\} |
| Delete role | deleteUserRole(id: UUID!) | DELETE /v1/user-roles/\{id\} |
| List a user's role assignments | userRoleAssignments(userId: UUID!) | GET /v1/users/\{user_id\}/roles |
| Assign user role | assignUserRole(userId, roleId) | POST /v1/users/\{user_id\}/roles |
| Remove user role | removeUserRole(userId, roleId) | DELETE /v1/users/\{user_id\}/roles/\{role_id\} |
| List user overrides | userPermissionOverrides(userId) | GET /v1/users/\{user_id\}/permission-overrides |
| Set user override | setUserPermissionOverride(userId, permission, granted, reason) | PUT /v1/users/\{user_id\}/permission-overrides |
| Remove user override | removeUserPermissionOverride(userId, permission) | DELETE /v1/users/\{user_id\}/permission-overrides/\{permission\} |
| Resolved permissions | resolvedUserPermissions(userId) | GET /v1/users/\{user_id\}/permissions/resolved |
| List account overrides | adminAccountPermissionOverrides(accountId) | GET /v1/admin/accounts/\{id\}/permission-overrides |
| Set account override | adminSetAccountPermissionOverride(accountId, permission, granted, reason) | PUT /v1/admin/accounts/\{id\}/permission-overrides |
| Remove account override | adminRemoveAccountPermissionOverride(accountId, permission) | DELETE /v1/admin/accounts/\{id\}/permission-overrides/\{permission\} |
The admin app does not call these directly — it goes through its own Next.js proxy routes (/api/user-roles/*, /api/users/\{id\}/roles, /api/users/\{id\}/permission-overrides, /api/users/\{id\}/effective-permissions), which execute the GraphQL operations above.
Related
- User Roles developer guide — tables, resolution algorithm, AuthContext changes, cache
- RBAC & Permissions developer guide — account-scope and admin-scope RBAC layers
- Users — managing users and their account memberships
- Accounts — managing streaming accounts