The Problem

A NestJS service needs a reusable, type‑safe way to enforce role‑ and attribute‑based permissions without scattering access‑control logic throughout controllers and services.

What This Does

The package supplies a Nest‑style guard (src/access-control.guard.ts) and a set of decorators (src/decorators/*) that wrap the popular accesscontrol library. Roles are built with src/roles-builder.class.ts (mirrored in lib/roles-builder.class.js) and injected via src/decorators/inject-roles-builder.decorator.ts. The module entry point src/index.ts re‑exports the guard, decorators, and AccessControlModule (implemented in src/access-control.module.ts).

How It Is Wired

  1. Bootstrapping – Execution starts at example/src/main.ts, which creates a Nest application and loads AppModule.
  2. Module registration – example/src/app.module.ts imports AccessControlModule.forRoles(roles) (see src/access-control.module.ts). This registers the RolesBuilder instance and provides the ACGuard.
  3. Guard activation – When a controller method is annotated with @UseGuards(ACGuard), Nest instantiates src/access-control.guard.ts. Its canActivate method (the only public entry) calls getUserRoles.
  4. Role resolution – getUserRoles invokes getUser (extracts the request user) and then uses the injected RolesBuilder to fetch the role list. The call graph shows constructor → InjectRolesBuilder (2 occurrences) and canActivate → getUserRoles (1 occurrence).
  5. Permission check – ACGuard forwards the role list to the underlying AccessControl instance (from the accesscontrol dependency) to evaluate the requested action.
  6. Decorator flow – src/decorators/user-roles.decorators.ts provides @UserRoles() which also relies on InjectRolesBuilder. This creates a circular import: src/decorators/index.ts ↔ src/decorators/user-roles.decorators.ts ↔ src/index.ts (high‑severity import cycle).

The most‑connected module is src/index.ts (imports 6 others, imported by 1) and sits in the cycle, meaning any change to its exports risks ripple effects. The RolesBuilder class (src/roles-builder.class.ts and lib/roles-builder.class.js) is imported by 7 files but imports none, making it a stable hub.

How To Use It

# clone and install
git clone https://github.com/moses-y/nest-access-control
cd nest-access-control
yarn install          # lockfile present, Yarn is the default manager
  1. Define roles – Create src/app.roles.ts (example already provided) and export a RolesBuilder instance.
  2. Register the module – In your root module (example/src/app.module.ts), add
import { roles } from './app.roles';
@Module({
  imports: [AccessControlModule.forRoles(roles)],
  // …
})
export class AppModule {}
  1. Protect routes – Apply @UseGuards(ACGuard) or the @UserRoles() decorator to controller methods.
  2. Run the demo –
cd example
yarn start           # boots the Nest server (main.ts)

No additional configuration files or env variables are required by the library itself.

Real‑World Use

A video‑sharing service could define VIDEO_CREATE_OWN, VIDEO_READ_ANY, etc., in app.roles.ts. Controllers handling /videos would use @UserRoles() to automatically reject requests where the user’s role lacks the createOwn('video') permission, and the guard would filter response objects to only the allowed attributes.

Code Health & Issues

  • High – Duplicated code – Identical 6‑line blocks appear in lib/access-control.guard.js, src/access-control.guard.ts, lib/decorators/user-roles.decorators.js, src/decorators/user-roles.decorators.ts, etc. Consolidate shared helpers into a single source to eliminate redundancy.
  • High – Import cycle – src/decorators/index.ts, src/decorators/user-roles.decorators.ts, and src/index.ts form a circular dependency. Break the cycle by extracting shared types or inverting the import direction.
  • Medium – No automated dependency updates – Two manifest files (package.json, lib/package.json) lack a Dependabot or Renovate config. Add .github/dependabot.yml to keep libraries patched.

No critical security or test coverage gaps are reported; the repo includes a Travis CI config, a test suite (src/*.spec.ts), and a LICENSE file.

The Bottom Line

nest-access-control provides a clear Nest‑native wrapper around the accesscontrol library, with usable guards and decorators out of the box. The codebase suffers from duplicated implementations and a small import cycle that increase maintenance overhead. It is suitable for teams already using NestJS who need quick role‑based enforcement, provided they address the DRY and cycle issues before extensive customization.