payload-warding v0.1.10
A Collections / Globals Backed Payload RBAC Plugin
📖 Table of Contents
✨ Synopsis
- This plugin collects information from
collections,globalsand user provided extrasynopsesto build a collection of unifiedfeatureswhich looks like the following data structure:
{
feature: string, // the slug of a collection or a global
traits: string[], // a collection of field names or endpoint (which belongs to the collection or global) paths
verbs: string[], // create, read, update, delete
}[] // a collection of this of all the collections, globals and user provided synopses- Then the data is used to bring to us this:

⚙️ Usage
yarn add payload-warding
# or
npm i payload-warding// ...
import warding, { convention } from "payload-warding";
//...
export default buildConfig({
// ...
plugins: [
// ...
warding(
convention.opts({
root: { email: process.env.YOUR_ROOT_EMAIL!, password: process.env.YOUR_ROOT_PASSWORD! },
}),
),
// ...
],
// ...
});
// ...The convention.opts will merge your options with predefined default options, see convention.ts for details.
🎨 Options
root
/**
* The root user's email and password. If not provided, the root user will not
* be created.
*/
root?: {
email: string;
password: string;
};Please note that the user created in the create-first-user page will be automatically bound with a root role. So it's fine to skip the root user creation.
user
/**
* The user {@link Options}.
*/
user?: Options;
type Options = {
slug: string;
fields?: Field[]; // payload's Field type
title?: string;
tag?: SpecLabels;
};
type SpecLabels = {
plural?: Record<string, string> | string;
singular?: Record<string, string> | string;
};role
/**
* The role {@link Options}.
*/
role?: Options;label
/**
* All the labels for plugin introduced collections, fields and select options.
*/
label?: Label;ext
/**
* Extended features in the form of {@link Synopsis}s.
*/
ext?: Synopsis[];
type Synopsis = {
slug: string;
traits: [string, Label | undefined][];
label?: Label;
};
type Label = Record<string, string> | string;This paired with the check function in convention.ts can be used to build custom access control upon the user + role system provided by this plugin.
mod
/**
* Modifies the {@link Built} result after {@link Warding.build}.
*/
mod?: (w: Built) => Built;
type Built = {
collections: { user: CollectionConfig; role: CollectionConfig };
warden: Warden;
populate: Populate;
initialize: Initialize;
initializationExtra?: { user: any; role: any };
};See factory/spec.ts for details.
mute
/**
* Disable this plugin without uninstalling it.
*/
mute?: boolean;🔐 Authorization
📚 Collections
Authorizations of Collections are provided by adding access functions to all possible collections, fields...and so on. The said access functions will ask for a specific feature, traits, verbs combination to be present, or otherwise reject the operation it is assigned to.
For example, the expected feature, traits, verbs combination for which an access.create of a collection chad will ask looks like this:
{
feature: "chad",
trais: [],
verbs: ["create"]
}Any user who has a role with a feature chad and any trait (which, if is left empty in the role editing page, will have a default "_" trait assigned) of verb create can pass the check. As for the access.update of a field age of the collection chad, it looks like this:
{
feature: "chad",
trais: ["age"],
verbs: ["update"]
}🧭 Globals
Authorizations of Globals are provided the same way as Collections
🌠 Endpoints
Authorizations of Endpoints are provided by prepending check functions in the handler function arrays. The check functions basically do the same as those access functions mentioned above, in which case the verbs are determined by the endpoint's http method as such:
{
post: "create",
connect: "read",
options: "read",
head: "read",
get: "read",
put: "update",
patch: "update",
delete: "delete",
}✏️ Note
Note You can also choose to skip the authorization for specific
collections,globalsor some of theirfieldsorendpointsby assign thecustom.warding.shouldto false orcustom.warding.should.[verb]flags of correspondingverbsto false.Alternatively, if an access function is customly assigned in
collections,globalsorfields, the authorization will always be skipped but a plugin generated authorization functionreq.context.wardingwill be attached to the access function argument. So that plugin users can decide how and when to call the plugin generated authorization function.The
custom.warding.shouldandcustom.warding.should.[verb]flags assigned infieldsorendpointscan override those assigned in their correspondingcollectionsandglobals.The plugin generated authorization function
req.context.wardingwill always be attached to the handler function's argument whenendpointshave thecustom.warding.shouldflag orcustom.warding.should.[verb]flags assigned to false.