DEV Community

Nurul Islam Rimon
Nurul Islam Rimon

Posted on

Advanced Role Based Access Control (RBAC) in NestJS with a Custom Permission Guard

Implementing role-based access control in your NestJS app? Here's a clean and scalable solution using a custom PermissionGuard that:
✅ Supports @public() routes
✅ Checks permissions via @Permission() decorator
✅ Allows super_admin to bypass all checks
✅ Supports wildcard access like user:*
🔐 Example:

@Permission('user:create') @Post('create') createUser() { ... } 
Enter fullscreen mode Exit fullscreen mode

No more messy checks inside controllers! This guard handles everything neatly and efficiently at the route level.

🧱 The Permission Guard Code

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { IS_PUBLIC_KEY } from 'src/decorators/public.decorator'; import { PERMISSION_KEY } from 'src/decorators/Permission.decorator'; import { JwtPayload } from 'jsonwebtoken'; import { AdministratorRoleEnum } from '@prisma/client'; @Injectable() export class PermissionGuard implements CanActivate { constructor(private reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { const isPublic = this.reflector.get<boolean>( IS_PUBLIC_KEY, context.getHandler(), ); if (isPublic) return true; const requiredRules = this.reflector.get<string[]>( PERMISSION_KEY, context.getHandler(), ); if (!requiredRules || requiredRules.length === 0) return true; const request = context.switchToHttp().getRequest(); const user = request.user as JwtPayload; if (!user) return false; if (user.role === AdministratorRoleEnum.super_admin) return true; if (!Array.isArray(user.rules)) return false; return requiredRules.every((requiredRule) => { if (user.rules.includes(requiredRule)) return true; const resource = requiredRule.split(':')?.[0]; return user.rules.includes(`${resource}:*`); }); } } 
Enter fullscreen mode Exit fullscreen mode

Perfect for admin panels, dashboards, or any app with multiple user roles. 💼

👉 Clean, scalable, and production-ready RBAC in NestJS.

Click here to Read more

Regards,
N I Rimon

Top comments (1)

Collapse
 
nevodavid profile image
Nevo David

Neat. Kinda like having a security guard at every door who knows who can go in and who can't. Makes things way less messy.