RPS Implementation

wa wang
2 min readJan 22, 2020

In the previous article we explore RPS in depth. I will now present an implementation of RPS. RPS has four components. All components are interfaced and two have default implementations.

PermissionService

Permission service is dual purposed:

  1. Consume the permission configuration.
  2. Provide a set of permissions when given a resource, a set of roles and a scope.

A default RRSP (resource role scope permission) implementation is provided. RRSP expects a json file tiered by resources, roles, scopes and permissions respectively.

PrincipleRoleService

Provide a set of roles available to a principal when given a scope and a list of respective ScopeIds.

EntityScopeService

Provide a list of scopeIds when given a resourceId and a scope.

PermissionEvaluator

Given a resourceId and a specific permission, determine whether a principal possesses the given permission. The RPSevaluator accomplishes this by using the three above components.

EntityScopeService: ScopeIdFunc(scope, resourceId) = ScopeIds

PrincipleRoleService: RolesFunc(principal, ScopeIds) = Roles

PermissionService: RPfunction(Roles, Scope) = RPs

PermissionEvaluator: RP exists in RPs ?

Example:

Suppose there is a resource `truck` with resourceId `t1`. We want to determine if a user with id `u1` may drive the truck. User `u1` has the `owner` role at the `user` scope.

`truck`: {          #resource  `owner`: {`       #role    `user`:         #scope      [`drive`, `sell`]}}}    #permissions

ScopeIdFunc(`truck`,`t1`) = `u1` (user is associated with the truck)

RolesFunc(u1, `user`, `u1` ) = `owner` (u1 is the owner of the truck at the user scope)

RPfunction([`owner`], `user`) = [`drive`, `sell`] (u1 may drive, sell the truck t1)

`drive` exists in [`drive`, `sell`] = true (u1 may indeed drive the truck)

FAQ

What’s the meaning of global scope?

Global when referring to a RP it means the role may perform the said permission against all resourceIds of the given resource. When referring to the scope of a role it means all roles.

How do I define custom scopes?

Handle the scope in your implementation of `EntityScopeService` and `PrincipalRoleService`. Bind the scopes to the container. `authorization.test.ts` has a complete implementation of this.

May I use my own `PermissionService`?

Yes. Simply provide your own implementation and inject into the service.

For a principal, how do I represent a role that’s associated with multiple scopes?

Make sure the role is associated with the applicable scopes and scopeIds.

How do I allow one user access resources belonging to another user, another group?

  1. Define a new scope. For the targeted resources, add the assessor userIds. Give the assessor users the necessary permissions at the new scope. The same logic can be applied for organizations, teams etc.
  2. Share the resource. For the targeted resources, add the assessor userIds.

Well that’s it. You may find an implement of RPS in Typescript on Github and NPM. A in-depth example is provided in the test folder. Feel free to post any questions or concerns.

--

--

wa wang
wa wang

Written by wa wang

Wa is a former software engineer with primary focus in physics.

No responses yet