Giter Site home page Giter Site logo

Extending Roles? about access-control HOT 7 CLOSED

tselect-npm avatar tselect-npm commented on September 26, 2024
Extending Roles?

from access-control.

Comments (7)

SylvainEstevez avatar SylvainEstevez commented on September 26, 2024

@broom9 We could definitely consider adding role inheritance. If you have ideas on how this could be implemented, then feel free to share them here and we'll see how we can make things happen.

As of today, and as a you mentioned in your issue, adding multiple roles is indeed the way to go with the current implementation. If you're using the builtin memory store, then it will take care of fetching permissions for all roles the user is assigned to and evaluate permissions associated with each of those roles.

On another note and to better understand your use case, which of RBAC or ABAC do you need?

from access-control.

broom9 avatar broom9 commented on September 26, 2024

from access-control.

SylvainEstevez avatar SylvainEstevez commented on September 26, 2024

Reading your explanations, conditions with dynamic variables indeed seem to fit your needs. I'm trying to provide some examples below, let me know if things are not clear enough.

Ensuring that resource.userId == req.user.id

Assuming an endpoint GET /profiles/:user_id that allows users to fetch profile information. To ensure that the user only accesses their own information, you could write a permission like this:

const permission = {
  id: 'UserFetchProfile',
  resource: 'profiles',
  action: 'fetch',
  effect: 'allow',
  condition: {
    stringEquals: {
      simpleValue: {
        'req.params.user_id': '{{{subject.id}}}'
      }
    }
  }
};

Then to check the user's permissions:

const subject = new Subject(req.user);
accessControl.authorize(subject, 'profiles', 'fetch', { req }); // <- Passing req to the environment

Ensuring that users only reach the tenant they're allowed to

Gonna assume that you're storing something like a tenant_id property within your user data and that you're able to access the tenant's id from the url in your request. We can modify the condition as follows to add the constraint.

const permission = {
  id: 'UserFetchProfile',
  resource: 'profiles',
  action: 'fetch',
  effect: 'allow',
  condition: {
    stringEquals: {
      simpleValue: {
        'req.params.user_id': '{{{subject.id}}}',
        'tenant': '{{{subject.tenant_id}}}'
      }
    }
  }
};

Then to check the user's permissions:

const subject = new Subject(req.user); // <- Where req.user.tenant_id is defined
const tenant = parseTenant(req); // <- Your way to parse the tenant information
accessControl.authorize(subject, 'profiles', 'fetch', { req, tenant }); // <- Passing req and "tenant" to the environment

This will guarantee that the user can only fetch their own profile on their assigned tenant.


If what you are looking for is a way to factorize the tenant check for all users, then I'm afraid it could only be done with condition merging, which is a bit different from role inheritance and would probably be hard to implement. I'm definitely open to suggestions on how to handle this though. Hope that clarifies things a bit!

from access-control.

broom9 avatar broom9 commented on September 26, 2024

Thanks for the detailed example codes. There is still one thing I'm not sure it's clear.

When you delcare simpleValue condition like this:

 simpleValue: {
        'req.params.user_id': '{{{subject.id}}}'
      }

The key 'req.params.user_id' is retrieved from the environment, basically the package will try to do environment.req.params.user_id, which makes sense.

Does the value subject.id need to be in the environment as well? I thought it would use the subject parameter passed into the authorize method, but from my experiment looks like it needs me to pass "subject" as a key in the environment. https://github.com/bluebirds-blue-jay/access-control/blob/13610cf9bfc8d8ac8553cc813e35b3454482458b/src/classes/condition-evaluator.ts#L81

from access-control.

SylvainEstevez avatar SylvainEstevez commented on September 26, 2024

@broom9 I just checked our own project's implementation and indeed the subject is not passed by Bluejay. Instead we have an environmentFactory utility that extracts the most common environment values from the request, which I'm partially reproducing here:

import { Keys } from '@bluejay/access-control';

export function environmentFactory(req: Request): TAuthorizeEnvironment {
  return {
      bodyAttributes: Keys.list(req.body),
      body: req.body,
      headers: req.headers,
      queryAttributes: Keys.list(req.query),
      query: req.query,
      params: req.params,
      subject: req.subject.toJSON() // We store the subject on the request
    };
}

Then:

authorizer.authorize(resource, action, environmentFactory(req));

The {{{subject.id}}} in the previous example is indeed explicitly passed to the environment.

from access-control.

broom9 avatar broom9 commented on September 26, 2024

from access-control.

SylvainEstevez avatar SylvainEstevez commented on September 26, 2024

See example here: https://github.com/bluebirds-blue-jay/access-control#condition-variables.

I'm assuming that you found a way to achieve your goal @broom9, closing for housekeeping.

from access-control.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.