npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

multi-tenant-rbac

v2.1.1

Published

multi-tenant-rbac is a Node.js package that provides a role-based access control (RBAC) system for multi-tenant applications. It allows you to manage roles and permissions at the tenant level, so each tenant can have its own set of roles and permissions

Readme

Multi-Tenant RBAC v2.1

multi-tenant-rbac is a production-focused, multi-tenant authorization package for Node.js and TypeScript.

Why multi-tenant-rbac?

Most RBAC libraries:

  • are not tenant-aware
  • assume single-tenant apps
  • are tightly coupled to one ORM
  • don’t support schema remapping
  • break in enterprise SaaS environments

multi-tenant-rbac solves this by:

  • strict tenant isolation
  • adapter-based architecture
  • schema remapping support
  • CLI scaffolding
  • production-ready migration flow

Core Capabilities

It provides:

  • tenant-scoped roles and permissions
  • adapter-based data access (core is ORM-agnostic)
  • configurable model/table names and foreign-key names
  • easy startup for MySQL, PostgreSQL, and MongoDB setups

What changed in 2.x

  • Introduced adapter-based architecture so core logic is ORM-agnostic.
  • Added models config to override default model/table names.
  • Added keys config to override default foreign-key names.
  • Added rbac init and expanded CLI flows for scaffolding and validation.
  • Preserved backward compatibility with default names and legacy config paths.

For full details, see RELEASE_NOTES_v2.md.

Install

npm install multi-tenant-rbac

Who Provides DB Dependencies?

This package keeps core dependencies light.

  • You provide database/ORM dependencies in your parent app (for example sequelize, mysql2, mongoose) when needed.
  • Core RBAC logic does not hard-depend on Sequelize or Mongoose.

Quick Start (Sequelize)

import MultiTenantRBAC, { Database, rbacConfig } from 'multi-tenant-rbac';

const config: rbacConfig = {
  sequelizeConfig: {
    dialect: 'mysql', // mysql | postgres | mariadb | sqlite | mssql
    host: '127.0.0.1', // DB host
    port: 3306, // DB port
    database: 'rbac_db', // DB name
    username: 'root', // DB username
    password: 'password', // DB password
    logging: false, // set true (or logger fn) to see SQL queries
    sync: true, // dev only; prefer migrations in production
  },
};

await Database.init(config);
const rbac = new MultiTenantRBAC(config);

Advanced Existing-Schema Setup (Custom Tables + Keys)

Use this when your parent app already has different table names and FK fields.

import MultiTenantRBAC, { Database, rbacConfig } from 'multi-tenant-rbac';

const config: rbacConfig = {
  sequelizeConfig: {
    dialect: 'mysql',
    host: '127.0.0.1',
    port: 3306,
    database: 'rbac_db',
    username: 'root',
    password: 'password',
    logging: false,
    sync: true, // auto-sync Sequelize models
    syncOptions: {
      alter: true, // add missing columns safely
      force: false, // never drop/recreate tables
    },
  },
  models: {
    users: 'admins',
    tenants: 'workspaces',
    roles: 'acl_roles',
    permissions: 'acl_permissions',
    userRoles: 'admin_role_links',
    rolePermissions: 'role_permission_links',
  },
  keys: {
    userId: 'adminId',
    tenantId: 'workspaceId',
    roleId: 'roleRefId',
    permissionId: 'permissionRefId',
  },
};

await Database.init(config);
const rbac = new MultiTenantRBAC(config);

Defaults are used automatically for any models or keys values you do not provide.

Config Options (Easy Guide)

  • sequelizeConfig: SQL connection/runtime options used by the built-in Sequelize adapter.
  • models: overrides default RBAC table/collection names.
  • keys: overrides default relation key names (userId, tenantId, roleId, permissionId).
  • sync: useful for local development; in production prefer migrations.
  • syncOptions.alter: adds missing columns without dropping tables.
  • syncOptions.force: drops/recreates tables; keep false for safety.

Default names (used when you do not override):

  • models: users, tenants, roles, permissions, user_roles, role_permissions
  • keys: userId, tenantId, roleId, permissionId

Most Important Methods

Bootstrap and structure

  • createTenant
  • createRole / upsertRole
  • createPermission / ensurePermissions

Permission mapping

  • syncRoleWithPermissions
  • grantPermissionsToRole
  • revokePermissionsFromRole

User assignment

  • assignRoleToUser
  • assignRolesToUserBulk
  • syncUserRoles
  • revokeRoleFromUser

Authorization checks

  • authorize
  • userHasPermission
  • listEffectivePermissions

Example End-to-End Flow

const tenant = await rbac.createTenant({
  name: 'acme',
  description: 'Acme Inc',
  isActive: true,
});

await rbac.ensurePermissions([
  { title: 'invoice.read', description: 'Read invoices', isActive: true },
  { title: 'invoice.manage', description: 'Manage invoices', isActive: true },
]);

const role = await rbac.upsertRole(tenant.slug, {
  title: 'finance-admin',
  description: 'Finance admin role',
  isActive: true,
});

await rbac.syncRoleWithPermissions(tenant.id, {
  role: role.slug,
  permissions: ['invoice.read', 'invoice.manage'],
});

await rbac.assignRoleToUser({
  tenantId: tenant.id,
  userId: 'user-100',
  roleSlug: role.slug,
});

const allowed = await rbac.authorize(tenant.id, 'user-100', 'invoice.manage');
console.log({ allowed });

CLI

Generate RBAC models and migrations

rbac init --orm sequelize --out ./rbac-generated

With custom names

rbac init \
  --orm sequelize \
  --models users=admins,roles=acl_roles,permissions=acl_permissions,userRoles=admin_role_links,rolePermissions=role_permission_links \
  --keys userId=adminId,roleId=roleRefId,permissionId=permissionRefId,tenantId=workspaceId

Other commands

rbac validate --manifest ./rbac-generated/rbac.init.json
rbac seed --out ./rbac.seed.json
rbac doctor --out ./rbac.doctor.json

Migrations (Default)

Existing users can continue using default migrations when not configuring custom names:

node ./node_modules/.bin/sequelize-cli db:migrate \
  --url mysql://root:password@localhost:3306/lib_rbac \
  --migrations-path ./node_modules/multi-tenant-rbac/src/migrations

If you provide custom models and/or keys, generate custom migrations and run those instead of package defaults:

rbac init --orm sequelize --out ./rbac-generated --models ... --keys ...
node ./node_modules/.bin/sequelize-cli db:migrate --migrations-path ./rbac-generated/sequelize/migrations

Generated SQL migrations are idempotent:

  • create table only when missing
  • add missing configured columns when table already exists
  • never drop/recreate by default

Standalone Integration Examples

  • examples/mysql-sequelize-app
  • examples/postgres-sequelize-app
  • examples/mongodb-app

Production Notes

  • Prefer sync: false in production and use migrations.
  • Use structured logging for SQL if needed: logging: (sql) => logger.debug(sql).
  • Keep tenant boundaries strict in every service call.

Contributing

Contributions are welcome.

If you want to contribute, please:

  1. Open an issue with your proposal or bug report.
  2. Submit a PR with tests.
  3. For major changes, discuss design first.

Reach out here:

  • Issues: https://github.com/donchi4all/multi-tenant-rbac/issues
  • Repository: https://github.com/donchi4all/multi-tenant-rbac

If you want to collaborate directly on enterprise features, please open an issue titled: Collaboration Request.

License

MIT