Skip to content

Permissions (RBAC)

Neemias implements Role-Based Access Control (RBAC) with 8+ built-in roles and 17 granular permissions. Since v0.56.0, users can hold multiple roles simultaneously (AuthPrincipal.roles[]). Starting from version v0.26.0, dynamic roles can be created and managed via the API.

The @neemias/permissions package is the single source of truth — both the frontend (Vite) and the Worker (Wrangler) import definitions from this package.

Built-in roles

RolePermissionsTypical use
ADMINAll 17 permissionsSystem administrator
CHAMADORattendance, students.searchAttendance taking
RELATORIOSreports, students.searchReport viewing
CADASTROstudents.add, students.search, sessions.add, sessions.edit, nuclei.manage, classes.manageStudent registration and class management
RESPONSAVELstudents.search (own children)Parent viewing child attendance
VOLUNTARIOattendance, students.search, reports (assigned)Volunteer teacher
COORDENACAO_KIDSattendance, students.add, sessions.add, nuclei.manage, classes.manage (assigned)Kids ministry coordinator
ADMINISTRATIVO_KIDSstudents.add, students.search, sessions.add, attendance, reports (assigned)Kids ministry administrator

Multi-role (v0.56.0+): Users can hold multiple roles. AuthPrincipal.roles[] + primaryRole. See ADR-0022.

v0.55.1: VOLUNTEER removed, VOLUNTARIO_KIDSVOLUNTARIO.

Permission matrix

Attendance

PermissionADMINCHAMADORRELATORIOSCADASTRO
attendance

Students

PermissionADMINCHAMADORRELATORIOSCADASTRO
students.add
students.edit
students.delete
students.search

Users

PermissionADMINCHAMADORRELATORIOSCADASTRO
users.view
users.create
users.edit
users.deactivate
users.resetPassword

Settings

PermissionADMINCHAMADORRELATORIOSCADASTRO
settings

Import/Export

PermissionADMINCHAMADORRELATORIOSCADASTRO
import-export

Sessions (Class sessions)

PermissionADMINCHAMADORRELATORIOSCADASTRO
sessions.add
sessions.edit

Nuclei

PermissionADMINCHAMADORRELATORIOSCADASTRO
nuclei.manage

Classes

PermissionADMINCHAMADORRELATORIOSCADASTRO
classes.manage

Reports

PermissionADMINCHAMADORRELATORIOSCADASTRO
reports

Dynamic roles (v0.26.0+)

In addition to the 4 built-in roles, the system supports dynamic roles created via the API. Each dynamic role has:

  • name: unique identifier (e.g., "SUPERVISOR")
  • displayName: friendly name (e.g., "Regional Supervisor")
  • permissions: array of strings with the granted permissions
  • isSystem: false for custom roles (built-in roles have isSystem: true)

Dynamic roles are managed exclusively by users with users.create / users.edit permissions (ADMIN).

Role schema

ts
interface Role {
  name: string; // min 1, max 50
  displayName: string; // min 1, max 100
  permissions: string[];
  isSystem: boolean;
  createdAt: string; // ISO 8601 datetime
  updatedAt: string; // ISO 8601 datetime
}

How to add a new role

Add an entry in the PERMISSIONS map in packages/permissions/index.ts. The UserRole type is derived automatically — no separate type definition to maintain.

ts
export const PERMISSIONS = {
  // ... existing roles ...
  NEW_ROLE: ["attendance", "reports"],
} as const;

Source: packages/permissions/index.ts

Distributed under MIT License.