All Projects → nestjsx → Nest Access Control

nestjsx / Nest Access Control

Licence: mit
Role and Attribute based Access Control for Nestjs 🔐

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Nest Access Control

Laravel Authz
An authorization library that supports access control models like ACL, RBAC, ABAC in Laravel.
Stars: ✭ 136 (-75.8%)
Mutual labels:  permissions, access-control
advancedPermissionHandler
This Android library is for handle running time permissions in simplest way!
Stars: ✭ 13 (-97.69%)
Mutual labels:  helper, permissions
Think Authz
An authorization library that supports access control models like ACL, RBAC, ABAC in ThinkPHP 6.0 .
Stars: ✭ 155 (-72.42%)
Mutual labels:  permissions, access-control
Unix Permissions
Swiss Army knife for Unix permissions
Stars: ✭ 106 (-81.14%)
Mutual labels:  permissions, access-control
permissionUtil
Simple permission helper
Stars: ✭ 64 (-88.61%)
Mutual labels:  helper, permissions
Rbac.dev
A collection of good practices and tools for Kubernetes RBAC
Stars: ✭ 115 (-79.54%)
Mutual labels:  permissions, access-control
Nest Permissions Seed
A simple application demonstrating the basic usage of permissions with NestJS.
Stars: ✭ 121 (-78.47%)
Mutual labels:  nestjs, permissions
Ngx Permissions
Permission and roles based access control for your angular(angular 2,4,5,6,7,9+) applications(AOT, lazy modules compatible
Stars: ✭ 749 (+33.27%)
Mutual labels:  permissions, access-control
rbac-tool
Rapid7 | insightCloudSec | Kubernetes RBAC Power Toys - Visualize, Analyze, Generate & Query
Stars: ✭ 546 (-2.85%)
Mutual labels:  permissions, access-control
nova-permissions
Add Permissions based authorization for your Nova installation via User-based Roles and Permissions. Roles are defined in the database whereas Permissions are defined in the code base.
Stars: ✭ 115 (-79.54%)
Mutual labels:  permissions, access-control
Vakt
Attribute-based access control (ABAC) SDK for Python
Stars: ✭ 92 (-83.63%)
Mutual labels:  permissions, access-control
Casbin4D
An authorization library that supports access control models like ACL, RBAC, ABAC in Delphi
Stars: ✭ 25 (-95.55%)
Mutual labels:  permissions, access-control
Authr
🔑 a flexible and expressive approach to access-control
Stars: ✭ 33 (-94.13%)
Mutual labels:  permissions, access-control
Accesscontrol
Role and Attribute based Access Control for Node.js
Stars: ✭ 1,723 (+206.58%)
Mutual labels:  permissions, access-control
Pundit Elixir
Simple authorization helpers for Elixir stucts, like Ruby's Pundit
Stars: ✭ 17 (-96.98%)
Mutual labels:  permissions, access-control
Drf Access Policy
Declarative access policies/permissions modeled after AWS' IAM policies.
Stars: ✭ 200 (-64.41%)
Mutual labels:  permissions, access-control
Access Granted
Multi-role and whitelist based authorization gem for Rails (and not only Rails!)
Stars: ✭ 733 (+30.43%)
Mutual labels:  permissions, access-control
ngx-access
Add access control to your components using hierarchical configuration with logical expressions.
Stars: ✭ 21 (-96.26%)
Mutual labels:  permissions, access-control
nest-abstract
NestJs Abstraction Helper
Stars: ✭ 36 (-93.59%)
Mutual labels:  helper, nestjs
react-abac
Attribute Based Access Control for React
Stars: ✭ 54 (-90.39%)
Mutual labels:  permissions, access-control

Nest Access Control

MIT npm version Open Source Love PRs Welcome forthebadge forthebadge

A helper Module for building a Role and Attribute based Access Control System for Nestjs

TL;DR: recently our system was needing to have a Control Panel, so you can control, and monitor every thing from there, and it was really really needing some Role based access control system, so i build this module for that, it is really cool, so i'd love to share it with you, and any PR are more than welcome ❤️

This module is built on top of onury's accesscontrol library here is some of it's Core Features

  • Chainable, friendly API.
    e.g. ac.can(role).create(resource)
  • Role hierarchical inheritance.
  • Define grants at once (e.g. from database result) or one by one.
  • Grant/deny permissions by attributes defined by glob notation (with nested object support).
  • Ability to filter data (model) instance by allowed attributes.
  • Ability to control access on own or any resources.
  • Ability to lock underlying grants model.
  • No silent errors.
  • Fast. (Grants are stored in memory, no database queries.)
  • Brutally tested.
  • TypeScript support.

What does this Module Provide?

In this module you will have all these features out of the box, but in nest-ish way.

  • It's Decorator-based so most of the time you will use decorators in your routes.
  • Built-in ACGuard so you can go and use it directly.
  • Access to the underlying AccessControl object from everywhere.

Installation

  • NPM:
npm install nest-access-control --save
  • Yarn:
yarn add nest-access-control

Example

See example folder for the more code

We need to build a Video service so users can share there videos with others, but we need some admins to control these videos.

  1. Let's first define our roles:

    To build our roles we will need the RolesBuilder class, it extends the AccessControl class from accesscontrol package.

    // app.roles.ts
    
    export enum AppRoles {
      USER_CREATE_ANY_VIDEO = 'USER_CREATE_ANY_VIDEO',
      ADMIN_UPDATE_OWN_VIDEO = 'ADMIN_UPDATE_OWN_VIDEO',
    }
    
    export const roles: RolesBuilder = new RolesBuilder();
    
    roles
      .grant(AppRoles.USER_CREATE_ANY_VIDEO) // define new or modify existing role. also takes an array.
        .createOwn('video') // equivalent to .createOwn('video', ['*'])
        .deleteOwn('video')
        .readAny('video')
      .grant(AppRoles.ADMIN_UPDATE_OWN_VIDEO) // switch to another role without breaking the chain
        .extend(AppRoles.USER_CREATE_ANY_VIDEO) // inherit role capabilities. also takes an array
        .updateAny('video', ['title']) // explicitly defined attributes
        .deleteAny('video');
    

Pro Tip 👍 : Keep all roles organized and in one file e,g: app.roles.ts

  1. Next let's use AccessControlModule in our Root module:
    // app.module.ts

    import { roles } from './app.roles';

    @Module({
      imports: [AccessControlModule.forRoles(roles)],
      controllers: [AppController],
      providers: [AppService],
    })
    export class AppModule {}
    ```

    Until now everything is fine, but let's make our application,
    assume that we have list of video names, user can - _according to our roles_ - `create:own` new video, and `read:any` video, so let's build it:
    // app.controller.ts
    ...
    @Controller()
    export class AppController  {
      constructor(private readonly appService: AppService)  {}
      @UseGuards(AuthGuard, ACGuard)
      @UseRoles({
        resource:  'video',
        action:  'read',
        possession:  'any',
      })
      @Get()
      root(@UserRoles() userRoles: any)  {
        return this.appService.root(userRoles);
      }
    }

ForRootAsync

Injecting providers for a RoleBuilder Factory (using a database to populate roles)

@Injectable()
class RoleProvider {

  getRoles(): Promise<string[]> {
    return Promise.resolve([
      'my-custom-role',
    ]);
  }
}

@Module({
  providers: [RoleProvider],
  exports: [RoleProvider],
})
class RoleModule {

}

@Module({
  imports: [
    AccessControlModule.forRootAsync({
      imports: [TestModule],
      inject: [RoleService],
      useFactory: async (roleService: RoleService): Promise<RolesBuilder> => {
        return new RolesBuilder(await roleService.getRoles());
      },
    }),
  ],
})
export class AccessModule {}

Notice the use of imports in the forRootAsync method. This will allow you to inject exported providers from the imported module. Injecting providers, provided in the same module as the imported AccessControlModule will result in the provider not being found. This is because the module is created before the providers.

So let's discuss what's going on!

First we introduced two new decorators, actually they are three, but let's see what they can do:

  • @UseRoles({ ... }): this the most used decorator, it define what roles should user have to access this route. It may take one or more role, but keep in mind that all roles must be satisfied. The structure of the role is really simple, for example, here we define what resources we have, and the ACGuard* - Damn, it's a good name for a guard 😂 - will check for the user roles, then if the user roles have the permissions to access this resource the guard will return true, else it will throw a ForbiddenException. For more information about the structure of roles see roles.interface.ts file or read the original documentation form accesscontrol library here.

    *note: for those who are asking what ACGuard stands for, it of course stands for Access Control Guard 😄

  • UserRoles(<prop>): if you want to get access to the user roles directly, maybe you want to check it's roles manually instead of ACGuard doing it for you, then that decorator is what you are looking for. The decorator is really simple, it just return the req.user.roles value from the request object, but wait, what if the user roles doesn't exist in prop: role? We knew that you would ask this question, so you can pass an optional property key to the decorator to get it from the user object e.g @UserRoles('permissions') will return the req.user.permissions instead.

  • @InjectRolesBuilder(): if you hate the ACGuard - imo it's a good guard - and want to build your own Guard instead, you will likely need to access to the underlying RolesBuilder Object , then that decorator is for you; it will inject the Roles you have defined before, i.e the object passed to the AccessControlModule.forRoles(roles).

  1. Are you still there? Ok, that's it, you can go and run the application now, but wait, did someone asked for the AuthGuard? Ok let's discuss the LIMITATIONS.

Limitations

First of all, this module built with some assumptions

  1. The user object will exist in req.user
  2. It is up to you to build your own AuthGuard that will attach the user object to the req object, read more
  3. The AuthGuard must be registered before roles guard, in this case it's ACGuard, and of course you can combine the AuthGuard and ACGuard in one guard, and use it everywhere.

Secondly, i don't think these are limitations, since you can easily build your own guard and you don't need the built-in ones anymore.

CHANGELOG

See CHANGELOG for more information.

Contributing

You are welcome with this project for contributing, just make a PR.

Authors

  • Shady Khalifa - Initial work

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].