Roles and Privileges

Enforcement model

Each protected route is guarded by an admin authorization hook bound to a specific privilege. The hook:

  1. Runs the shared JWT-auth preauth check — it validates the JWT and confirms the caller holds the requested privilege.
  2. Additionally requires request.user?.isAdmin to be truthy.
  3. If either check fails, throws EQ-USR-4030004 (INSUFFICIENT_PERMISSIONS, HTTP 403).

So every business endpoint requires both a valid privilege and an admin token. JWT validation itself (missing/expired/invalid token → 401 EQ-USR-401xxxx) is handled inside the shared JWT plugin; ErrorHandler.transformAuthErrors (an onSend hook) enriches those {errorCode}-only 401/403 bodies with a localized errorMessage.

Privilege strings (all auth:*)

Privilege Used by
auth:createPolicy POST /v1/policies
auth:viewPolicy GET /v1/policies, GET /v1/policies/action
auth:updatePolicy PATCH /v1/policies/:id
auth:deletePolicy DELETE /v1/policies/:id
auth:createRole POST /v1/role
auth:viewRole GET /v1/role
auth:updateRole PATCH /v1/role/:id
auth:deleteRole DELETE /v1/role/:id
auth:viewServicePrivileges GET /v1/service-privileges

These strings are evaluated against the caller’s own policies, and they also form part of the privilege catalog authored and served by this service (view/create/update/delete groups in masterseeddata). Privileges support a wildcard model — for example *:* grants everything, auth:view* grants all view operations, and auth:* grants all Auth Service operations.

Revision History
2026-08-05 | AN – Page created and uploaded the contents