{"id":13657573,"url":"https://github.com/simon-barton/node-abac","last_synced_at":"2025-10-31T19:30:23.267Z","repository":{"id":54382109,"uuid":"80822633","full_name":"simon-barton/node-abac","owner":"simon-barton","description":":raised_hand: Node.js Attributes Based Access Control library","archived":false,"fork":false,"pushed_at":"2021-02-22T07:41:46.000Z","size":24,"stargazers_count":44,"open_issues_count":3,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-05T04:34:01.142Z","etag":null,"topics":["abac","access-control","nodejs"],"latest_commit_sha":null,"homepage":"","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/simon-barton.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}},"created_at":"2017-02-03T11:17:53.000Z","updated_at":"2024-11-19T21:02:40.000Z","dependencies_parsed_at":"2022-08-13T14:00:47.671Z","dependency_job_id":null,"html_url":"https://github.com/simon-barton/node-abac","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simon-barton%2Fnode-abac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simon-barton%2Fnode-abac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simon-barton%2Fnode-abac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simon-barton%2Fnode-abac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simon-barton","download_url":"https://codeload.github.com/simon-barton/node-abac/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239224359,"owners_count":19602973,"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":["abac","access-control","nodejs"],"created_at":"2024-08-02T05:00:45.465Z","updated_at":"2025-10-31T19:30:23.180Z","avatar_url":"https://github.com/simon-barton.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"node-abac\n========\n\n### Node.js Attributes Based Access Control library\n\n[![npm version](https://badge.fury.io/js/node-abac.svg)](https://www.npmjs.com/package/node-abac) \n[![npm](https://img.shields.io/npm/dt/node-abac.svg)](https://www.npmjs.com/package/node-abac) \n[![npm](https://img.shields.io/npm/l/node-abac.svg)](LICENSE)\n\nThis library is designed to help implement the concept of Attribute Based Access Control (ABAC) in your Node.js applications \nusing simple `JSON` or `YAML` policies.\n\nFor more information on ABAC consider reading the [NIST Specification Guide](http://nvlpubs.nist.gov/nistpubs/specialpublications/NIST.sp.800-162.pdf).\n\nInspired by [php-abac](https://github.com/Kilix/php-abac)\n\n## Installation\n\nInstall the latest stable release with the npm command-line tool:\n\n```bash\n$ npm install node-abac\n```\n\n## Configuration\n\nImport the library\n\n```javascript\nconst NodeAbac = require('node-abac');\n```\n\n#### Policies\n\nPolicies can be read from one or more files. Both JSON and YAML structures are supported and can be mixed if desired.\n\n```javascript\nconst Abac = new NodeAbac('path/to/policy.json');\nconst Abac = new NodeAbac(['path/to/policy.json', 'another/path/policy2.yml']);\n```\n\nOr passed directly in as a JavaScript object\n\n```javascript\nconst myPolicy = {\n    attributes: {\n        user: {\n            hasDrivingLicense: \"Possesses driving license\"\n        }\n    },\n    rules: {\n        \"can-drive\": {\n            attributes: {\n                \"user.hasDrivingLicense\": {\n                    /* NOTE: 'comparison_type' value must be lowercase e.g. 'boolean' vs 'isStrictlyEqual: Boolean' */\n                    comparison_type: \"boolean\",\n                    comparison: \"booleanAnd\",\n                    value: true\n                }\n            }\n        }\n    }\n};\n\nconst Abac = new NodeAbac(myPolicy);\n```\n\n#### Error messages\n\nDescriptive enforcement errors can be toggled on or off globally using a second parameter to `NodeAbac`. By default they're disabled\nso failed enforcements will simply return `false`. For example:\n\n```json\n{\n  \"msg\": \"can-be-admin DENIED\",\n  \"errors\": [\n    {\n      \"msg\": \"numeric value 'Times banned' failed to pass isLesserThanEqualTo\",\n      \"expected\": 1,\n      \"actual\": 2\n    },\n    {\n      \"msg\": \"array value 'Origin' failed to pass isIn\",\n      \"expected\": \"FR|DE|IT|L|GB|P|ES|NL|B\",\n      \"actual\": \"PL\"\n    }\n  ]\n}\n```\n\nTo enable globally\n\n```javascript\nconst Abac = new NodeAbac(myPolicy, true);\n```\nAlternatively this global flag can be overwritten on individual enforcement calls by using the fourth parameter `verbose_error`.\n\n```javascript\nconst Abac = new NodeAbac(myPolicy); // verbose_errors globally off\nconst mySubject = {};\nconst myResource = {};\n\n...\n\nconst result = Abac.enforce('my-rule', mySubject, myResource, true); // verbose_error on for this call only\n```\n\n## Usage\n\nThis library simply consists of two functions to integrate ABAC into your application.\n \n* [`getRuleAttributes(rule)`](#getRuleAttributes)\n* [`enforce(rule_name, subject, resource = {}, verbose_error = false)`](#enforce)\n\n### `getRuleAttributes`\n\n`getRuleAttributes` is used to inspect a rule for its required objects and their fields. The response is typically used to make further \nrequests to a Policy Information Point (PIP).\n\nGiven the policy with a rule `can-be-admin-of-group`: for a user to become admin of a group they must me active, over 21 years old, been banned no more than once\nand be in the group that they're attempting to administer.\n\n```json\n{\n    \"attributes\": {\n        \"user\": {\n            \"active\": \"Active\",\n            \"banCount\": \"Times banned\",\n            \"dob\": \"Date of birth\",\n            \"group\": \"Group ID\"\n        },\n        \"group\": {\n            \"id\": \"Group ID\"\n        }\n    },\n    \"rules\": {\n        \"can-be-admin-of-group\": {\n            \"attributes\": {\n                \"user.active\": {\n                    \"comparison_type\": \"boolean\",\n                    \"comparison\": \"boolAnd\",\n                    \"value\": true\n                },\n                \"user.dob\": {\n                    \"comparison_type\": \"datetime\",\n                    \"comparison\": \"isLessRecentThan\",\n                    \"value\": \"-21Y\"\n                },\n                \"user.banCount\": {\n                    \"comparison_type\": \"numeric\",\n                    \"comparison\": \"isLesserThanEqualTo\",\n                    \"value\": 1\n                },\n                \"user.group\": {\n                    \"comparison_target\": \"group\",\n                    \"comparison_type\": \"numeric\",\n                    \"comparison\": \"isStrictlyEqual\",\n                    \"field\": \"id\"\n                }\n            }\n        }\n    }\n}\n```\n\nCalling `getRuleAttributes('can-be-admin-of-group')` will return our required fields to fulfill the rule.\n\n```json\n{\n    \"user\": [\n        \"active\",\n        \"dob\",\n        \"banCount\",\n        \"group\"\n    ],\n    \"group\": [\n        \"id\"\n    ]\n}\n```\n\nThis tells us our `subject` is `user` and the `resource` is `group`.\n\n### `enforce`\n\n`enforce` is the point at which a permit or deny decision is made. It must be called with a rule name and subject and can optionally accept \na resource that the rule is protecting.\n\nTo continue the above example consider the scenario where we have acquired our attribute data and want to check the user can administer the group.\n\n```javascript\nlet subject = {\n    user: {\n        active: true,\n        dob: '1991-05-12',\n        banCount: 0,\n        group: 12\n    }\n};\nlet resource = {\n    group: {\n        id: 12\n    }\n};\n\nconst permit = Abac.enforce('can-be-admin-of-group', subject, resource); // returns true\n\nsubject = {\n    user: {\n        active: true,\n        dob: '2006-05-12', // too young\n        banCount: 4, // banned too many times\n        group: 12\n    }\n};\nresource = {\n    group: {\n        id: 12\n    }\n};\n\nconst deny = Abac.enforce('can-be-admin-of-group', subject, resource); // returns false || error message\n```\n\n### Comparisons\n\nFor more information on comparison usage please refer to the [dedicated comparisons documentation](doc/comparisons.md).\n\n## Coming Soon\n\n* Additional documentation and examples\n* Testing\n* Additional datatype operations\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimon-barton%2Fnode-abac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimon-barton%2Fnode-abac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimon-barton%2Fnode-abac/lists"}