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

@riao/authz-rbac

v1.0.0

Published

Riao RBAC

Downloads

8

Readme

@riao/authz-rbac

A Role-Based Access Control (RBAC) Authorization Driver for the Riao Identity & Access Management (IAM) system.

Overview

@riao/authz-rbac provides a complete RBAC implementation for the Riao IAM framework. RBAC is a widely-used authorization model that grants permissions to roles, which are then assigned to principals (users, applications, etc.).

RBAC Model

The RBAC authorization model follows this hierarchy:

Principal → Roles → Permissions

How it works:

  • Principals (users, applications, services) are assigned Roles
  • Roles are granted Permissions
  • A Permission is an action (e.g., "read", "write", "delete") optionally scoped to a resource (e.g., "documents", "users")
  • Authorization is granted when a principal has an active role that contains the required permission

Key Features

  • ✅ Full RBAC authorization model implementation
  • ✅ Action-only and resource-specific permissions
  • ✅ Role activation/deactivation
  • ✅ Multiple roles per principal support
  • ✅ Permission inheritance through roles
  • ✅ Comprehensive test coverage
  • ✅ TypeScript-first development

Installation

npm install @riao/authz-rbac @riao/iam @riao/dbal
npm install --save-dev @riao/cli
npx riao migration:create import-rbac-tables

database/main/migrations/123456789-import-rbac-tables.ts:

import { AuthzRbacMigrations } from '@riao/authz-rbac/authz-rbac-migrations';

export default AuthzRbacMigrations;

Quick Start

1. Setup

import { Database } from '@riao/dbal';
import { RbacAuthorization } from '@riao/authz-rbac';

const db = new Database(/* ... */);
const rbac = new RbacAuthorization({ db });

2. Grant Permissions

Grant a permission to a principal by creating a role and assigning it:

// Grant a single permission
await rbac.grantPermission({
	principalId,
	action: 'read',
	resource: 'documents'
});

// Grant an action-only permission (no specific resource)
await rbac.grantPermission({
	principalId,
	action: 'logout'
});

3. Check Authorization

Check if a principal is authorized for an action:

// Check with a specific resource
const result = await rbac.evaluate({
	principal,
	action: 'read',
	resource: 'documents'
});

// Check without a resource (for action-only permissions)
const logoutResult = await rbac.evaluate({ principal, action: 'logout' });

// Full evaluation with metadata
const writeResult = await rbac.evaluate({
	principal,
	action: 'write',
	resource: 'documents',
	metadata: { ip: '192.168.1.1' }
});

if (writeResult.allowed) {
	console.log('Access granted');
} else {
	console.log('Access denied:', writeResult.reason);
}

4. Revoke Permissions

Revoke a permission by deactivating the role assignment:

await rbac.revokePermission({
	principalId,
	action: 'read'
});

Core Concepts

Roles

Roles are containers for permissions. They allow grouping related permissions and assigning them to principals in bulk.

// Interfaces
interface RbacRole {
	id: DatabaseRecordId;
	name: string;
	description?: string;
	create_timestamp: Date;
	deactivate_timestamp?: Date;
}

Properties:

  • name: Unique identifier for the role (e.g., "editor", "viewer", "admin")
  • description: Optional description of the role's purpose
  • deactivate_timestamp: When set, indicates the role is inactive

Permissions

Permissions represent what actions can be performed, optionally on specific resources.

interface RbacPermission {
	id: DatabaseRecordId;
	action: string;
	resource: string | null;
	description?: string;
	create_timestamp: Date;
}

Properties:

  • action: The action being performed (e.g., "read", "write", "delete")
  • resource: Optional resource identifier (e.g., "documents", "users"). When null, the permission applies to the action regardless of resource

Examples:

  • action: "read", resource: "documents" → Can read documents
  • action: "logout", resource: null → Can logout (no resource)

Role-Permission Assignment

Links roles to permissions. A role can have multiple permissions, and a permission can be assigned to multiple roles.

interface RbacRolePermission {
	id: DatabaseRecordId;
	role_id: DatabaseRecordId;
	permission_id: DatabaseRecordId;
	create_timestamp: Date;
}

Principal-Role Assignment

Links principals to roles. A principal can have multiple roles, and roles can be deactivated without deletion.

interface RbacPrincipalRole {
	id: DatabaseRecordId;
	principal_id: DatabaseRecordId;
	role_id: DatabaseRecordId;
	create_timestamp: Date;
	deactivate_timestamp?: Date;
}

API Reference

RbacAuthorization Class

Constructor

new RbacAuthorization(options: RbacAuthorizationOptions)

Parameters:

  • options.db: Database instance for RBAC operations

Methods

evaluate(context: AuthorizationContext): Promise<AuthorizationResult>

Evaluates whether a principal is authorized for an action.

