You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@incubator.apache.org by Upendra Jariya <up...@gmail.com> on 2016/05/23 07:30:18 UTC

[PROPOSAL] to accept BRBAC into the Apache Incubator

[PROPOSAL] to accept BRBAC into the Apache Incubator

= Abstract =

Pluggable, Scalable and Fastest possible approach for Role Based Access
Control (RBAC) based on binary arithmetic and basic Linux style permissions.

= Proposal =

BRBAC aims to become the default free, readymade and configurable access
control plugin for enterprise applications, spring-web like frameworks,
hadoop infrastructure and new era big data applications.

BRBAC is a very simple binary concept which can easily be implemented in
all programming languages and can be applied for access control in most
complex and simple permission scenarios. It may scale easily from single
user to lacks of users and from single entity to lacks of entities with
same performance.

A maximum of 3-5 classes with 20-30 lines of code are more than sufficient
to implement BRBAC in any enterprise application. Permissions need to be
stored separately as binary numbers (8 bit integers or bit-sets) on a per
entity, per user or per role basis.

Please visit wiki page for more details (
https://github.com/muktalabs/brbac/wiki)

= Background =

In enterprise applications, Access needs to be controlled where an
Operation is being performed on an Entity by an authenticated User. Hence,
access control in enterprise applications has some basic aspects

== User ==

Authenticated user has fixed set of permissions to perform certain
operations in an enterprise level application. Based on these permissions,
user is allowed or denied to perform various operations in the application.
Thus, permissions are always stored on a per user basis.

== Entity / Model ==

Generally, enterprise applications have many entity classes. Each entity
allows certain operations by some roles and denies certain operations to
some roles / users. To control this behavior, permissions also need to be
stored on a per entity basis.

== Operation / Action ==

CRUD = Create, Read, Update, Delete. Every entity in the application is
subject to the CRUD operations. There can be more operations but CRUD is
the most basic and most common set of operations. Since entities have
different behavior for different operations by different users, permissions
also need to be stored on a per operation basis.

== Role / Level ==

Another such aspect is Role. Each User has a Role in the system, based on
the role, he /she is assigned Permissions to perform Operations on
Entities. Common RBAC systems store permissions for a Role and each User is
assigned one or more Roles as per requirements.

== Context ==

If the entity is created by an admin level user, it should not be editable
/ deletable by lower permissions. Keeping it simple for now, we shall look
after context in the next version of BRBAC.

= Rationale =

An application needs to store and evaluate permissions on a per User, per
Entity and per Operation basis. Most of the times this data takes up-to 5
tables to store the RBAC permissions. Selecting permissions for user from
database also consumes time while user attempts to perform some operation.
Sometimes the time taken to check permission is more than time taken to
perform required operation. Thus the current approaches for RBAC seems
inefficient in TIME and STORAGE.

Now since databases are storing petabytes of data in raw binary formats
(hbase, cassandra) and applications are supporting hundred lacks of users,
if a big data application requires access control, the RBAC should also be
fast and scalable enough to support the volume and performance.

== How BRBAC works ==

Binary arithmetic is known for vast in scalability, smallest in memory and
fastest in speed. BRBAC uses separate bits to store permissions on User,
Entity and Operation level. Permission bits of User, Operation and Entity
are bitwise ANDed together to see if the operation is allowed or denied for
the user.

In BRBAC, long (8 bytes number) data type is used to store CRUD permission
bits on various levels / roles for Operations, User and Entities. Since
CRUD are 4 different operations, 1 hexadecimal number (4 bits) are used to
store permission mask for 1 role. If number of operations are more than 4,
a bigger number (6 bits or 8 bits) should be used to store permissions. To
keep it simple and manageable by hexadecimal numbers, we recommend to use 4
or 8 bits.

We are assuming 4 roles i.e. Admin, Supervisor, Operator and Guest which
seems sufficient for all general purpose applications… so 4 hexadecimal
numbers are used to store permissions e.g. 0x44EF. If number of Roles
increase, that many number of hexadecimal digits are also increased in
permission mask. If application has 8 roles, the mask would be e.g.
0x44ECCEFF.

== 1’s = permissive, 0’s = restrictive ==

More number of 1’s make BRBAC more permissive and more number of 0’s make
BRBAC more restrictive. Controlling the number of 1’s and 0’s at the
specific locations is the key point in management of BRBAC.

User’s permission mask 0x44EF or 0100-0100-1110-1111, provides this user
full access on guest level, Create, Read and Update access on Operator
level and Read access on Admin and Supervisor level. Thus this user becomes
an Operator level user who can read all Entities in the system.

By Entity’s permission mask 0xFEC4 or 1111-1110-1100-0100, this entity
allows full access to Admin level, Create, Read and Update access to
Supervisor level, Create and Read access to Operator level and Read only
access to the Guest level.

= Example =

An example of checking CRUD permissions is described below where User has a
permission mask of 0x44EF and entity has a permission mask of 0xFEC4:

== Create ==

Create action / operation has 1 on the 3rd bit and 0 on the remaining bits
of each hexadecimal digit. Thus, the action / permission mask becomes
0x8888 in hexadecimal or 1000-1000-1000-1000 in binary. When it binary
ANDed with User’s permission mask 0x44EF or 0100-0100-1110-1111, and
Entity’s permission mask 0xFEC4 or 1111-1110-1100-0100, it gives 1 on the
8th bit (0000-0000-1000-0000).

Since the result of binary AND is non zero, Create access is hereby granted
to the User for the Entity. Since highest 1 is seen on Operator level /
Role, the User can Create Entity as an Operator.

See example image (
https://github.com/muktalabs/brbac/blob/master/docs/brbac_concept_create.png
)

== Read ==

Read action / operation has 1 on the 2nd bit and 0 on the remaining bits of
each hexadecimal digit. Thus, the action / permission mask becomes 0x4444
in hexadecimal or 0100-0100-0100-0100 in binary. When it binary ANDed with
User’s permission mask 0x44EF or 0100-0100-1110-1111, and Entity’s
permission mask 0xFEC4 or 1111-1110-1100-0100, it gives 1’s on the 2nd,
6th, 10th and 14th bits (0100-0100-0100-0100).

Since the result of binary AND is non zero, Read access is hereby granted
to the User for the Entity. Since highest 1 is seen on Admin level / Role,
the User can Read Entity as an Admin.

See example image (
https://github.com/muktalabs/brbac/blob/master/docs/brbac_concept_read.png)

== Update ==

Update action / operation has 1 on the 1st bit and 0 on the remaining bits
of each hexadecimal digit. Thus, the action / permission mask becomes
0x2222 in hexadecimal or 0010-0010-0010-0010 in binary. When it binary
ANDed with User’s permission mask 0x44EF or 0100-0100-1110-1111, and
Entity’s permission mask 0xFEC4 or 1111-1110-1100-0100, it gives 0’s on all
the bits (0000-0000-0000-0000).

Since the result of binary AND is zero, Update access is hereby denied to
the User for the Entity.

See example image (
https://github.com/muktalabs/brbac/blob/master/docs/brbac_concept_update.png
)

== Delete ==

Delete action / operation has 1 on the 0th bit and 0 on the remaining bits
of each hexadecimal digit. Thus, the action / permission mask becomes
0x1111 in hexadecimal or 0001-0001-0001-0001 in binary. When it binary
ANDed with User’s permission mask 0x44EF or 0100-0100-1110-1111, and
Entity’s permission mask 0xFEC4 or 1111-1110-1100-0100, it gives 0’s on all
the bits (0000-0000-0000-0000).

Since the result of binary AND is zero, Delete access is hereby denied to
the User for the Entity.

See example image (
https://github.com/muktalabs/brbac/blob/master/docs/brbac_concept_delete.png
)

= Initial Goals =


   1.

   Initial goal is to create a simple Java maven project which can be added
   as a plugin to any maven project. Code for this plugin is 80% ready and has
   been tested for access control in our spring mvc applications. Some
   brainstorming and guidance is needed for deciding the project structure for
   an independent release.
   2.

   Next goal is to provide a simple API to configure the binary permission
   flags on User, Entity and Role levels. API needs to be provided to add and
   define new operations. A robust mechanism needs to be designed carefully
   where adding new permission flags does not corrupt the existing settings.
   3.

   Collaborative brainstorming is also needed to plan plugin based
   approaches for storage of binary permissions on per Entity and per User
   basis which can provide easiest integration with existing applications.


= Current Status =

A very basic POC level code is written, tested and open-sourced. This code
directly hard codes the permissions in complex hexadecimal format (e.g.
0xFFE4). Brainstorming and efforts are needed to simplify the configuration
of permissions so that API user does have to directly edit hexadecimal
codes.

== Meritocracy ==

We are open to collaborate with and respect the committers and we agree
that active committers should be members of project management committee
(PMC).

== Community ==

The need for Role Based Access Control in enterprise applications is
tremendous and lacks a universal default pluggable API thus providing the
potential for a large community

== Core Developers ==

The developers Upendra Jariya and Douglas Johnson are aged software
professionals, both having interest in open source community and both have
invested hard earned time in developing open source software.

== Alignment ==

Apache is the best suitable place for hosting BRBAC because all leading
open source projects already belong to Apache. We aim to propose BRBAC as
RBAC plugin to existing Apache projects including apache-commons,
spring-security, spring-web, struts, hadoop etc.

= Known Risks =

API need to be carefully designed to define and modify the permissions.
This API should support migration from present to future versions of BRBAC
without loss of functionality.

Since the storage will be binary and disjoint, adding new Roles or New
Operations should not impact existing Roles / permissions of the
application by giving or denying access to the wrong User.

== Relationships with Other Apache Products ==

BRBAC will likely be used by apache-commons, spring-security, spring-mvc,
struts, hadoop and will support Apache commons logging.

= Documentation =

Project documentation is available on wiki page at:
https://github.com/muktalabs/brbac/wiki

= Initial Source =

Source code for BRBAC is available online @
https://github.com/muktalabs/brbac under open source Apache 2.0 license.

It requires very less code to integrate BRBAC into any existing or new
application. For the sake of illustration, some important code snippets are
as following:

== Crud Action ==

There can be 100 ways to store action / operation codes. We have chosen
enum as per suitability in our application.

package com.muktalabs.brbac;

public enum CrudAction {



    CREATE   (0x8888),

    READ     (0x4444),

    UPDATE   (0x2222),

    DELETE   (0x1111),

    DISABLED (0x0000);



    private final long mask;

    CrudAction(long mask){

       this.mask = mask;

    }



    public long getMask() {

       return mask;

    }



    public static CrudAction get(String straction) {

       if(straction == null){

           return DISABLED;

       }

       switch(straction.toUpperCase()) {

       case "CREATE" :

           return CREATE;

       case "READ" :

           return READ;

       case "UPDATE" :

           return UPDATE;

       case "DELETE" :

           return DELETE;

       case "DISABLED" :

       default :

           return DISABLED;

       }

    }

}

== Entity ==

For easiest implementation, we have directly associated different
permission mask to each Entity using  annotation. Since Entity’s permission
mask does not change in most general cases, Annotation fits best in most
requirements.

import com.muktalabs.brbac.CrudPermission;

@CrudPermission(permission=0xFEC4)

public class Employee extends Model

{

}

== Crud Permission ==

This is the source code for customized @CrudPermission annotation. This
annotation has a default value of 0x4444 i.e. by default, the entity allows
Read access to all the Users. The permission attribute can be overridden
for each entity by @CrudPermission(permission=0xFEC4)

package com.muktalabs.brbac;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE) //on class level

public @interface CrudPermission {



    long permission() default 0x4444; // Read permission to all



}

== Base Controller ==

In most enterprise web applications, controllers are used to check login
and check access permissions. This BaseController is the base class of all
Controllers which defines the checkPermission method. This
checkPermission() method need to be invoked from all controller methods.
Aspect pointcuts can also be used to make a call to checkPermission method.

package com.muktalabs.brbac.controller;

import java.util.logging.Logger;

import com.muktalabs.brbac.CrudAction;

import com.muktalabs.brbac.CrudPermission;

import com.muktalabs.brbac.model.Model;

import com.muktalabs.brbac.model.User;

public class BaseController {

    private static final Logger logger =
Logger.getLogger(BaseController.class.getName());

    public boolean checkPermission(Class<? extends Model> entity,
CrudAction action, User user)

           {

       CrudPermission entityPerms =
entity.getAnnotation(CrudPermission.class);

       // Get permissions on entity

       long entityMask = entityPerms.permission();

       // Get permissions for user

       String userPermStr = user.getPermission();

       long userPerm = Long.decode(userPermStr);

       // Get permissions required to perform the action

       long actionMask = action.getMask();

       // Binary AND the 3 Masks

       long result = entityMask & userPerm & actionMask;

       // Done. If result is non-zero, user has the permission

       if (result > 0) {

           // TODO: Context: Here, in case of update/ delete, if saved
entity has

           // greater roleMask, than current user's roleMask, do not allow.

           // Scale: Also use 0xFFFF000000000000 format.

           return true;

       } else {

           throw new RuntimeException("Insufficient priviliges to perform
this operation. "

                   + "Please contact your system administrator.");

       }

    }

}

= Source and Intellectual Property Submission Plan =

The initial source code is already available in Apache 2.0 license on a
github public URL. Still, if separate IPR submission is required, we will
follow the instructions from Apache Incubator.

= External Dependencies =

NONE as of now.

= Required Resources =

== Mailing lists ==

private@brbac.incubator.apache.org

dev@brbac.incubator.apache.org

commits@brbac.incubator.apache.org

users@brbac.incubator.apache.org

== Git Repository ==

https://git-wip-us.apache.org/repos/asf/incubator-brbac.git

== Issue Tracking ==

JIRA: Apache BRBAC (BRBAC)

== Wiki ==

Confluence: Apache BRBAC (BRBAC)

= Initial Committers =

Upendra Jariya (upendra dot jariya at gmail dot com),

Douglas Johnson (doug4j at gmail dot com),

Gourav Dodia (gouravkumardodia at gmail dot com)

Willing developers are most invited to participate in BRBAC development

== Affiliations ==

None as of now.

= Sponsors =

== Champion / Mentors ==

Yet to be searched for, will start searching after initial project
acceptance.

== Sponsoring Entity ==

Mukta InfoTech (www.muktainfotech.org)

Clyrity (www.clyrity.com)

Apache Incubator is requested to take the sponsorship of this project.


Thanks & Regards,

*Upendra Jariya <https://in.linkedin.com/in/upendrajariya>*
Freelance Consultant,
*Mukta InfoTech* <http://www.muktainfotech.org/>
Email: upendra.jariya@gmail.com
Phone: +919406614355