Authorization in Software Systems

As we know that, the concept of Autorization is simply checking if a verified user or application is allowed to do something.

It generally comes to authorization policies which would be checked to make this decision. The decision is simple, is person X allowed to access resource R ? This can be further broken up to Create, Read, Update, Delete Access.

There are multiple patterns to achieve access control in software systems. But generally, the idea is to filter out data that is only accessible to a user.

Here are two general strategies which can be applied generally to any kind of access control accordingly.

  1. To deny access unless a user is eligible
  • Convenient with higher restriction and for sensitive data.
  • Admin section can be generally denied access unless the user is an admin, deny by default makes more sense here.
  1. To allow access unless a user is not eligible
  • Convenient with less restriction to be applied and for less sensitive data.
  • Liking a post, everyone should be able to like a post but a user who already liked can’t like the post again.. we can allow likes but makes sense to deny it only if it is already liked.

Also, the authorization among different applications can have an advanced flow (OAuth), which enables different applications to access data or API of the main application on behalf of the user.

Let’s start with a single application with simple Authorization.

RBAC Implementation

Role-based access control is generally applied on higher levels, entry points such as specific APIs, directories, routes etc… It can be imagined like a real-life Offices with admin only section.

We can say RBAC generally implements Deny by default strategy (but it is not always the case). And here’s a very simplified representation.

adminDasboard {
    if user == admin {
        return AllowAccess
    }

    return AccessDenied.
}

ABAC Implementation

Attribute access control generally can be a check condition after allowing entry to a particular section.

We can say ABAC implements Allow by default strategy (again, not always the case). And here’s a very simplified representation,

updateMyProfile {
    if profile.user != user {
        return AccessDenied
    }

    return UpdateProfile where profile.user = user
}

Example: In an eCommerce web application, with Admin managing products and sales, Customers can purchase and view their purchase history, the public can see all products without a login

RBAC

  • We can enforce a rule that create, update, delete operation on the product is denied for all, except admin.
    • Therefore, before even checking any parameter we can block POST, PATCH, PUT, DELETE requests (any requests that allow create, update, delete) for the product management route, and only allow further if the requesting user is admin.
  • Only logged in users can purchase and view their purchase history
    • We can deny the public to access purchase and history, so a “login required” means the request must be from at least a role of Customer. the public would be having the role of an anonymous user in most cases.

ABAC

  • Purchase history should only be visible to the users which the purchase belongs to.
    • We can allow all customers to access the purchase history section but, we provide a condition while fetching the history list… we only Fetch purchase history where the customer of that purchase is the requesting user.
  • Updating profile information.
    • We can allow access to update profile route for all members but, we only allow the update if the profile belongs to the requesting user.