Role Levels
This page defines the shared Octopus role-level policy.
Role Matrix
Role |
Level |
|---|---|
Viewer |
1 |
User |
2 |
Operator |
3 |
Engineer |
4 |
Admin |
5 |
Default for setting-level gates:
If a setting does not define
level, it is treated aslevel: 0(visible to all logged-in users).
Semantics
A user can access a feature/setting only when:
userRoleLevel >= requiredLevel.Role names are canonicalized case-insensitively (
admin,ADMIN->Admin).Unknown/invalid role names are treated as
Viewer.Role level must be enforced server-side for security. Frontend checks are UX only.
Backend
Source-of-truth mapping lives in
auth/roles.py.Auth session/token claims include
roleandrole_level.GraphQL authorization enforces minimum levels for sensitive operations.
Dynamic endpoint-defined GraphQL mutations require
Operator(level 3) or higher.Preference access is user-scoped by default:
A user can read/update only their own preferences (
userIdmust match the authenticated user).If
userIdbelongs to someone else, the request is denied.Only
Admin(level 5) can read/update another user’s preferences.
Frontend
Frontend reads JWT claims (
role, optionalrole_level) for UI behavior.Frontend fetches canonical role levels from backend
/auth/rolesand uses them as the primary mapping.If backend role levels are temporarily unavailable, frontend uses cached values (or built-in defaults) as fallback.
Widget settings UI hides fields where
field.level > userRoleLevel.Frontend filtering is not a security boundary.
SDK
Widget config fields support optional
level?: number.JSON-schema style widget settings can define
levelper property.SDK schema conversion preserves
levelso host apps can enforce visibility.
Example
const schema = {
type: 'object',
properties: {
useLiveData: {
type: 'boolean',
title: 'Use Live Data',
level: 5,
default: true
},
title: {
type: 'string',
title: 'Title',
default: '' // implicit level 0
}
}
};