{"id":13818172,"url":"https://github.com/sergey-telpuk/nestjs-rbac","last_synced_at":"2026-02-05T19:00:47.846Z","repository":{"id":45033842,"uuid":"207534107","full_name":"sergey-telpuk/nestjs-rbac","owner":"sergey-telpuk","description":"Awesome RBAC for NestJs","archived":false,"fork":false,"pushed_at":"2025-02-12T16:52:45.000Z","size":202,"stargazers_count":483,"open_issues_count":3,"forks_count":37,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-08-24T23:48:52.994Z","etag":null,"topics":["javascript","nestjs","nodejs","npm","rbac"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sergey-telpuk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-10T10:51:32.000Z","updated_at":"2025-08-19T03:18:25.000Z","dependencies_parsed_at":"2024-01-18T05:15:25.267Z","dependency_job_id":"b4413931-4029-42c9-9f83-3c127fd3df84","html_url":"https://github.com/sergey-telpuk/nestjs-rbac","commit_stats":null,"previous_names":[],"tags_count":32,"template":true,"template_full_name":null,"purl":"pkg:github/sergey-telpuk/nestjs-rbac","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergey-telpuk%2Fnestjs-rbac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergey-telpuk%2Fnestjs-rbac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergey-telpuk%2Fnestjs-rbac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergey-telpuk%2Fnestjs-rbac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sergey-telpuk","download_url":"https://codeload.github.com/sergey-telpuk/nestjs-rbac/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergey-telpuk%2Fnestjs-rbac/sbom","scorecard":{"id":812218,"data":{"date":"2025-08-11","repo":{"name":"github.com/sergey-telpuk/nestjs-rbac","commit":"9c8e6134fc446b56bf53a6ce5c927c7d249c21bf"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Code-Review","score":1,"reason":"Found 5/30 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/CD.yml:1","Warn: no topLevel permission defined: .github/workflows/CI.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENCE.md:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CD.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/sergey-telpuk/nestjs-rbac/CD.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/CD.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/sergey-telpuk/nestjs-rbac/CD.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/sergey-telpuk/nestjs-rbac/CI.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/sergey-telpuk/nestjs-rbac/CI.yml/master?enable=pin","Warn: containerImage not pinned by hash: docker/Dockerfile:1: pin your Docker image by updating node:alpine to node:alpine@sha256:51dbfc749ec3018c7d4bf8b9ee65299ff9a908e38918ce163b0acfcd5dd931d9","Warn: npmCommand not pinned by hash: docker/Dockerfile:7","Warn: npmCommand not pinned by hash: .github/workflows/CD.yml:22","Warn: npmCommand not pinned by hash: .github/workflows/CI.yml:21","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   3 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 9 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T13:27:12.007Z","repository_id":45033842,"created_at":"2025-08-23T13:27:12.007Z","updated_at":"2025-08-23T13:27:12.007Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29130088,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T18:55:47.139Z","status":"ssl_error","status_checked_at":"2026-02-05T18:55:04.010Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","nestjs","nodejs","npm","rbac"],"created_at":"2024-08-04T07:00:34.972Z","updated_at":"2026-02-05T19:00:47.834Z","avatar_url":"https://github.com/sergey-telpuk.png","language":"TypeScript","funding_links":[],"categories":["Components \u0026 Libraries","TypeScript"],"sub_categories":[],"readme":"[![npm version](https://badge.fury.io/js/nestjs-rbac.svg?icon=si%3Anpm)](https://badge.fury.io/js/nestjs-rbac)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sergey-telpuk/nestjs-rbac/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sergey-telpuk/nestjs-rbac/)\n[![codecov](https://codecov.io/gh/sergey-telpuk/nestjs-rbac/branch/master/graph/badge.svg)](https://codecov.io/gh/sergey-telpuk/nestjs-rbac)\n[![npm](https://img.shields.io/npm/dw/nestjs-rbac)](https://www.npmjs.com/package/nestjs-rbac)\n![RBAC CI](https://github.com/sergey-telpuk/nestjs-rbac/workflows/RBAC%20CI/badge.svg)\n![RBAC CD](https://github.com/sergey-telpuk/nestjs-rbac/workflows/RBAC%20CD/badge.svg)\n\n# nestjs-rbac\nRBAC module for [Nest](https://github.com/nestjs/nest) applications.\n\n## Community\nJoin our Discord server: [Link](https://discord.gg/Gu3KxPJNg3)\n\n## Compatibility\nSupports NestJS ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0.\n\n## Installation\n```bash\nnpm i nestjs-rbac\n```\n\n## Core concepts\nRBAC storage consists of the following keys:\n\n- `roles`: list of role names\n- `permissions`: map of permission name to allowed actions\n- `grants`: map of role name to permission grants\n- `filters`: map of filter key to filter implementation (class or instance)\n\nPrefix `ASYNC_` use for async operations.\n\n### Grant syntax\n- `\u0026` extends another grant, for instance `admin` extends `user` (only one level of inheritance)\n- `@` selects a single action, for instance `permission1@update`\n\n### Behavior notes\n- Grants are expanded to include `permission@action` for each action in `permissions`.\n- Missing permissions in `permissions` are ignored during grant parsing.\n- When multiple permissions are passed to `can` or `canAsync`, all must pass (AND).\n- `ParamsFilter.setParam` stores arguments as an array; filters receive the same array.\n\n## Quick start\nDefine your RBAC storage:\n```typescript\nimport { Type } from '@nestjs/common';\nimport { IFilterPermission, IStorageRbac } from 'nestjs-rbac';\n\nexport const RBAC: IStorageRbac = {\n  roles: ['admin', 'user'],\n  permissions: {\n    permission1: ['create', 'update', 'delete'],\n    permission2: ['create', 'update', 'delete'],\n    permission3: ['filter1', 'filter2', RBAC_REQUEST_FILTER],\n    permission4: ['create', 'update', 'delete'],\n    permission5: ['ASYNC_filter1', 'ASYNC_filter2', ASYNC_RBAC_REQUEST_FILTER],\n  },\n  grants: {\n    admin: ['\u0026user', 'permission1', 'permission3', 'permission5'],\n    user: [\n      '\u0026userRoot',\n      'permission2',\n      'permission1@create',\n      'permission3@filter1',\n      'permission5@ASYNC_filter1',\n    ],\n    userRoot: ['permission4'],\n  },\n  filters: {\n    filter1: TestFilterOne,\n    filter2: TestFilterTwo,\n    ASYNC_filter1: TestAsyncFilterOne,\n    ASYNC_filter2: TestAsyncFilterTwo,\n    [RBAC_REQUEST_FILTER]: RequestFilter,\n    [ASYNC_RBAC_REQUEST_FILTER]: RequestAsyncFilter,\n  },\n};\n```\n\nRegister the module:\n```typescript\nimport { Module } from '@nestjs/common';\nimport { RBAcModule } from 'nestjs-rbac';\n\n@Module({\n  imports: [RBAcModule.forRoot(RBAC)],\n  controllers: [],\n})\nexport class AppModule {}\n```\n\nProtect routes with the guard and decorators:\n```typescript\nimport { Controller, Get, UseGuards } from '@nestjs/common';\nimport { RBAcGuard, RBAcPermissions } from 'nestjs-rbac';\n\n@Controller()\nexport class RbacTestController {\n  @RBAcPermissions('permission1', 'permission1@create')\n  @UseGuards(AuthGuard, RBAcGuard)\n  @Get('/example')\n  async example(): Promise\u003cboolean\u003e {\n    return true;\n  }\n}\n```\n\n\u003e Note: The guard expects `request.user` to implement `IRole` (`{ role: string }`).\n\n## Static vs dynamic storage\n### Static storage\n```typescript\nimport { Module } from '@nestjs/common';\nimport { RBAcModule } from 'nestjs-rbac';\n\n@Module({\n  imports: [RBAcModule.forRoot(RBAC)],\n})\nexport class AppModule {}\n```\n\n### Dynamic storage\nImplement `IDynamicStorageRbac` to load RBAC rules from a database, service, or file:\n```typescript\nimport { Injectable, Module } from '@nestjs/common';\nimport { IDynamicStorageRbac, IStorageRbac, RBAcModule } from 'nestjs-rbac';\n\n@Injectable()\nexport class DynamicStorageService implements IDynamicStorageRbac {\n  constructor(private readonly repository: AnyRepository) {}\n\n  async getRbac(): Promise\u003cIStorageRbac\u003e {\n    return this.repository.getRbac();\n  }\n}\n\n@Module({\n  imports: [RBAcModule.forDynamic(DynamicStorageService)],\n})\nexport class AppModule {}\n```\n\n## Decorators\n- `@RBAcPermissions('permission', 'permission@create')` (AND)\n- `@RBAcAnyPermissions(['permission'], ['permission@create'])` (OR)\n- `@RBAcAsyncPermissions('permission', 'permission@create')` (AND, async filters)\n- `@RBAcAnyAsyncPermissions(['permission'], ['permission@create'])` (OR, async filters)\n\n### Controller-wide guard example (CRUD)\n```typescript\nimport { RBAcPermissions, RBAcGuard } from 'nestjs-rbac';\n\n@Crud({ model: { type: Company } })\n@RBAcPermissions('permission2')\n@UseGuards(AuthGuard, RBAcGuard)\n@Controller('companies')\nexport class CompaniesController implements CrudController\u003cCompany\u003e {\n  constructor(public service: CompaniesService) {}\n}\n```\n\n## Using as a service\n```typescript\nimport { Controller, Get } from '@nestjs/common';\nimport { RbacService } from 'nestjs-rbac';\n\n@Controller()\nexport class RbacTestController {\n  constructor(private readonly rbac: RbacService) {}\n\n  @Get('/')\n  async test(): Promise\u003cboolean\u003e {\n    return (await this.rbac.getRole(role)).can('permission', 'permission@create');\n  }\n}\n```\n\n## Custom filters\nFilters allow custom runtime checks. Implement `IFilterPermission` and bind the filter key in storage.\n```typescript\nimport { IFilterPermission } from 'nestjs-rbac';\n\nexport class TestFilter implements IFilterPermission {\n  can(params?: unknown[]): boolean {\n    return Boolean(params?.[0]);\n  }\n}\n\n@Injectable()\nexport class TestAsyncFilter implements IFilterPermission {\n  constructor(private readonly myService: MyService) {}\n\n  async canAsync(params?: unknown[]): Promise\u003cboolean\u003e {\n    const myResult = await this.myService.someAsyncOperation();\n    return Boolean(myResult);\n  }\n}\n```\n\nA single filter can implement both `can` and `canAsync`. If you use the `RBAcGuard`, they are evaluated with an AND condition.\n\n### ParamsFilter\n```typescript\nconst filter = new ParamsFilter();\nfilter.setParam('filter1', somePayload);\n\nconst res = (await rbacService.getRole('admin', filter)).can('permission1@filter1');\n```\n\n### Request filter example\n`RBAC_REQUEST_FILTER` passes the request object into the filter:\n```typescript\nimport { IFilterPermission, RBAC_REQUEST_FILTER } from 'nestjs-rbac';\n\nexport class RequestFilter implements IFilterPermission {\n  can(params?: unknown[]): boolean {\n    const request = params?.[0] as { headers?: Record\u003cstring, string\u003e } | undefined;\n    return request?.headers?.['test-header'] === 'test';\n  }\n}\n\nexport const RBAC: IStorageRbac = {\n  roles: ['role'],\n  permissions: {\n    permission1: ['filter1', 'filter2', RBAC_REQUEST_FILTER],\n  },\n  grants: {\n    role: [`permission1@${RBAC_REQUEST_FILTER}`],\n  },\n  filters: {\n    [RBAC_REQUEST_FILTER]: RequestFilter,\n  },\n};\n```\n\n## Cache\nLarge RBAC storages can make grant parsing expensive. You can enable cache with the built-in `RbacCache` (node-cache):\n```typescript\nimport { RBAcModule, RbacCache } from 'nestjs-rbac';\n\n@Module({\n  imports: [\n    RBAcModule.useCache(RbacCache, { KEY: 'RBAC', TTL: 400 }).forDynamic(AsyncService),\n  ],\n})\nexport class AppModule {}\n```\n\nTo use a custom cache, implement `ICacheRBAC` and inject it via `@Inject('ICacheRBAC')`.\n\n## Testing\n```bash\nnpm test\nnpm run test:int\nnpm run test:e2e\n```\n\n## Linting\n```bash\nnpm run lint\nnpm run lint:fix\n```\n\n## Docker\n```bash\ndocker-compose up --build\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergey-telpuk%2Fnestjs-rbac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsergey-telpuk%2Fnestjs-rbac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergey-telpuk%2Fnestjs-rbac/lists"}