Package Exports
- multi-tenant-rbac
- multi-tenant-rbac/donsoft/src/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (multi-tenant-rbac) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Multi-Tenant RBAC v2.0
multi-tenant-rbac is a production-focused, multi-tenant authorization package for Node.js and TypeScript.
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.0
- Introduced adapter-based architecture so core logic is ORM-agnostic.
- Added
modelsconfig to override default model/table names. - Added
keysconfig to override default foreign-key names. - Added
rbac initand 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-rbacWho 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',
host: '127.0.0.1',
port: 3306,
database: 'rbac_db',
username: 'root',
password: 'password',
logging: false,
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,
},
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.
Most Important Methods
Bootstrap and structure
createTenantcreateRole/upsertRolecreatePermission/ensurePermissions
Permission mapping
syncRoleWithPermissionsgrantPermissionsToRolerevokePermissionsFromRole
User assignment
assignRoleToUserassignRolesToUserBulksyncUserRolesrevokeRoleFromUser
Authorization checks
authorizeuserHasPermissionlistEffectivePermissions
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-generatedWith 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=workspaceIdOther commands
rbac validate --manifest ./rbac-generated/rbac.init.json
rbac seed --out ./rbac.seed.json
rbac doctor --out ./rbac.doctor.jsonMigrations (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/migrationsIf 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/migrationsGenerated 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-appexamples/postgres-sequelize-appexamples/mongodb-app
Production Notes
- Prefer
sync: falsein 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:
- Open an issue with your proposal or bug report.
- Submit a PR with tests.
- 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