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

@indrajitsir/nest-auth-core

v0.2.0

Published

Persistence-agnostic authorization core for NestJS

Readme

@indrajitsir/nest-auth-core

Persistence-agnostic authorization core for NestJS.

It provides the @Authorization decorator, AuthorizationGuard, AuthorizationEngine, PolicyEvaluator, and the AuthorizationProvider contract — with zero SQL, ORM, or persistence code inside. Pair it with an adapter such as @indrajitsir/nest-auth-sql-adapter or write your own provider.

Features

  • Role-based authorization (RBAC)@Authorization("ADMIN", "HR_MANAGER") declares which roles may access an endpoint (v0.2.0).
  • Resource/action authorization@Authorization({ resource, action }) remains fully supported (v0.1.0).
  • Fail-safe DENY — missing user, missing roles, or a failed lookup never grant access.
  • Provider abstraction — the engine never touches the database; any AuthorizationProvider implementation plugs in.
  • TypeScript-first — strict types, Action enum, normalized AuthorizationResult.

Installation

npm install @indrajitsir/nest-auth-core

Peer dependencies (install them if your project does not already have them):

npm install @nestjs/common @nestjs/core reflect-metadata

Quickstart

The core package needs a provider to make decisions. The example below uses the SQL adapter (see its README) — the wiring is identical for any provider.

// app.module.ts
import { Module } from "@nestjs/common";

import { AuthorizationModule } from "@indrajitsir/nest-auth-core";
import {
  AuthorizationSqlModule,
  SqlAuthorizationProvider,
} from "@indrajitsir/nest-auth-sql-adapter";

@Module({
  imports: [
    AuthorizationModule.forRoot({
      provider: SqlAuthorizationProvider,
      global: true,
    }),

    AuthorizationSqlModule.forRoot({
      dataSource, // your TypeORM DataSource
      schema: {
        roleMapping: {
          table: "role_base_access_mapping",
          userIdColumn: "user_id",
          roleIdColumn: "role_id",
        },
        role: {
          table: "mapping_access",
          roleIdColumn: "role_id",
          roleNameColumn: "role_name",
        },
      },
    }),
  ],
})
export class AppModule {}
// employees.controller.ts
import { Controller, Get, UseGuards } from "@nestjs/common";

import { Authorization, AuthorizationGuard } from "@indrajitsir/nest-auth-core";

@Controller("employees")
@UseGuards(AuthorizationGuard)
export class EmployeesController {
  @Authorization("ADMIN", "HR_MANAGER") // ADMIN OR HR_MANAGER
  @Get()
  findAll() {
    return [];
  }
}

That is everything: the guard reads the decorator metadata, resolves the current user's roles through the provider, and throws a ForbiddenException when access is not allowed.

Role-based authorization (v0.2.0)

Declare the roles allowed to access an endpoint. Multiple roles mean OR:

@Authorization("ADMIN")                    // single role
@Authorization("ADMIN", "HR_MANAGER")      // ADMIN OR HR_MANAGER
@Authorization(["ADMIN", "HR_MANAGER"])    // array form

The engine resolves the authenticated user's role names (user_id → role_id → role_name) through the provider and allows the request when the sets intersect:

requiredRoles ∩ userRoles ≠ ∅   →  ALLOW
requiredRoles ∩ userRoles = ∅   →  DENY (403)

The decorator only writes metadata — it never queries the database itself.

Resource/action authorization (v0.1.0)

The original API is still supported and coexists with role-based policies:

@Authorization({ resource: "employee", action: "READ" })
@Authorization({ resource: "employee", action: Action.DELETE })

or split across two decorators:

@Resource("employee")
@Allow("DELETE")

The policy evaluator dispatches automatically based on the policy shape, so both forms can be used in the same application.

Module options

AuthorizationModule.forRoot({
  provider: SqlAuthorizationProvider, // a class, Provider, or FactoryProvider
  global: true,                       // register the guard/engine app-wide
})

| Option | Type | Description | | --- | --- | --- | | provider | Type<AuthorizationProvider> \| Provider \| FactoryProvider | The authorization mechanism used to make decisions. | | global | boolean | When true, the guard/engine are available in every feature module (recommended). |

The module exports AuthorizationGuard, AuthorizationEngine, PolicyEvaluator, AuthorizationMetadataResolver, and the AUTHORIZATION_PROVIDER token.

Writing a custom provider

Any class implementing AuthorizationProvider works:

import {
  AuthorizationContext,
  AuthorizationPolicy,
  AuthorizationProvider,
  AuthorizationResult,
} from "@indrajitsir/nest-auth-core";

export class MyProvider implements AuthorizationProvider {
  // Used for resource/action policies (@Authorization({ resource, action })).
  async authorize(
    context: AuthorizationContext,
    policy: AuthorizationPolicy,
  ): Promise<AuthorizationResult> {
    const roles = await this.resolveRoles(context);

    // ... your logic ...
    return { allowed: true };
  }

  // Used for role-based policies (@Authorization("ADMIN", ...)).
  // Optional — role-based policies DENY when the provider cannot resolve roles.
  async resolveRoles(context: AuthorizationContext): Promise<string[]> {
    const userId = context.user?.id;

    if (!userId) {
      return [];
    }

    return this.roleService.findNamesByUserId(userId);
  }
}

Register it:

AuthorizationModule.forRoot({
  provider: MyProvider,
  global: true,
})

How authorization flows

HTTP Request
    ↓
AuthorizationGuard          reads metadata, builds the AuthorizationContext
    ↓
AuthorizationEngine         orchestrates evaluation
    ↓
PolicyEvaluator             dispatches by policy shape
    ├── role policy         → provider.resolveRoles(context) → set intersection
    └── resource/action     → provider.authorize(context, policy)
    ↓
AuthorizationResult         { allowed, reason? }

Fail-safe behavior

The library never grants access because of a missing lookup or an exception:

| Situation | Result | | --- | --- | | No @Authorization metadata on the endpoint | Guard passes through (endpoint unprotected) | | No authenticated user | DENY — Unauthenticated user. | | User has no roles | DENY — User has no roles assigned. | | Endpoint declares no roles | DENY | | User role not required | DENY — Access denied. Required roles: ... | | Provider cannot resolve roles | DENY — Role lookup failed. | | Role lookup throws (DB failure) | DENY — Role lookup failed. |

Public API

| Export | Kind | Purpose | | --- | --- | --- | | Authorization | Decorator | @Authorization("ADMIN", ...) or @Authorization({ resource, action }) | | Allow / Resource | Decorators | Split resource/action metadata (v0.1.0) | | Action | Enum | CREATE, READ, UPDATE, DELETE, ACTIVATE, DEACTIVATE | | AuthorizationGuard | Guard | NestJS CanActivate that enforces the metadata | | AuthorizationEngine | Service | Orchestrates evaluation | | PolicyEvaluator | Service | Dispatches role vs resource/action policies | | AuthorizationProvider | Contract | authorize() + optional resolveRoles() | | AuthorizationContext | Type | User, request, headers, params, metadata | | AuthorizationPolicy | Type | RoleAuthorizationPolicy \| ResourceAuthorizationPolicy | | AuthorizationResult | Type | { allowed, reason?, metadata? } | | AuthorizationModule | Module | forRoot({ provider, global }) | | AUTHORIZATION_PROVIDER | Token | DI token for the configured provider |