
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
@rbac/rbac
Advanced tools
Blazing Fast, Zero dependency, Hierarchical Role-Based Access Control for Node.js
This project now uses Vite to generate the bundled output
Thanks to Karl Düüna (DeadAlready) and his awesome post on medium
yarn add @rbac/rbac or npm install @rbac/rbac
This library is written in TypeScript and the published package ships with its declaration files for a great developer experience.
The package supports both ES modules and CommonJS.
ES Modules (recommended)
// Default import
import RBAC from '@rbac/rbac';
// Named imports
import { createTenantRBAC, MongoRoleAdapter } from '@rbac/rbac';
// Combined
import RBAC, { createTenantRBAC } from '@rbac/rbac';
CommonJS
// Default import
const RBAC = require('@rbac/rbac');
// Named imports
const { createTenantRBAC, MongoRoleAdapter } = require('@rbac/rbac');
// Combined
const RBAC = require('@rbac/rbac');
const { createTenantRBAC } = require('@rbac/rbac');
RBAC is a curried function thats initially takes an object with configurations, then returns another function that takes an object with roles, finally returns an object that holds "can" property that is a function.
You can use it in many ways, below is one of them:

| Property | Type | Params | Default | Description |
|---|---|---|---|---|
| logger | Function | role: String operation: String result: Boolean colorsEnabled: Boolean (optional) | defaultLogger | Function that logs operations to console |
| enableLogger | Boolean | true | Enable or disable logger | |
| colors | Boolean | auto-detect | Enable, disable, or auto-detect color support in logger output |

RBAC expects an object with roles as property names.
| Property | Type | Example | Description |
|---|---|---|---|
| can | Array | ['products:*'] | Array of strings, list of operations that user can do, it also supports glob patterns |
| when | Function, Async Function or Promise | (params , done ) => done (null , true ) | Optional Promise that should resolve in Truthy or Falsy, an async function that returns a boolean or Promise, or a Callback function that receives params and done as properties, should return done passing errors and result |
| inherits | Array | ['user'] | Optional Array of strings, list of roles inherited by this role |
import type { Roles } from '@rbac/rbac';
interface Params {
registered: boolean;
}
const roles: Roles<Params> = {
supervisor: {
can: [{ name: 'products:find', when: (params, done) => {
// done receives error as first argument and Truthy or Falsy value as second argument
done(null, params.registered);
}}]
},
admin: {
can: [{ name: 'products:*', when: async (params) => {
return params.registered;
} }]
}
};

