Skip to content

Repository files navigation

@zealamic/payload-plugin-rbac

Centralized role-based access control (RBAC) for Payload CMS v3 (payload ^3.84.1). Not compatible with Payload 2.x.

Payload Auth RBAC Plugin

Permissions live in the database (feature + action), are assigned to roles, and enforced via reusable access helpers — editable in Admin without redeploying policy code.

Row-level access (dataScope): list collection slugs in targetCollections for auto ownership field + create hook, then wire getPermissionAccess. → COLLECTIONS — targetCollections · manual setup → UTILS


Documentation

Guide Read when you need to…
COLLECTIONS Plugin collections, users augmentation, dataScope, permission matrix, field/access overrides
UTILS getPermissionAccess, data-scope filters, field merge helpers
TRANSLATIONS Admin labels, select options, matrix UI strings (en, vi, …)
CUSTOM_COMPONENTS Custom matrix checkboxes / search input (client field component)

Typical flow: install → register plugin with targetCollections (COLLECTIONS) → run migration → seed RBAC data (COLLECTIONS) → add getPermissionAccess on app collections (UTILS) → translate Admin UI (TRANSLATIONS).

Demos in this repo: dev/rbac.ts, dev/collections/posts.ts, dev/components/role-permission-matrix-field.tsx.


Key features

  • Five RBAC collections — features, actions, permissions, roles, join table (details)
  • Multi-role users — union of enabled grants across assigned roles
  • Granular permissions — any featureCode + actionCode pair (helpers)
  • Data scopeown / hierarchy / all; use targetCollections for ownership field + hook, or add manually (UTILS)
  • targetCollections — auto-add hidden ownership field + create hook on app collections (COLLECTIONS)
  • Auth users slugconfig.admin.user (default users) for hierarchy + options.usersCollectionSlug
  • Permission matrix — role update UI; syncs draft → roles-permissions on save
  • Reorder drawers — drag-and-drop sortOrder for permission features and actions on each collection list view
  • Custom matrix UI — optional client field component + render props (CUSTOM_COMPONENTS)
  • TypeScript — typed plugin config and exported helpers/types from the main package
  • i18n — plugin translations merged into Payload i18n (guide)

Installation

npm install @zealamic/payload-plugin-rbac
# or: yarn add / pnpm add @zealamic/payload-plugin-rbac

Quick start

1. Register the plugin

import { payloadPluginRBAC } from "@zealamic/payload-plugin-rbac";

export default buildConfig({
  plugins: [
    payloadPluginRBAC({
      autoModifyUsersCollection: true, // roles, isSuperAdmin, parent, default user access
      targetCollections: ["posts"], // ownership field + create hook — see step 4
      // collections: { ... }   → https://github.com/zealamic/payload-plugin-rbac/blob/main/docs/COLLECTIONS.md
      // translations: { ... } → https://github.com/zealamic/payload-plugin-rbac/blob/main/docs/TRANSLATIONS.md
      // components: { rolePermissionMatrixField: "..." } → custom matrix Field (client module)
    }),
  ],
});

2. Migration

After adding the plugin (and especially after changing targetCollections), update your database schema:

yarn payload migrate:create
yarn payload migrate

(npm run / pnpm equivalents work too.)

Run migrate:create when new fields are added to collections (e.g. first time you list a slug in targetCollections). Then migrate to apply pending migrations.

Bootstrap a super admin: RBAC collections are restricted to super admins by default. Set isSuperAdmin: true on at least one user (via seed script, Local API, or direct database update) before you can manage roles, permissions, and the permission matrix in Admin.

COLLECTIONS — Bootstrap super admin

3. Seed RBAC data (Admin or script)

  1. permission-features — e.g. posts, users (code = featureCode in access helpers); use Reorder on the list view to set row order in the matrix
  2. permission-actions — e.g. create, read, update, delete (main / sub types); use Reorder to set main column and sub-action order
  3. permissions — one row per feature + action pair (status: active)
  4. roles — set dataScope; open update screen, configure matrix → Save
  5. users — assign roles; bootstrap isSuperAdmin via seed/API

→ Full reference: COLLECTIONS

4. Protect app collections

