Sorry, the language specified is not available for this page

    Porper (Portable Permission Controller) – RBAC Library for Microservices

    January 23, 2017

    PORPER - Portable Permission Controller, an RBAC Library for Microservices

    Thanks to serverless frameworks like AWS Lambda, Google Cloud Function and Azure Functions, applications implemented as microservices are growing rapidly.  However, because microservices frameworks are still evolving, there are a few parts missing that would make development as easy as developing applications using existing frameworks.

    One of the missing microservice frameworks is how to manage the permissions/privileges by users/groups. When implementing applications using existing frameworks, you can use the modules that the frameworks provide, however they are not available when you implement applications using serverless computing. Managing permissions and privileges based on Role Based Access Controller (RBAC) is not straightforward and is difficult to architect. To fix this, I developed a simple module called Porper for use when developing serverless applications. Porper is a very simple RBAC  library that manages user permissions based on their privileges.

    The Porper module is based on python 2.7 and stores data in a MySQL database. To use Porper, first you must create a database in MySQL server. Once created, please follow the steps below which will populate the database using the initial data and set up the demo environment:

    • Clone this project,
    • Import the data in ‘porper_initial.sql’ which will populate
      • Tables for users/roles/permissions and other resources
      • Administrator role, ‘admin’, which is an administrator group (You may think the role as a group/department/company)
    • Install the Porper library using pip
      <span style="font-weight: 400;">pip install porper [-t .]</span>
    • Set the environment variables with your new database information
      <span style="font-weight: 400;">export MYSQL_HOST=&lt;database_host&gt;</span><span style="font-weight: 400;">export MYSQL_USER=&lt;databse_user&gt;</span><span style="font-weight: 400;">export MYSQL_PASSWORD=&lt;database_password&gt;</span><span style="font-weight: 400;">export MYSQL_DATABASE=&lt;database_name&gt;</span>

    Now, to start, execute the command below to run ‘’ python file.

    <span style="font-weight: 400;">python</span>

    This command will setup the demo environment with executing below steps so that you don't need to do them manually.

    Get the connection to the 'porper' database

    • Create the first user, ‘admin’, who is the administrator and belongs to the ‘admin’ role
    • Simulate the login by the ‘admin’ user for authentication. (You can use Google+ and GitHub authentication using their OpenID connect. Please see Porper-API and Porper-UI projects for more detail)
    • Create a new role, ‘demo’
    • Invite a user so that the user can login to the system (Because this system is based on the authentication using Google+ and GitHub accounts, you need to invite users to be added. After invited, the users will be automatically added to this system once they successfully authenticate using their Google+ or GitHub accounts for the first time)
    • Simulate the login by the ‘demo’ user for authentication
    • Create a table for a sample resource, ‘demo’

    Once the script successfully completes the setup of the environment for demonstration, it’s time to dive into how the Porper library works. I already created the controller and model classes to manage the sample resource, demo (which are ‘’ and ‘’).

    ‘DemoController’ inherits from the ‘ResourceController’ in the Porper library and provides interfaces to ‘create’, ‘read’, ‘update’ and ‘delete’ instances. To make this demo simple, ‘DemoController’ only re-defines the ‘create’ interface to give permissions of ‘read’, ‘update’ and ‘delete’ on the newly created instance to the creator once the instance is successfully created. You can add/remove any permissions you need later.

    As you see in ‘’, it implemented the ‘create’ method and it calls ‘add_permission’ method once a new instance is created as below.

    def add_permissions(self, id, user_id):

    from porper.controllers.permission_controller import PermissionController    permission_controller = PermissionController(self.connection)    # give       read/update/delete permissions to this user    user_permission_params =


    "user_id": user_id,

    "resource": self.resource,

    "value": '%s' % id


    user_permission_params["action"] = "read"

    permission_controller.create(None, user_permission_params, user_id)

    user_permission_params["action"] = "update"

    permission_controller.create(None, user_permission_params, user_id)

     user_permission_params["action"] = "delete"

    permission_controller.create(None, user_permission_params, user_id)

    Let’s try to create a new instance of the ‘demo’ resource using python commands after getting the connection to the 'porper' database. We’re using the ‘admin_access_token’ to use the ‘admin’ session, which was created during environment setup.

    $ python

    >>> from porper.models.connection import mysql_connection

    >>> connection = mysql_connection()

    >>> from demo_controller import DemoController

    >>> from demo_controller import DemoController

    >>> demo_controller = DemoController(connection)

    >>> admin_access_token = 'ffffffff-ffff-ffff-ffff-ffffffffffff'

    >>> demo_create_params = { "id":"1", "name":"first", "description":"first instance" }

    >>> demo_controller.create(admin_access_token, demo_create_params)

    Exception: not permitted

    As expected, it will raise an exception of ‘not permitted’ because we didn’t give the permission to create a new instance of ‘demo’ resource to the ‘admin’ user. So, let’s give the ‘create’ permission to ‘admin’ user. (We’re assigning ‘*’ for ‘value’, which allows all instances of the resource because no instance id is available for the instances to be created)

    >>> from porper.controllers.permission_controller import PermissionController

    >>> permission_controller = PermissionController(connection)

    >>> admin_user_id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'

    >>> permission_params = {

    "user_id": admin_user_id,

    "resource": "demo",

    "value": "*",

    "action": "create"


    >>> permission_controller.create(admin_access_token, permission_params)

    >>> connection.commit()

    Now, try again adding a new instance of ‘demo’ resource.

    >>> demo_controller.create(admin_access_token, demo_create_params)

    >>> connection.commit()

    Now, the admin user created an instance of 'demo' resource with no exception. Once a new instance is created successfully, try retrieving the instance to confirm the creation.

    >>> demo_find_params = { "id":"1" }

    >>> demo_controller.find_all(admin_access_token, demo_find_params)

    [{'description': 'first instance', 'id': '1', 'name': 'first'}]

    You may wonder how the ‘find_all’ method successfully retrieved the target instance because we didn’t give the ‘read’ permission to this user. The reason is because ‘read’ access was granted right after the instance is created in ‘add_permissions’ method inside the ‘DemoController’ as shown above.

    Now let’s try to retrieve the same instance using another user other than the ‘admin’. We created an additional user, ‘’, during the demo environment setup. First, find the ‘id’ of the user, ‘’.

    >>> from porper.controllers.user_controller import UserController

    >>> user_controller = UserController(connection)

    >>> user_find_params = { "email": "" }

    >>> user_info = user_controller.find_all(admin_access_token, user_find_params)

    >>> user_id = user_info[0][ "id"]

    Next, simulate the login by the user for authentication.

    >>> from porper.controllers.token_controller import TokenController

    >>> token_controller = TokenController(connection)

    >>> user_access_token = 'ffffffff-user-ffff-ffff-ffffffffffff'

    >>> user_refresh_token = 'ffffffff-user-ffff-ffff-ffffffffffff'

    >>>, user_refresh_token, user_id)

    >>> connection.commit()

    Now, try finding the newly created first demo instance using the session of ‘’ user.

    >>> demo_controller.find_all(user_access_token, demo_find_params)

    Exception: not permitted

    As you may expect, it will raise an exception of ‘not permitted’ because this user was not granted access to read that instance. So let’s give the ‘read’ permission to this user. You have to use ‘admin_access_token’ because this user doesn’t have a permission to grant permissions.

    >>> permission_params = {

    "user_id": user_id,

    "resource": "demo",

    "value": "1",

    "action": "read"


    >>> permission_controller.create(admin_access_token, permission_params)

    >>> connection.commit()

    Let’s try again to find the newly created demo instance using this users session. As you’ll see, this user now can retrieve the instance.

    >>> demo_controller.find_all(user_access_token, demo_find_params)

    [{'description': 'first instance', 'id': '1', 'name': 'first'}]

    So far, I explained the very basic features of the Porper library to control the access to resources based on user roles. Please see the main repository for this library, Porper-Core, for additional  features. Using this library will make it easy to implement resource management by just granting/revoking appropriate permissions to users and their roles.

    You can also choose the RESTful interfaces implemented in Porper-API project, which is built using AWS Lambda and API Gateway along with supporting OpenID authentication using Google+ and GitHub accounts. In addition, please check out the Porper-UI project, which present a basic ReactJS UI application that interfaces with Porper-API to manage a sample resource with Google+ and GitHub authentication.


    Other Posts You Might Be Interested In

    CodeBuild, CodeDeploy and CodePipeline Quick Start Guide to go from Development to Production

    In this guide, I will give you a quick but complete example to create a development to production Continuous Deployment (CD) or Continuous Delivery (CD) pipeline. I want you... Learn More

    Application Authentication Using Amazon Cognito and An Introduction to Key APIs

    All web applications and mobile applications need a way to register or sign-up users and require a secured and robust mechanism to sign-in (login) users to authenticate into... Learn More

    Journey Through a Proof of Concept Application Development Using AWS Cloud Services

    I recently had the opportunity to develop a Proof of Concept (PoC) for an idea whereby data is available from PDFs and Excel files to be consumed and analyzed into a... Learn More