Adds role-based access control to Payload v3 by registering collections for features, actions, permissions and roles. Permissions are edited in the admin and enforced through access helpers such as getPermissionAccess. Supports multi-role users, super admins and data scopes (own, hierarchy, all). Requires a database migration after setup.
A plugin for Payload CMS to manage authentication and authorization
Installation
npm i @zealamic/payload-plugin-rbac10
Stars
1
Forks
0
Open Issues
3 months ago
Last Updated
27
Weekly Downloads
v1.3.0
npm Version
478.3 KB
Unpacked Size
0
Dependencies
Trends appear after 7 days of data. Daily snapshots have not started yet.
Trends appear after 7 days of data. Daily snapshots have not started yet.
Each point is npm's rolling 7-day download count.
Health Score
Composite score based on GitHub activity, stars, npm downloads, publish recency, dependency count, and package size.
Badge for your README
[](https://payloaddirectory.dev/plugins/1251146173-root)<a href="https://payloaddirectory.dev/plugins/1251146173-root"><img src="https://payloaddirectory.dev/badge/1251146173-root.svg" alt="Payload Directory"></a>README
Centralized role-based access control (RBAC) for Payload CMS v3 (payload ^3.84.1). Not compatible with Payload 2.x.

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 intargetCollectionsfor auto ownership field + create hook, then wiregetPermissionAccess. → COLLECTIONS — targetCollections · manual setup → UTILS
| 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.
featureCode + actionCode pair (helpers)own / hierarchy / all; use targetCollections for ownership field + hook, or add manually (UTILS)targetCollections — auto-add hidden ownership field + create hook on app collections (COLLECTIONS)config.admin.user (default users) for hierarchy + options.usersCollectionSlugroles-permissions on savesortOrder for permission features and actions on each collection list viewnpm install @zealamic/payload-plugin-rbac
# or: yarn add / pnpm add @zealamic/payload-plugin-rbac
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)
}),
],
});
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: trueon 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.
posts, users (code = featureCode in access helpers); use Reorder on the list view to set row order in the matrixcreate, read, update, delete (main / sub types); use Reorder to set main column and sub-action orderstatus: active)→ Full reference: 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").
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.

| Step | Action |
|---|---|
| Features | Permission Features → Reorder → drag → Save order |
| Actions | Permission Actions → Reorder → pick Main or Sub → drag → Save order |

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.
| 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";
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.
| Import | Contents |
|---|---|
@zealamic/payload-plugin-rbac | payloadPluginRBAC, utils, constants, TypeScript types |
@zealamic/payload-plugin-rbac/client | RolePermissionMatrixClient, PermissionActionReorderClient, PermissionFeatureReorderClient, createRolePermissionMatrixClient, and related types |

Reorder screenshots: Reorder overview above.
MIT
If this plugin helps your team ship safer access control with less friction, thank you for giving it a place in your stack.
multi tenant
Manage multiple tenants with scoped content and access from a single Payload admin panel
10090.4k/wk45.4kv3
rbac
Database-stored roles with a per-collection CRUD permission matrix enforced across all collections and globals
6327/wk15v3
rbac
Database-driven role-based access control with a per-collection permissions matrix in the Payload admin
530/wk0v4
abac
Attribute-based access control that compiles user attributes into Payload where clauses
520/wk181v3
Payload RBAC Plugin
Database-backed role and permission management with row-level conditions for Payload collections
500/wk6v3
rbac
Role-based access control with ready-made access functions and query filters for Payload auth collections
4418/wk142v1