Recommended: list slugs in targetCollections — the plugin adds a hidden ownership field (createdBy text by default) and a create hook. You only wire getPermissionAccess on the collection. Full options → COLLECTIONS — targetCollections.

// payload.config.ts
payloadPluginRBAC({
  targetCollections: ["posts"],
});

// collections/posts.ts — no manual createdBy field or hook needed
import type { CollectionConfig } from "payload";
import { getPermissionAccess } from "@zealamic/payload-plugin-rbac";

export const Posts: CollectionConfig = {
  slug: "posts",
  access: {
    read: getPermissionAccess({ featureCode: "posts", actionCode: "read", options: {} }),
    create: getPermissionAccess({ featureCode: "posts", actionCode: "create" }),
    update: getPermissionAccess({ featureCode: "posts", actionCode: "update", mode: "modify" }),
    delete: getPermissionAccess({ featureCode: "posts", actionCode: "delete", mode: "modify" }),
  },
  fields: [{ name: "title", type: "text", required: true }],
};

After adding or changing targetCollections, run yarn payload migrate:create then yarn payload migrate.

Manual setup (visible fields, custom layout, or full control): add ownership field + create hook yourself → UTILS — Ownership field · relationship demo: dev/collections/posts.ts

Access order: no user → deny · super admin → allow · else → matrix permission (+ scope when options / mode: "modify").


Reorder overview (features & actions)

List views for permission-features and permission-actions include a Reorder drawer to set sortOrder (hidden on edit forms). Order drives the role permission matrix: features → rows, main actions → columns, sub actions → checkbox order under each row.

Sorted matrix

Step Action
Features Permission FeaturesReorder → drag → Save order
Actions Permission ActionsReorder → pick Main or Sub → drag → Save order

Reorder permission features Reorder permission actions

API: POST /api/permission-features/reorder · POST /api/permission-actions/reorder — body { "sortedItems": [{ "id": "…", "sortOrder": 0 }] }. Requires update access (super admin by default). Details → COLLECTIONS · labels → TRANSLATIONS — Reorder drawers.


Plugin options

Option Default Description
disabled false Skip runtime i18n/onInit wiring; collections still register in schema
autoModifyUsersCollection true Add RBAC fields, parent-path hooks, and default access on the auth users collection
targetCollections Auto ownership field + create hook on listed app collections → COLLECTIONS
translations Admin + matrix i18n → TRANSLATIONS
collections Per-collection fields / access / admin overrides → COLLECTIONS
components.rolePermissionMatrixField default client export Import-map path to a custom matrix Field component (client module)

Types import from the main entry:

import type {
  RBACTranslations,
  PayloadPluginRBACConfig,
  TargetCollection,
} from "@zealamic/payload-plugin-rbac";

Exported helpers (summary)

Full reference: UTILS

Function Purpose
getPermissionAccess Unified access: permission-only, read Where, or modify per-document
targetCollections (plugin config) Quick ownership field + hook — COLLECTIONS
getCreatedByRelationshipField / createCreatedByOnCreateBeforeChangeHook Manual ownership field + hook → UTILS
resolveUsersCollectionSlug Same admin.user → slug resolution as the plugin
getSuperAdminAccess Super admin only (default on RBAC collections)
getAuthenticatedOrSuperAdminAccess Owner or super admin
canAccessDocumentByDataScope Low-level single-document RBAC + scope check
resolveEffectiveDataScope / getHierarchyVisibleUserIds Scope resolution
getDataScopeReadWhere / mergeDataScopeWhere Query filters
getMergedFieldAffectingData / getArrayOfMergedFieldAffectingData Field merge for overrides

Constants: CONSTANTS.ROLE.DATA_SCOPE, CONSTANTS.PERMISSION_ACTION.TYPE, etc.


Package exports

Import Contents
@zealamic/payload-plugin-rbac payloadPluginRBAC, utils, constants, TypeScript types
@zealamic/payload-plugin-rbac/client RolePermissionMatrixClient, PermissionActionReorderClient, PermissionFeatureReorderClient, createRolePermissionMatrixClient, and related types

Images from demo

demo-1

Reorder screenshots: Reorder overview above.


License

MIT


If this plugin helps your team ship safer access control with less friction, thank you for giving it a place in your stack.

About

A plugin for Payload CMS to manage authentication and authorization

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages