npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

abacl

v8.0.7

Published

Attribute Based Access Control Library

Downloads

352

Readme

Attribute-Based Access Control Library

npm Coverage npm GitHub Gitter documentation Build, Test and Publish

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 define any actions you want (scoped).
  • What can? the answer is object - You can define all objects 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? | :white_check_mark: | :heavy_check_mark: With more options | | How can operate? | :white_check_mark: CRUD | :heavy_check_mark: With more options | | What resource? | :white_check_mark: Not Bad At All | :heavy_check_mark: More control on resource | | Where user can do? | :x: | :heavy_check_mark: Supported by IP and CIDR | | When user can do? | :x: | :heavy_check_mark: Supported by CRON | | Best structure? | Monolithic Apps | PWA, Restful, 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, We scoped action, object and subject which means you can have more control over these attributes.

Note: if you want to have more control over the scoped attributes send at most three character of the first subject, action, or object for example so or sub|obj it means subject and object are in strict mode.

Quick Start Guide

installation

npm install --save abacl

Usage 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 = await ac.can([user.subject], 'read', 'article');

// change strict mode dynamically, Example:
// const strictPermission = await ac.can([user.subject], 'read', 'article', { strict: true });

/**
 *   it('should change strict mode dynamically', () => {
 *     const ac = new AccessControl(policies, { strict: true });
 *
 *     expect(await ac.can([Role.User], 'read', 'article:published').granted).toBeFalsy();
 *
 *     // After changing strict mode
 *     expect(await 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 ...

  // return filtered data based on the permission
  const response = await 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 = await ac.can([user.subject], 'create', 'article', {
  callable: (perm: Permission) => {
    return perm.location(user.ip) && perm.time();
  },
});

if (permission.granted) {
  const inputData = await permission.field(article);

  // the `inputData` has not `owner` property
  // do something and then return results to user
}

Related Project

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.

License

MIT