New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@rbac/rbac

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rbac/rbac

Blazing Fast, Zero dependency, Hierarchical Role-Based Access Control for Node.js

latest
Source
npmnpm
Version
2.1.3
Version published
Weekly downloads
1K
45.31%
Maintainers
1
Weekly downloads
 
Created
Source

RBAC

Hierarchical Role-Based Access Control for Node.js

CircleCI npm version Tweet

  • ⏱ Lightweight
  • ⚡️Fastest RBAC (check benchmarks)
  • ️🍃low dependency

Features

  • Focused on operations
  • Scalable
  • Each role is given specific access rights for every operation
  • High granularity in assigning rights
  • Wildcard and regex support for operations
  • Optional database adapters (MongoDB, MySQL, PostgreSQL)
  • Express, NestJS and Fastify middlewares
  • Roles can be updated at runtime

Thanks

This project now uses Vite to generate the bundled output

Thanks to Karl Düüna (DeadAlready) and his awesome post on medium

Getting Started

Install

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.

Import

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');

Usage

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:

Setup RBAC config

step 01

PropertyTypeParamsDefaultDescription
loggerFunctionrole: String
operation: String
result: Boolean
colorsEnabled: Boolean (optional)
defaultLoggerFunction that logs operations to console
enableLoggerBooleantrueEnable or disable logger
colorsBooleanauto-detectEnable, disable, or auto-detect color support in logger output

Creating some roles

step 02

RBAC expects an object with roles as property names.

PropertyTypeExampleDescription
canArray['products:*']Array of strings, list of operations that user can do, it also supports glob patterns
whenFunction, 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
inheritsArray['user']Optional Array of strings, list of roles inherited by this role
IMPORTANT! "when" property can be a Callback function that receives params and done, an async function that returns a boolean or Promise, or a Promise that resolves in Truthy or Falsy values. Example:
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;
    } }]
  }
};

Check if user can do some operation

step 03

ParamTypeExampleDescription
FirstString'admin'Array of strings, list of operations that user can do
SecondString, Glob (Wildcard), Regex'products:find'Operation to validate
ThirdAny{registered: true}Optional Params that will flow to "when" callback Function

Update roles at runtime

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

Color Configuration

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:

  • If colors: true is set, colors are always enabled
  • If colors: false is set, colors are always disabled
  • If colors is not specified (default), the logger automatically detects:
    • FORCE_COLOR environment variable (enables colors)
    • NO_COLOR environment variable (disables colors)
    • TTY detection (process.stdout.isTTY)
    • CI environment detection (GitHub Actions, GitLab CI, CircleCI)

This ensures readable logs across all environments including CI systems, Windows terminals, and redirected output.

Database adapters

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:

  • MongoRoleAdapter
  • MySQLRoleAdapter
  • PostgresRoleAdapter

Adapters 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' }
})

Multi-tenant RBAC

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.

Middlewares

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.

Roadmap

  • Wildcard support
  • Regex support
  • Update roles in runtime
  • Async when callbacks
  • Database adapters (MongoDB, MySQL, PostgreSQL)
  • Middlewares for Express, NestJS and Fastify

v2.0.0

  • Rewritten in TypeScript
  • Internal refactor focused on readability and performance
  • Added support to update roles at runtime
  • Database adapters
  • Middlewares for Express, NestJS and Fastify

Benchmarks

Run npm run bench to execute the performance suite. The script runs two end-to-end scenarios:

  • Baseline comparison – compares @rbac/rbac with AccessControl, RBAC, Easy RBAC and Fast RBAC using the default dataset.
  • Large dataset comparison – stresses the libraries with hundreds of resources, deep inheritance chains and three 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.

More Information

Contributing

Contributions are welcome!

  • Build RBAC
  • Run npm install (or yarn install) to get RBAC's dependencies
  • Run npm run build to compile the library and produce the minified bundle using Vite
  • Development mode
  • Having all the dependencies installed run yarn 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.
  • Running the tests
  • Run yarn test
  • Scripts
  • npm run build - produces production version of your library under the lib folder and generates lib/@rbac/rbac.min.js via Vite
  • npm run dev - produces development version of your library and runs a watcher
  • npm test - well ... it runs the tests :)
  • npm run test:watch - same as above but in a watch mode
  • npm run bench - run the benchmark suite

License

This project is under MIT License [https://opensource.org/licenses/MIT]

Keywords

rbac

FAQs

Package last updated on 30 Jan 2026

Did you know?

Socket

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.

Install

Related posts