Package Exports
- abacl
- abacl/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (abacl) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Attribute-Based Access Control Library
The Attribute-Based Access-Control Library let you define five can access ability:
- Who can? the answer is
subject- Like RBAC a user can have multiple subjects. - How can it? the answer is
action- You can defineanyactions you want (scoped). - What can? the answer is
object- You can defineallobjects you want (scoped). - Where can? the answer is
location- With IP and CIDR you can find the location of users. - When can it? the answer is
time- objects availabilities with cron expression and a duration.
ABAC vs RBAC?
| Question | RBAC | ABAC |
|---|---|---|
| Who can access? | ✔️ | ✔️ |
| How can operate? | ✅ CRUD | ✔️ With more options |
| What resource? | ✅ Not Bad At All | ✔️ More control on resource |
| Where user can do? | ❌ | ✔️ Supported by IP and CIDR |
| When user can do? | ❌ | ✔️ Supported by CRON |
| Best structure? | Monolithic Apps | PWA, Restfull, GraphQL |
| Suitable for? | Small and medium projects | Medium and large projects |
What's Scope?
- look at carefully; scan.
- assess or investigate something.
In this library, I have scoped action, object and subject which means you can have more control over these attributes.
Quick Start Guide
installation
npm install --save abaclUsage and Dangling
Define your user policies as a json array, so you can store it in your database:
import { Policy } from 'abacl';
enum Role {
Admin = 'admin',
User = 'user',
Guest = 'guest',
Manager = 'manager',
}
const policies: Policy<Role>[] = [
{
subject: Role.Admin,
action: 'any',
object: 'all',
},
{
subject: Role.Guest,
action: 'read',
object: 'article:published',
},
{
subject: Role.Guest,
action: 'create:own',
object: 'article:published',
},
{
subject: Role.Manager,
action: 'any',
object: 'article',
},
{
subject: Role.User,
action: 'create:own',
object: 'article',
field: ['*', '!owner'],
location: ['192.168.2.10', '192.168.1.0/24'],
time: [
{
cron_exp: '* * 7 * * *', // from 7 AM
duration: 9 * 60 * 60, // for 9 hours
},
],
},
{
subject: Role.User,
action: 'read:own',
object: 'article',
},
{
subject: Role.User,
action: 'read:shared',
object: 'article',
filter: ['*', '!owner'],
},
{
subject: Role.User,
action: 'delete:own',
object: 'article',
},
{
subject: Role.User,
action: 'update:own',
object: 'article',
field: ['*', '!id', '!owner'],
},
];Article and User definition objects:
const user = {
id: 1,
subject: Role.User,
ip: '192.168.1.100',
};
const article = {
id: 1,
owner: 'user1',
title: 'title',
content: 'content',
};Create a new access control object, then get the permission grants:
import AccessControl from 'abacl';
// The `strict` `AccessControlOption` control the scoped functionality
// default strict value is true, you can change it on the `can` method
const ac = new AccessControl(policies, { strict: false });
const permission = ac.can([user.subject], 'read', 'article');
// change strict mode dynamically, Example:
// const strictPermission = ac.can([user.subject], 'read', 'article', { strict: true });
/**
* it('should change strict mode dynamically', () => {
* const ac = new AccessControl(policies, { strict: true });
*
* expect(ac.can([Role.User], 'read', 'article:published').granted).toBeFalsy();
*
* // After changing strict mode
* expect(ac.can([Role.User], 'read', 'article:published', { strict: false }).granted).toBeTruthy();
* });
*
* */
if (permission.granted) {
// default scope for action and object is `any` and `all`
if (permission.has({ action: 'read:own' })) {
// user has read owned article objects
}
if (permission.has({ action: 'read:shared' })) {
// user can access shared article objects
}
if (permission.has({ object: 'article:published' })) {
// user can access shared article objects
}
// do something ...
const response = permission.filter(article);
}Time and location access check example:
import { AccessControl, Permission } from 'abacl';
// default `strict` value is true
const ac = new AccessControl(policies, { strict: true });
const permission = ac.can([user.subject], 'create', 'article', {
callable: (perm: Permission) => {
return perm.location(user.ip) && perm.time();
},
});
if (permission.granted) {
const inputData = permission.field(article);
// the `inputData` has not `owner` property
// do something and then return results to user
}Thanks a lot
accesscontrol - Role and Attribute based Access Control for Node.js
CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access.