{"id":25495380,"url":"https://github.com/mutaimwiti/rbactl","last_synced_at":"2025-06-30T02:36:56.335Z","repository":{"id":90781966,"uuid":"184244269","full_name":"mutaimwiti/rbactl","owner":"mutaimwiti","description":"Easy to use and intuitive role-based access control library for Express apps.","archived":false,"fork":false,"pushed_at":"2019-12-16T11:02:19.000Z","size":808,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-04-10T02:54:53.159Z","etag":null,"topics":["authorization","express","node","rbac"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/rbactl","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mutaimwiti.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-04-30T10:42:42.000Z","updated_at":"2024-07-21T21:29:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"7e097262-37ca-4fcd-be96-59d533a1ff42","html_url":"https://github.com/mutaimwiti/rbactl","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mutaimwiti/rbactl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutaimwiti%2Frbactl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutaimwiti%2Frbactl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutaimwiti%2Frbactl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutaimwiti%2Frbactl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mutaimwiti","download_url":"https://codeload.github.com/mutaimwiti/rbactl/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutaimwiti%2Frbactl/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262699782,"owners_count":23350369,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["authorization","express","node","rbac"],"created_at":"2025-02-19T00:36:09.653Z","updated_at":"2025-06-30T02:36:56.289Z","avatar_url":"https://github.com/mutaimwiti.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## rbactl\n\n[![build](https://gitlab.com/mutaimwiti/rbactl/badges/master/build.svg)](https://gitlab.com/mutaimwiti/rbactl/pipelines)\n[![coverage](https://gitlab.com/mutaimwiti/rbactl/badges/master/coverage.svg)](https://gitlab.com/mutaimwiti/rbactl/commits/master)\n[![version](https://img.shields.io/npm/v/rbactl.svg)](https://www.npmjs.com/package/rbactl)\n[![downloads](https://img.shields.io/npm/dm/rbactl.svg)](https://www.npmjs.com/package/rbactl)\n[![license](https://img.shields.io/npm/l/rbactl.svg)](https://www.npmjs.com/package/rbactl)\n\n**rbactl** is an easy to use and intuitive role-based access control library for [Express](https://expressjs.com/)\napps. The library embraces the unopinionated and minimalist approach of express and can also be used with other\nframeworks built on top of express. Your app decides how to store and retrieve roles (plus permissions) and the\nauthentication logic. The library only comes in to simplify the process of building your authorization logic.\n\n\u003e Repo : [GitLab](https://gitlab.com/mutaimwiti/rbactl) | [GitHub](https://github.com/mutaimwiti/rbactl)\n\n### Installation\n\nUse one of the two based on your project's dependency manager.\n\n```bash\n$ npm install rbactl --save\n\n$ yarn add rbactl\n```\n\n### Getting started\n\n1. Install the library.\n\n2. Define application permissions.\n\n   Permissions can be defined in a single file or directory with each entity having its own file. This does not prevent\n   you from defining it on an object on the fly.\n\n3. Define application policies.\n\n   Policies can be defined in a single file or directory with each entity having its own file. This does not prevent\n   you from defining it on an object on the fly.\n\n4. Add or update user and role models.\n\n   The role model should have a property that stores permissions (an array). A relationship should exist such that a\n   user can have many roles and a role can have many users. The user model should have a property or a function that\n   returns the user's list of permissions based on their roles.\n\n5. Add or update user and role control logic.\n\n   This will allow management of roles and users on the application. It should achieve at least the following:\n\n   - Creation of roles\n   - Setting of role permissions\n   - Setting of user roles\n\n6. Add user sign up / creation logic\n\n   This will allow for creation of user accounts.\n\n7. Create your authentication middleware.\n\n   Ideally, once the middleware identifies the user it should add the user object to the `req` object.\n\n8. Create your authorization middleware creator.\n\n   This will take an action and entity and return a middleware function that authorizes the action against the\n   user permissions and system policies.\n\n9. Apply both the authentication and authorization middleware as required on your routes.\n\n10. Consider defining an authorization check method, `can`, on your user model.\n\n    This can prove convenient if you still need to perform an authorization check without necessarily doing it at the\n    routing level.\n\n### Quick start\n\n##### Define permissions\n\n```javascript\nconst { parsePermissions } = require('rbactl');\n\nconst permissions = parsePermissions({\n  article: {\n    '*': 'Full articles access',\n    view: 'View articles',\n    create: 'Create articles',\n    update: 'Update articles',\n    delete: 'Delete articles',\n  },\n  report: {\n    '*': 'Full reports access',\n    view: 'View reports',\n    create: 'Create reports',\n    update: 'Update reports',\n    delete: 'Delete reports',\n  },\n\n  // ... more permissions ...\n});\n```\n\n\u003e See an actual example of this;\n\u003e [mongo](examples/mongo/src/permissions.js) or [postgres](examples/postgres/src/permissions).\n\u003e\n\u003e See [permissions documentation](DOCUMENTATION.md#permissions).\n\n##### Define policies\n\n```javascript\nconst policies = {\n  article: {\n    view: {\n      any: [\n        'article.view',\n        'article.create',\n        'article.update',\n        'article.delete',\n      ],\n    },\n    create: 'article.create',\n    update: 'article.update',\n    delete: 'article.delete',\n  },\n\n  report: {\n    view: {\n      any: ['report.view', 'report.create', 'report.update', 'report.delete'],\n    },\n    create: 'report.create',\n    update: 'report.update',\n    delete: 'report.delete',\n  },\n\n  // ... more policies ...\n};\n```\n\n\u003e See an actual example of this;\n\u003e [mongo](examples/mongo/src/policies.js) or [postgres](examples/postgres/src/policies).\n\u003e\n\u003e See [policies documentation](DOCUMENTATION.md#policies).\n\n##### Define roles\n\nIdeally, you will have a Role model that has a permissions property (array). This is just a simple static example.\n\n```javascript\nconst roles = [\n  {\n    name: 'Basic',\n    permissions: ['article.view'],\n  },\n\n  {\n    name: 'Admin',\n    permissions: ['article.create', 'article.update'],\n  },\n\n  {\n    name: 'Super Admin',\n    permissions: ['article.*'],\n  },\n\n  // ... more roles ...\n];\n```\n\n\u003e See an actual example of this;\n\u003e [mongo](examples/mongo/src/models/role.js) or [postgres](examples/postgres/src/models/role.js).\n\n##### Define user permissions resolver\n\nThe user model should have a relationship with the roles model. This is required to determine the permissions of a\nuser.\n\n```javascript\nconst User = {\n  // ... other user model logic and properties\n\n  /**\n   * The definition of this function is down to your persistence\n   * system.\n   *\n   * @returns {Array}\n   */\n  getPermissions() {\n    let permissions = [];\n\n    this.roles.forEach((role) =\u003e {\n      permissions = permissions.concat(role.permissions);\n    });\n\n    return permissions;\n  },\n\n  // ... other user model logic and properties\n};\n```\n\n\u003e See an actual example of this;\n\u003e [mongo](examples/mongo/src/models/user.js) or [postgres](examples/postgres/src/models/user.js).\n\n##### Define authentication middleware\n\nThis is a tiny snippet of the authorization middleware. It only shows the success case where the user object is added\nto the `req` express object.\n\n```javascript\nconst authenticate = async (req, res, next) =\u003e {\n  // other authentication logic\n\n  // make user object available to the next handlers\n  req.user = authUserObject;\n  next();\n\n  // other authentication logic\n};\n```\n\n\u003e See an actual example of this;\n\u003e [mongo](examples/mongo/src/middleware/authenticate.js) or\n\u003e [postgres](examples/postgres/src/middleware/authenticate.js).\n\n##### Define authorization middleware - can\n\n```javascript\nconst { createCan } = require('rbactl');\n\nconst can = createCan(\n  // the system policies\n  policies,\n\n  // user permissions resolver\n  async (req) =\u003e req.user.getPermissions(),\n\n  // unauthorized request handler\n  (req, res) =\u003e {\n    return res.status(403).json({\n      message: `You are not authorized to perform this action.`,\n    });\n  },\n\n  // authorization exception handler\n  (req, res) =\u003e {\n    return res.status(500).json({\n      message: 'Sorry :( Something bad happened.',\n    });\n  },\n);\n```\n\n\u003e See an actual example of this;\n\u003e [mongo](examples/mongo/src/middleware/can.js) or [postgres](examples/postgres/src/middleware/can.js).\n\u003e\n\u003e See [authorization documentation](DOCUMENTATION.md#authorization).\n\n##### Protect endpoints\n\n```javascript\n// assuming we have our simple app ...\nconst app = express();\n\napp.get('/article/', authenticate, can('view', 'article'), () =\u003e {\n  // user is allowed to view list of articles\n});\n\napp.post('/article/', authenticate, can('create', 'article'), () =\u003e {\n  // user is allowed to create article\n});\n\n// ... the same pattern applies for other routes\n```\n\n\u003e See an actual example of this;\n\u003e [mongo](examples/mongo/src/routes) or [postgres](examples/postgres/src/routes).\n\n### Complete examples\n\nTo wrap your head around the entire process carefully go through one or both examples:\n\n- [Mongo](examples/mongo)\n- [Postgres](examples/postgres)\n\n\u003e These may still not make everything crystal clear. Go through the [documentation](DOCUMENTATION.md#documentation) to \n\u003e understand all key concepts.\n\n### Licence\n\n[MIT](https://mit-license.org/) © Mutai Mwiti |\n[GitHub](https://github.com/mutaimwiti) |\n[GitLab](https://gitlab.com/mutaimwiti)\n\n_**DISCLAIMER:**_\n_All opinions expressed in this repository are mine and do not reflect any company or organisation I'm involved with._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmutaimwiti%2Frbactl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmutaimwiti%2Frbactl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmutaimwiti%2Frbactl/lists"}