Skip to content

Roles & Permissions

This is the reference for the role-based access control system — available roles, permissions, and the helper functions used to enforce them in collections and fields.

RoleAccess Level
ADMINFull access to everything
EDITORContent management per permissions
import { USER_ROLES } from '@/roles/roles';
USER_ROLES.ADMIN; // 'admin'
USER_ROLES.EDITOR; // 'editor'

Always import role strings from USER_ROLES rather than using literals — a typo in a string fails silently at runtime, while a bad constant fails at compile time.

PermissionAllows
MANAGE_USERSCreate, update, delete users
CREATE_CONTENTCreate new documents
EDIT_OWN_CONTENTEdit own documents
EDIT_ALL_CONTENTEdit any document
DELETE_OWN_CONTENTDelete own documents
DELETE_ALL_CONTENTDelete any document
PUBLISH_CONTENTPublish documents
VIEW_AUDIT_LOGSView system logs
FunctionUse Case
isAuthenticatedAny logged-in user
isAdminOnly admins
canViewDocument('field')Users see own; editors/admins see all
canEditDocument('field')Users edit own; editors/admins edit all
canDeleteDocument('field')Users delete own; editors/admins delete all

Direct check:

import { hasPermission, PERMISSIONS } from '@/roles/permissions';
if (hasPermission(user.role, PERMISSIONS.EDIT_ALL_CONTENT)) {
// User can edit any document
}

hasPermission looks up the role in rolePermissions and returns whether the given permission constant is in its list.

In collection access control:

import { requirePermission } from '@/roles/permissions';
access: {
create: isAuthenticated,
read: canViewDocument('author'),
update: requirePermission(PERMISSIONS.EDIT_ALL_CONTENT),
}

Each access key accepts a function that receives the request context and returns a boolean. requirePermission returns one of these functions, ready to be used directly.

In field access control:

{
name: 'internalNotes',
type: 'textarea',
access: {
read: isAdmin,
create: isAdmin,
update: isAdmin,
},
}

Field-level access control works the same way as collection-level — the same functions apply. Fields hidden by access control are simply absent from the API response rather than returning an error.

  • Always check req.user exists before checking permissions
  • Use helper functions instead of inline checks
  • Test with different roles to verify access

See Managing Roles for adding new roles and admin lockout recovery.