| Param | Type | Example | Description |
|---|---|---|---|
| First | String | 'admin' | Array of strings, list of operations that user can do |
| Second | String, Glob (Wildcard), Regex | 'products:find' | Operation to validate |
| Third | Any | {registered: true} | Optional Params that will flow to "when" callback Function |
RBAC exposes two helpers to modify the role definition at runtime. addRole adds a new role and updateRoles merges new definitions with the existing ones.
import RBAC from '@rbac/rbac'
const base = RBAC({ enableLogger: false })({
user: { can: ['products:find'] }
})
base.addRole('editor', { can: ['products:update'], inherits: ['user'] })
await base.can('editor', 'products:update') // true
base.updateRoles({
user: { can: ['products:find', 'products:create'] }
})
await base.can('user', 'products:create') // true
The default logger automatically detects color support in your terminal and applies ANSI color codes accordingly. You can also manually control color output:
import RBAC from '@rbac/rbac'
// Auto-detect color support (default behavior)
const rbacAuto = RBAC({ enableLogger: true })({
user: { can: ['products:find'] }
})
// Force colors enabled
const rbacWithColors = RBAC({ enableLogger: true, colors: true })({
user: { can: ['products:find'] }
})
// Force colors disabled (plain text output)
const rbacNoColors = RBAC({ enableLogger: true, colors: false })({
user: { can: ['products:find'] }
})
Color Detection Logic:
colors: true is set, colors are always enabledcolors: false is set, colors are always disabledcolors is not specified (default), the logger automatically detects:
FORCE_COLOR environment variable (enables colors)NO_COLOR environment variable (disables colors)process.stdout.isTTY)This ensures readable logs across all environments including CI systems, Windows terminals, and redirected output.
RBAC exposes optional adapters to load and persist role definitions using
MongoDB, MySQL or PostgreSQL. Each adapter implements the RoleAdapter
interface with getRoles, addRole and updateRoles methods.
import RBAC from '@rbac/rbac'
import { MongoRoleAdapter } from '@rbac/rbac/adapters'
const adapter = new MongoRoleAdapter({
uri: 'mongodb://localhost:27017',
dbName: 'mydb',
collection: 'roles'
})
const roles = await adapter.getRoles()
const rbac = RBAC()(roles)
Adapters available:
MongoRoleAdapterMySQLRoleAdapterPostgresRoleAdapterAdapters also allow customizing the underlying table or collection column names
through a columns option when creating a new instance:
const adapter = new MySQLRoleAdapter({
table: 'roles',
columns: { name: 'rname', role: 'rdef', tenantId: 'tid' }
})
Adapters can optionally receive a tenantId parameter to store and retrieve
roles for different tenants. When omitted, the adapter falls back to a default
tenant so existing single-tenant usage keeps working. Use createTenantRBAC to
instantiate an RBAC instance scoped to a tenant:
import { MongoRoleAdapter, createTenantRBAC } from '@rbac/rbac';
const adapter = new MongoRoleAdapter({ uri: 'mongodb://localhost:27017', dbName: 'mydb', collection: 'roles' });
await adapter.addRole('user', { can: ['products:find'] }, 'tenant-a');
const rbacTenantA = await createTenantRBAC(adapter, 'tenant-a');
await rbacTenantA.can('user', 'products:find'); // true
Want more? Check out the examples folder.
RBAC also provides helper middlewares for Express, NestJS and Fastify. They make it easy to guard routes using existing role definitions.
import RBAC, { createExpressMiddleware } from '@rbac/rbac';
const rbac = RBAC({ enableLogger: false })({
user: { can: ['products:find'] }
});
const canFindProducts = createExpressMiddleware(rbac)('products:find');
app.get('/products', canFindProducts, handler);
For NestJS and Fastify you can use createNestMiddleware and createFastifyMiddleware
respectively with a similar API.
when callbacksRun npm run bench to execute the performance suite. The script runs two end-to-end scenarios:
@rbac/rbac with AccessControl, RBAC, Easy RBAC and Fast RBAC using the default dataset.when flavours (callback, async function and promise).For each scenario the suite generates detailed reports (JSON/CSV/HTML chart) under benchmarks/results/ and prints a human-readable summary (ops/sec, margins, standard deviation, samples, etc.).
$ npm run bench
RBAC Performance Comparison ops/sec: 6859456, 6193737, 4427263, ...
RBAC Performance Comparison - Large Dataset ops/sec: 3277352, 3396327, 3424089, ...
The baseline run shows @rbac/rbac leading all categories; the large dataset confirms the same behaviour when conditional checks and large permission sets come into play.
npm install (or yarn install) to get RBAC's dependenciesnpm run build to compile the library and produce the minified bundle using Viteyarn dev. This command will generate a non-minified version of your library and will run a watcher so you get the compilation on file change.yarn testnpm run build - produces production version of your library under the lib folder and generates lib/@rbac/rbac.min.js via Vitenpm run dev - produces development version of your library and runs a watchernpm test - well ... it runs the tests :)npm run test:watch - same as above but in a watch modenpm run bench - run the benchmark suiteThis project is under MIT License [https://opensource.org/licenses/MIT]
FAQs
Blazing Fast, Zero dependency, Hierarchical Role-Based Access Control for Node.js
The npm package @rbac/rbac receives a total of 882 weekly downloads. As such, @rbac/rbac popularity was classified as not popular.
We found that @rbac/rbac demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.