const result = await rbac.evaluate({
	principal: user,
	action: 'read',
	resource: 'documents'
});

// Returns: { allowed: true } or { allowed: false, reason: "..." }

Evaluation Logic:

  1. Fetch all active roles for the principal
  2. Get all permissions assigned to those roles
  3. Match permissions by action and resource
  4. Return authorization result

Permission Matching Rules:

  • If a resource is provided: Match permissions with the exact resource OR permissions with resource: null
  • If no resource is provided: Only match permissions with resource: null
evaluate(context: AuthorizationContext): Promise<AuthorizationResult>

Evaluates authorization for a principal, action, and optional resource.

const result = await rbac.evaluate({
	principal: user,
	action: 'delete',
	resource: 'users'
});

if (result.allowed) {
	// User can delete users
}
grantPermission(options: GrantPermissionOptions): Promise<void>

Grants a permission to a principal by assigning a role.

Options:

  • principalId: The principal ID to grant permission to
  • action: The action name (e.g., "read", "write", "delete")
  • resource (optional): The resource scope (e.g., "documents", "users")

Behavior:

  1. Creates or reuses a role for the action
  2. Creates or reuses a permission for the action and resource
  3. Links the permission to the role (if not already linked)
  4. Assigns the role to the principal (if not already assigned)
// Grant "read" permission on "documents"
await rbac.grantPermission({
	principalId,
	action: 'read',
	resource: 'documents'
});

// Grant action-only "logout" permission
await rbac.grantPermission({
	principalId,
	action: 'logout'
});

Note: Idempotent - safe to call multiple times

revokePermission(options: RevokePermissionOptions): Promise<void>

Revokes a permission from a principal by deactivating the role assignment.

Options:

  • principalId: The principal ID to revoke permission from
  • action: The action name to revoke
await rbac.revokePermission({
	principalId,
	action: 'delete'
});

Behavior:

  1. Finds the role for the action
  2. Sets deactivate_timestamp on the principal-role assignment
  3. Does not delete data; allows for audit trails and reactivation

Note: Deactivation is soft-delete; the principal can be re-granted the permission later

Repository Access

The RBAC instance exposes public repositories for direct database access:

const rbac = new RbacAuthorization({ db });

// Access repositories directly if needed
rbac.rolesRepo				// QueryRepository<RbacRole>
rbac.permissionsRepo		// QueryRepository<RbacPermission>
rbac.rolePermissionsRepo	// QueryRepository<RbacRolePermission>
rbac.principalRolesRepo		// QueryRepository<RbacPrincipalRole>

Usage Examples

Basic Permission Check

const rbac = new RbacAuthorization({ db });

// Check if user can read documents
const result = await rbac.evaluate({
	principal: user,
	action: 'read',
	resource: 'documents'
});

if (result.allowed) {
	// Allow access
}

Multiple Roles

A principal can have multiple roles with different permissions:

// Principal has both "editor" and "reviewer" roles
await rbac.grantPermission({
	principalId: userId,
	action: 'write',
	resource: 'articles'
});	// editor
await rbac.grantPermission({
	principalId: userId,
	action: 'approve'
});	// reviewer

// Has access through either role
const canWrite = await rbac.evaluate({
	principal: user,
	action: 'write',
	resource: 'articles'
});	// true
const canApprove = await rbac.evaluate({
	principal: user,
	action: 'approve'
});	// true

Hierarchical Permissions

Implement permission hierarchies using naming conventions:

// Define related permissions
await rbac.grantPermission({
	principalId: userId,
	action: 'read',
	resource: 'documents'
});
await rbac.grantPermission({
	principalId: userId,
	action: 'read',
	resource: 'reports'
});
await rbac.grantPermission({
	principalId: userId,
	action: 'read',
	resource: 'analytics'
});

// Check specific permissions
const canReadDocs = await rbac.evaluate({ principal: user, action: 'read', resource: 'documents' });	// true

Temporary Access

Grant access temporarily and revoke it later:

// Grant temporary access
await rbac.grantPermission({
	principalId: userId,
	action: 'export',
	resource: 'data'
});

// Later, revoke the access
await rbac.revokePermission({
	principalId: userId,
	action: 'export'
});

Action-Only Permissions

For permissions that don't require a resource scope:

// Grant action-only permission
await rbac.grantPermission({ principalId: userId, action: 'logout' });
await rbac.grantPermission({ principalId: userId, action: 'change-password' });
await rbac.grantPermission({ principalId: userId, action: 'view-profile' });

// Check authorization
const canLogout = await rbac.evaluate({
	principal: user,
	action: 'logout'
});	// true
const canLogoutWithResource = await rbac.evaluate({
	principal: user,
	action: 'logout',
	resource: 'resource'
});	// true (null resource matches any)

Contributing & Development

See contributing.md for information on how to develop or contribute to this project!

License

See LICENSE.md