Lumio uses role-based access control (RBAC) to manage what each team member can do within an account.
How It Works
Each account has roles (e.g., Owner, Moderator, Viewer). Each role has a set of permissions. When a user performs an action, the system checks if their role grants the required permission.
Permission checks run on all four protocol surfaces with the same resource:action strings:
- REST —
require_permission() in route handlers
- GraphQL —
PermissionGuard on resolvers
- WebSocket — channel-subscribe gate in
crates/lo-websocket/src/gate.rs
- Frontend —
<Gate permission> and hasPerm() in client code
The WebSocket layer maps each account-scoped channel to a single :read permission (e.g. chat:\{account_id\} → chat:read, events:\{account_id\} → events:read). See WebSocket → RBAC gate for the full mapping. A user without the permission receives code: "UNAUTHORIZED" on subscribe.
Default Roles
Owner
Full account access. System role (cannot be deleted). Has all permissions.
Moderator
Chat moderation, event monitoring, and Spotify playback control.
| Category | Permissions |
|---|
| Events | events:read, events:create, events:userinfo |
| Overlays | overlays:read |
| Spotify | spotify:read, spotify:playback, spotify:queue, spotify:playlist, spotify:device |
| Chat | chat:read, chat:write, chat:userinfo, chat:delete, chat:ban, chat:timeout, chat:notes, chat:raid, chat:poll, chat:prediction, chat:refresh_user |
| Connections | connections:read |
| Uploads | uploads:read |
| Rewards | rewards:read |
| Automations | automations:read, automations:execute, automations:history |
| Sounds | sounds:read, sounds:play |
Viewer
Read-only access to events and overlays.
| Category | Permissions |
|---|
| Events | events:read, events:userinfo |
| Overlays | overlays:read |
| Sounds | sounds:read |
Custom roles can be created under Dashboard > Settings > Roles.
Permission Reference
Events
| Permission | Description |
|---|
events:read | View events, notifications, and event history |
events:create | Send test events and manage notifications |
events:delete | Delete events and clear event history |
events:userinfo | View user cards and profiles from event entries |
Overlays
| Permission | Description |
|---|
overlays:read | View overlay configurations |
overlays:create | Create new overlays |
overlays:edit | Edit existing overlays |
overlays:delete | Delete overlays |
overlays:manage-access | Manage overlay access control and bypass per-overlay restrictions |
Spotify
| Permission | Description |
|---|
spotify:read | View now playing state, queue, devices, playlists, and search tracks |
spotify:playback | Control playback: play, pause, skip, previous, seek, volume, shuffle, repeat |
spotify:queue | Add tracks to the playback queue |
spotify:playlist | Manage playlists: create, rename, delete, add/remove tracks, start playlist playback |
spotify:device | Transfer playback between Spotify devices |
spotify:worker | Start and stop the manual Spotify worker connect |
Chat
| Permission | Description |
|---|
chat:read | View chat messages, history, and emotes |
chat:write | Send chat messages |
chat:userinfo | View user profiles, follow status, and moderation log |
chat:delete | Delete chat messages |
chat:ban | Ban and unban users |
chat:timeout | Timeout users |
chat:notes | View and manage user notes |
chat:raid | Cancel active raids |
chat:poll | End active polls |
chat:prediction | End active predictions |
chat:refresh_user | Manually refresh a user's platform profile data |
Connections
| Permission | Description |
|---|
connections:read | View connected platforms and credentials |
connections:create | Connect new platforms |
connections:edit | Update connection credentials |
connections:delete | Disconnect platforms |
Settings
| Permission | Description |
|---|
settings:read | View account settings |
settings:edit | Modify account settings |
Automations
| Permission | Description |
|---|
automations:read | View automations and their configuration |
automations:create | Create new automations |
automations:edit | Edit automation metadata, nodes, edges |
automations:delete | Delete automations |
automations:execute | Manually trigger and start/stop automations |
automations:history | View execution history and debug logs |
Members
| Permission | Description |
|---|
members:read | View the members list and all invitations |
members:create | Create invites, search users for direct invites |
members:edit | Change member roles, create/edit/delete custom roles |
members:delete | Remove members from the account, revoke pending invites |
Uploads
| Permission | Description |
|---|
uploads:read | View uploaded files |
uploads:create | Upload new files |
uploads:delete | Delete uploaded files |
Rewards
| Permission | Description |
|---|
rewards:read | View channel point rewards |
rewards:create | Create new rewards |
rewards:edit | Edit existing rewards |
rewards:delete | Delete rewards |
Tokens
| Permission | Description |
|---|
tokens:read | View popout tokens and API keys |
tokens:create | Create popout tokens and API keys |
tokens:edit | Edit popout tokens and API keys |
tokens:delete | Revoke popout tokens and API keys |
Account
| Permission | Description |
|---|
account:read | View account settings and information |
account:edit | Edit account settings (name, etc.) |
account:delete | Dissolve (permanently delete) the account |
Plan
| Permission | Description |
|---|
plan:read | View account plan and billing information |
plan:edit | Change account plan, manage subscription |
Login Assignments (User-Level)
These permissions are user-level rather than account-level. Own assignments are always allowed for any authenticated user.
| Permission | Description |
|---|
login-assignments:read | View login assignments for the active account. Own assignments are always visible without this permission. |
login-assignments:create | Assign a login connection to an account on behalf of another user. Own assignments are always allowed without this permission. |
login-assignments:delete | Remove a login assignment for the active account on behalf of another user. Own assignments are always removable without this permission. |
Sessions (User-Level)
These permissions are user-level. Every authenticated user can manage their own sessions.
| Permission | Description |
|---|
sessions:read | View active browser sessions |
sessions:delete | Revoke active browser sessions |
Extension Developer (User/Team-Level)
Extension developer permissions gate access to the developer dashboard and extension management. They are exercised through developer team RBAC rather than account roles. See Team-Scoped Permissions for the team permission model.
| Permission | Description |
|---|
extension-dev:read | View extension developer dashboard and owned extensions |
extension-dev:create | Create new extensions |
extension-dev:edit | Edit owned extensions (metadata, code, assets) |
extension-dev:delete | Delete owned extensions |
extension-dev:publish | Submit extensions for review and publish approved versions |
extension-dev:analytics | View extension analytics (installs, usage, ratings) |
extension-dev:payouts | Manage extension revenue payouts |
Sounds
| Permission | Description |
|---|
sounds:read | View sounds |
sounds:create | Upload sounds |
sounds:edit | Edit sound metadata |
sounds:delete | Delete sounds |
sounds:play | Play sounds in browser sources |
Bot Modules
| Permission | Description |
|---|
bot-modules:read | View bot module configurations |
bot-modules:edit | Edit bot module configurations |
Copyright
| Permission | Description |
|---|
copyright:read | View safe/blocked songs, copyright check results |
copyright:edit | Add to safe/blocked lists, import playlists |
copyright:delete | Remove entries from safe/blocked lists |
OBS
| Permission | Description |
|---|
obs:read | View OBS integration configuration and status |
obs:edit | Edit OBS integration settings and remote control |
Admin-Scope Permissions
Admin-scope permissions are checked against a user's admin role (not their account role). They gate the Lumio admin panel — /admin. The dashboard entry gate is admin:access, which is automatically included in every admin role.
Note: Some permissions (marked below) share an identical string with an account-scope permission but are enforced in a different context (require_admin_permission vs require_permission). This mirrors the bot-connections:* precedent.
Admin: Core Access
| Permission | Description |
|---|
admin:access | Dashboard entry gate. Auto-injected into every admin role. |
Admin: Role Management
| Permission | Description |
|---|
admin-roles:read | View admin roles, their permissions, and member lists |
admin-roles:create | Create new admin roles |
admin-roles:edit | Edit role name, description, permissions, and user assignments |
admin-roles:delete | Delete admin roles (is_system roles are protected server-side) |
Admin: Privacy
| Permission | Description |
|---|
admin:privacy-erase | Erase persisted personal data on subject request (GDPR Art. 17). Currently powers DELETE /v1/admin/privacy/youtube/member/{id} to clear cached YouTube member-channel records across all accounts. Reserved for support tooling; assigned only to system_admin. |
Admin: Developer Verifications
| Permission | Description |
|---|
developer-verification:read | View developer applications and their details |
developer-verification:edit | Approve or reject developer applications |
Admin: Feature Flags
| Permission | Description |
|---|
features:read | View feature flags |
features:edit | Toggle feature flags |
Admin: Users & Accounts
| Permission | Description |
|---|
users:read | View users, login connections, and membership details |
users:edit | Edit user display name, email, overrides, and manage login connections |
users:delete | Delete users |
accounts:read | View account details, limits, features |
accounts:edit | Update account name, plan, limits, feature overrides, members, reconnect flags, and primary connections |
accounts:delete | Delete accounts |
Admin: Providers
| Permission | Description |
|---|
providers:read | View platform provider configurations |
providers:edit | Toggle providers and sub-flags |
Admin: Infrastructure
| Permission | Description |
|---|
system-keys:read | View system API keys |
system-keys:edit | Create and delete system API keys |
oauth-clients:read | View OAuth client registrations |
oauth-clients:edit | Create, edit, and delete OAuth clients |
Admin: Ideas Moderation
| Permission | Description |
|---|
ideas:moderate_read | View all ideas with moderation details (reports, flags, internal notes) |
ideas:moderate_status | Change idea status (approve, reject, mark as planned, close) |
ideas:moderate_edit | Edit any idea regardless of ownership |
ideas:moderate_delete | Delete any idea regardless of ownership |
ideas:moderate_comment | Edit or delete any comment on ideas regardless of ownership |
Admin: User Roles
| Permission | Description |
|---|
user-roles:read | View user roles and their permissions |
user-roles:create | Create new user roles |
user-roles:edit | Edit user role name, description, permissions, and assignments |
user-roles:delete | Delete user roles (is_system roles are protected server-side) |
Admin: Shared with Account Scope
The following permissions are declared in both admin scope and account scope. They share the same string value but are enforced by different guards:
| Permission | Category | Notes |
|---|
copyright:read | Copyright | Seeded on system_admin admin role |
copyright:edit | Copyright | Seeded on system_admin admin role |
copyright:delete | Copyright | Seeded on system_admin admin role |
obs:read | OBS | Seeded on system_admin admin role |
obs:edit | OBS | Seeded on system_admin admin role |
bot-modules:read | Bot Modules | Seeded on system_admin admin role |
bot-modules:edit | Bot Modules | Seeded on system_admin admin role |
User-Scoped Permissions
User-scoped permissions are global — they are not tied to a specific account. They control access to platform-wide features that exist outside the account context, such as the Ideas Hub. User-scoped permissions are assigned via user roles (user_roles / user_role_permissions), not account roles. Enforcement uses auth.require_user_permission() on the backend.
Ideas Hub
| Permission | Description |
|---|
ideas:read | Read ideas |
ideas:create | Create new ideas |
ideas:edit | Edit own ideas |
ideas:delete | Delete own ideas |
ideas:vote | Vote on ideas |
ideas:comment_read | Read comments on ideas |
ideas:comment_create | Create comments on ideas |
ideas:comment_edit | Edit own comments |
ideas:comment_delete | Delete own comments |
Default User Roles
Three system user roles are seeded by default:
Member
Assigned to all users automatically. Grants full Ideas Hub participation.
| 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 |
Restricted
Limited to read-only access.
| Category | Permissions |
|---|
| Ideas | ideas:read |
| Comments | ideas:comment_read |
Moderator
Full user permissions plus admin-level moderation capabilities. The five ideas:moderate_* permissions are admin-scoped — see Admin: Ideas Moderation above.
| 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 |
| Moderation (admin-scoped) | ideas:moderate_read, ideas:moderate_status, ideas:moderate_edit, ideas:moderate_delete, ideas:moderate_comment |
Team-Scoped Permissions (Developer Teams)
Team-scoped permissions control what each member can do within a developer team. They are separate from both account-scope and admin-scope permissions and are defined in crates/lo-auth/src/rbac.rs::team. Enforcement uses require_team_permission() in REST handlers and an equivalent helper in GraphQL resolvers. Permissions are cached in Redis per (team_id, user_id) pair.
Extension Development
| Permission | Description |
|---|
team-extensions:create | Create extensions within the team |
team-extensions:edit | Edit team extensions (metadata, code, assets) |
team-extensions:delete | Delete team extensions |
team-extensions:publish | Submit extensions for review and release |
team-extensions:analytics | View extension analytics (installs, usage, ratings) |
team-versions:create | Create new extension versions |
team-versions:edit | Edit extension versions |
Secrets
| Permission | Description |
|---|
team-secrets:read | Read team secrets (API keys, webhooks) |
team-secrets:edit | Edit team secrets |
Testers
| Permission | Description |
|---|
team-testers:manage | Manage extension testers |
Team Members
| Permission | Description |
|---|
team-members:read | Read team member list |
team-members:invite | Invite new team members |
team-members:edit | Edit team member roles |
team-members:remove | Remove team members |
Team Settings
| Permission | Description |
|---|
team-settings:read | Read team settings |
team-settings:edit | Edit team settings |
Payouts
| Permission | Description |
|---|
team-payouts:read | Read team payout information |
team-payouts:edit | Edit team payout configuration |
Default Team Roles
Three roles are seeded for every new developer team:
Owner (team-owner)
System role (cannot be deleted). All 18 team permissions.
Admin (team-admin)
Manage extensions and team members. All permissions except team-settings:edit, team-payouts:edit, and team-members:remove.
Member (team-member)
View and develop extensions. Permissions: team-extensions:create, team-extensions:edit, team-extensions:analytics, team-versions:create, team-members:read, team-secrets:read, team-settings:read.
Popout Tokens
Popout tokens inherit specific permissions when created. A popout token can only have permissions that the creating user's role grants. For example, a Moderator cannot create a popout token with settings:write.
Overlay Tokens
Overlay tokens (lm_overlay_*) have no RBAC permissions. They cannot access any REST or GraphQL endpoint. Their sole capability is subscribing to the overlay:{key} WebSocket channel where the token's bound overlay_id matches the resolved overlay key.
has_permission(_) always returns false
- Cannot broadcast to any channel
- Cannot subscribe to any channel other than the one matching their bound overlay
- Rate-limited at 600 requests/min (same tier as Popout tokens)
Shared Overlay Tokens
Shared overlay tokens (lm_share_*) provide temporary, time-limited access to a specific overlay. They are designed for sharing overlays with collaborators or backup streaming setups without granting permanent account access.
- Prefix:
lm_share_ (9 characters)
- Body: 32 random bytes, hex-encoded (64 characters)
- Total length: 73 characters
- Transport:
?token=lm_share_… query parameter or Authorization: Bearer lm_share_… header
- Rate-limited at 600 requests/min (same tier as Popout and Overlay tokens)
has_permission(_) always returns false
- Cannot access REST or GraphQL endpoints
- Can only subscribe to the
overlay:{key} WebSocket channel matching the token's bound overlay
- Server checks expiry every heartbeat tick (5s) — disconnects with
TOKEN_EXPIRED when elapsed
- Server checks DB revocation every 30 seconds — disconnects with
TOKEN_REVOKED if revoked
Token Types
| Type | Prefix | Length | Purpose |
|---|
| System Key | lm_sys_ | 71 | Internal service-to-service auth |
| User API Key | lm_usr_ | 71 | External API access |
| JWT | lm_ + eyJ... | variable | Session-based auth |
| Popout Token | lm_pop_ | 71 | Non-expiring overlay/popout access |
| Overlay Token | lm_overlay_ | 75 | Per-overlay browser source access |
| Shared Overlay Token | lm_share_ | 73 | Temporary shared overlay link |
Extension Permissions
Extension tokens (lm_ext_*) have no RBAC permissions (has_permission() always returns false). Instead, extensions declare required permissions in lumio.config.json and are granted only those capabilities at install time. The Lumio API validates each action call against the extension's declared permission set.
Available Extension Permissions
Extensions can request the following permissions:
| Permission | Description | Review level |
|---|
events:read | Read events from the Lumio event bus | Standard |
events:write | Emit custom events | Standard |
chat:read | Read chat messages | Standard |
chat:send | Send chat messages | Standard |
chat:delete | Delete chat messages | Enhanced |
chat:ban | Ban and unban users, timeout users | Enhanced |
obs:control | Control OBS scenes, sources, streaming, recording | Standard |
overlays:edit | Update overlay layer properties | Standard |
spotify:control | Control Spotify playback, queue, volume | Standard |
Enhanced review: Extensions requesting chat:ban or chat:delete receive additional scrutiny during the approval process. Reviewers verify that the extension implements appropriate safeguards (e.g., confirmation prompts, configurable thresholds, exempt role support) and that the moderation logic does not create excessive false positives. The chat:ban permission grants ban, unban, and timeout capabilities through a single declaration.
API Keys
User API keys inherit all permissions of the user's account role. Rate limits differ by auth type — see Authentication.