A production-grade, highly optimized authorization framework for Node.js.
Combines the power of RBAC (Role-Based Access Control) and PBAC (Policy-Based Access Control)
into a unified engine with sub-microsecond evaluation latency.
- Performance by Default β Static role resolution (
O(1)) and indexed policy evaluation. - Framework Freedom β Core logic is fully isolated; adapters for Express, Fastify, and NestJS provide native integration without coupling.
- Audit First β Built-in lifecycle hooks (
onPreAuth/onPostAuth) for real-time security logging. - Developer Experience β Fluent policy builders, deep debug mode, and rich TypeScript inference.
| Package | Purpose | Version |
|---|---|---|
@vynelix/authz-core |
Core Engine β RBAC + PBAC logic | |
@vynelix/authz-express |
Middleware for Express.js | |
@vynelix/authz-fastify |
Plugin + Decorator for Fastify | |
@vynelix/authz-nestjs |
Module + Guard for NestJS | |
@vynelix/authz-node |
Vanilla Node.js wrapper |
# Core (required)
npm install @vynelix/authz-core
# Pick your framework adapter
npm install @vynelix/authz-express # Express
npm install @vynelix/authz-fastify # Fastify
npm install @vynelix/authz-nestjs # NestJS
npm install @vynelix/authz-node # Vanilla Node.js / Lambdaimport { createAuthz, policy } from '@vynelix/authz-core';
const authz = createAuthz({
// RBAC β hierarchical roles resolved at build time (O(1) lookups)
roles: {
guest: { can: ['post.read'] },
user: { inherits: ['guest'], can: ['post.create'] },
editor: { inherits: ['user'], can: ['post.update'] },
admin: { can: ['*'] },
},
// PBAC β fine-grained policies with function or JSON conditions
policies: [
policy('post.update')
.on('post')
.when((ctx) => ctx.user.id === ctx.resource?.ownerId) // only own posts
.build(),
policy('post.delete')
.deny()
.when((ctx) => ctx.resource?.locked === true) // hard lock even for admin
.build(),
],
});const allowed = await authz.can({
user: { id: 'usr_1', roles: ['editor'] },
action: 'post.update',
resource: { type: 'post', id: 'p42', ownerId: 'usr_1' },
});
// => true (editor role + user owns the post)import { authorize } from '@vynelix/authz-express';
app.put('/posts/:id',
authorize(authz, {
action: 'post.update',
resource: (req) => ({ type: 'post', id: req.params.id, ownerId: req.post.ownerId }),
}),
(req, res) => res.json({ ok: true })
);import { fastifyAuthz } from '@vynelix/authz-fastify';
fastify.register(fastifyAuthz, { engine: authz });
fastify.put('/posts/:id', {
preHandler: fastify.authorize({ action: 'post.update' })
}, handler);@Module({ imports: [AuthzModule.forRoot({ engine: authz })] })
export class AppModule {}
@Controller('posts')
@UseGuards(AuthzGuard)
export class PostController {
@Put(':id')
@Authorize({ action: 'post.update', resource: 'post' })
update() { ... }
}Every adapter supports debug: true which returns a full Decision object:
const decision = await authz.can(ctx, { debug: true });
// {
// allowed: false,
// reason: "PBAC Denied (Condition mismatch): ...",
// matchedPolicies: ["post.update"],
// failedConditions: ["Condition failed for policy: post.update"]
// }| Feature | Core | Express | Fastify | NestJS | Node |
|---|---|---|---|---|---|
| RBAC / PBAC Engine | β | β | β | β | β |
| Per-Request Caching | β | β | β | β | β |
| Audit Hooks (Pre/Post) | β | β | β | β | β |
| Debug Mode | β | β | β | β | β |
| Decorator Support | β | β | β | β | β |
| Global Middleware | β | β | β | β | β |
Evaluated on a standard Linux environment using
tinybench.
| Scenario | Ops/sec | Avg Latency |
|---|---|---|
| RBAC Only (100-level hierarchy) | ~438,000 | 2.27Β΅s |
| PBAC Only (100 indexed policies) | ~312,000 | 3.19Β΅s |
| Combined (No Cache) | ~237,000 | 4.20Β΅s |
| Combined + Cache Hit | ~716,000 | 1.39Β΅s |
See performance_report.md for full methodology.
| Feature | AuthZ | CASL | Oso |
|---|---|---|---|
| RBAC Hierarchy | β | β | |
| PBAC / Attributes | β | β | β |
| Deny Overrides Allow | β | β | β |
| Serializable JSON Policies | β | β | β |
| O(1) Role Lookup | β | β | β |
| Per-Request Cache | β | β | β |
| Framework Adapters | β |
| Guide | Description |
|---|---|
| Getting Started | Installation, first engine, first check |
| RBAC Guide | Roles, inheritance, wildcards |
| PBAC Guide | Policies, conditions, deny rules |
| Custom Engine | Implementing AuthorizationEngine |
Working runnable apps in authz-examples/:
- Express β RBAC + PBAC + audit hooks
- Fastify β Plugin + preHandler decorator
- NestJS β Module + Guard + @Authorize decorator
- Redis Cache Provider β Shared cache for multi-instance deployments
- AuthZ Dashboard β Visual policy editor and real-time audit viewer
- Rust/WASM Core β WASM-based engine for maximum performance
See CONTRIBUTING.md for how to set up the monorepo, run tests, and submit pull requests.
MIT Β© 2026 Engr., Isaiah Pius