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).
Role naming and ROLE_PREFIX
By default, the token role names expected by the backend are:
octopus-viewer, octopus-user, octopus-operator, octopus-engineer, octopus-admin
Set the ROLE_PREFIX environment variable at deployment time to scope roles to a specific telescope or site:
|
Expected role names |
|---|---|
(empty) |
|
|
|
|
|
|
|
ROLE_PREFIX applies to both MSAL (Entra app roles) and Keycloak realm roles. The same prefix must be set on the frontend (ROLE_PREFIX in config.js / the frontend chart) so Keycloak role derivation stays in sync.
Selection rules when a user holds multiple roles:
Roles belonging to a different prefix are ignored — only this deployment’s prefix is matched.
When a user holds multiple roles under the same prefix (e.g.
octopus-low-operatorandoctopus-low-admin), the highest level wins.
Per-provider overrides — if the role names in your IdP do not follow the octopus-<prefix>-<role> pattern, you can override individual names via MSENTRA_ROLE_* or KEYCLOAK_ROLE_* environment variables. Explicit overrides always take precedence over ROLE_PREFIX.
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
Engineer(level 4) or higher (role level > 3). Queries are available to any authenticated user.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
}
}
};