Roles and Permissions

Operyn uses roles to control what users can see and do in the console and, optionally, in backend APIs. This document defines the intended personas, permissions per resource, and a role–permission matrix. Implementation can start with organization-plugin roles and a small in-code permission map; a full RBAC plugin can be added later for database-driven permissions.

Personas and Roles

RoleWhoPurpose
ViewerNOC, stakeholders, auditorsSee incidents, analytics, and remediation status; no configuration or actions.
ResponderOn-call engineersEverything Viewer can do, plus: comment on incidents, assign, acknowledge, and approve or reject remediations.
OperatorSRE / platform teamEverything Responder can do, plus: create/update/delete correlation rules, manage the on-call team roster, and test notification channels.
AdminWorkspace ownersEverything Operator can do, plus: manage org members, configure notification channels and remediation policy, and full settings.
OwnerSingle per organizationSame as Admin, plus: transfer ownership and delete the organization.

Operyn natively supports these 5 roles via the better-auth organization plugin. Each role is assigned a specific set of permissions defined in lib/auth/permissions.ts (dashboard) and @operyn/shared-types (backend).

Permissions (Resource + Action)

Permissions are scoped by resource and action. This list aligns with the current Incident Engine, Remediation Engine, and Notification Service APIs.

Incidents

PermissionDescription
incidents:viewList incidents, get by id, subscribe to SSE stream.
incidents:createManually create an incident.
incidents:updateUpdate incident-linked metadata actions (for MVP: link/unlink runbooks).
incidents:update_statusAcknowledge, resolve, or change status.
incidents:commentAdd a comment.
incidents:assignAssign an incident to a team member.

Team (on-call roster)

PermissionDescription
team:viewList members and on-call state.
team:manageCreate or delete members, toggle on-call.
team:assign_incidentAssign an incident (can be merged with incidents:assign or kept separate).

Correlation rules

PermissionDescription
correlation_rules:viewList and view rules.
correlation_rules:createCreate a rule.
correlation_rules:updateUpdate a rule.
correlation_rules:deleteDelete a rule.

Remediation

PermissionDescription
remediation:viewList and view remediation requests.
remediation:approveApprove a remediation.
remediation:rejectReject a remediation (optionally with reason).

Policy (safety)

PermissionDescription
policy:viewView remediation policy.
policy:updateChange policy (e.g. auto-approve thresholds).

Notifications

PermissionDescription
notifications:viewView channel status and notification history.
notifications:configureConfigure channels.
notifications:testSend a test notification.

Organization (auth)

PermissionDescription
org:view_membersList org/team members.
org:inviteInvite users.
org:remove_memberRemove a member.
org:change_roleChange a member’s role.
org:manage_teamsCreate, rename, or delete teams within the org.
org:deleteDelete the organization (owner only).
org:transfer_ownershipTransfer ownership (owner only).

Settings

PermissionDescription
settings:viewView general, profile, and notification settings.
settings:editChange settings (profile can be restricted to “own profile only”).

Analytics

PermissionDescription
analytics:viewView the analytics page (read-only).

Role–Permission Matrix

PermissionViewerResponderOperatorAdminOwner
incidents:view, analytics:view
incidents:create, update, update_status, comment, assign
remediation:view, approve, reject
correlation_rules:*view onlyview onlyfullfullfull
team:view
team:manage, assign_incidentassign only
policy:view / policy:updateviewviewfullfull
notifications:view / configure / testviewfullfullfull
org:view_members, invite, remove, change_role, manage_teamsviewfullfull
settings:view / editviewown profilefullfullfull
org:delete, org:transfer_ownership
  • view = read-only for that resource.
  • assign only = can assign incidents but not add/remove team members.
  • full = create, update, delete (and test where applicable).

Implementation Architecture

Operyn uses a hybrid approach for RBAC:

  1. Native Better-Auth Roles: All 5 personas (owner, admin, operator, responder, viewer) are natively registered with the better-auth organization plugin.
  2. Synchronous Client Checks: Role verification and permission checking on the client are handled by a can() helper in permissions.ts.
  3. Backend Enforcement: Backend services (e.g. Incident Engine) use a RolesGuard that validates the user's role from a JWT and checks it against a per-service permission map.
  4. Shared Contract: A shared @operyn/shared-types library ensures that role-to-permission mappings are consistent between the dashboard and the backend.

See Authentication for how auth is integrated.