Modeling Authorization

Published on Oct 14, 2018

Most applications need to take care of authorization. Authorization is the answer to the question of whether a request is permitted or not. We will look at different models of authorization using a meta-model in this article. I am going to use Casbin for concrete examples. You can experiment with example model definitions using Casbin Model Editor.

PERM Meta-Model

An instance of PERM (Policy, Effect, Request, Matchers) describes how these four kinds of entities interact with each other to build something that can used for authorization. First let's describe each of these entities and then look at an example model built using them.

Request
Information about the access request. A simple request would be a tuple with the subject, action and the resource. A concrete request model can have resources such as physical hardware components like CPU caches or logical entities built out of persisted data like customers in a CRM system. r = {sub, action, resource}
Policy
A model of what can constitute a rule in the system, e.g., an administrator should be allowed to read user info. p = {sub, action, resource}
Matchers
A model of how requests and policies are matched. The simplest example would be using equality for matching requests and policies if the above models for those are used. m = r.sub == p.sub && r.action == p.action && r.resource == p.resource Given a request, a value is produced for every policy using this matcher expression. So, we have a p.eft value for every policy in our policy set. We haven't defined instances of policies yet. We have only defined how those instances would look like, i.e. the policy model.
Effect
A model for combining/reducing policies that match a given request to a final result. Value of evaluating the matcher expression is available in eft field in every policy. e = some(p.eft == allow)

The diagram below illustrates how a request is authorized using a model based on PERM.

perm.png

Model Definitions

Here is the complete model definition for ACL-based authorization:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

For such a model, the policies that define authorization rules will look like

p, alice, data1, read
p, bob, data2, write

If we wish to allow everything to the admin user, all we need to change is the definition of the matcher:

[matchers]
m = r.sub == admin || (r.sub == p.sub && r.obj == p.obj && r.act == p.act)

To enable simple attribute based access control, we need access to the actual data in the resource object. For example if we only want to allow requests which are initiated by the owner of the resource, the matcher expression would change to:

m = r.obj.owner == r.sub && (r.sub == p.sub && r.obj == p.obj && r.act == p.act)

The PERM meta-model is flexible enough to allow us to switch to complex authorization models even if we start with a simple model in the beginning. An extension of the PERM model would be to allow materialized views of the resource based on policies. This requires that the final result is a resource rather than a boolean value. This might seem like a good idea in the beginning but it seems to be mixing two different ideas:

  • Allowing access to a resource
  • Building an instance of a logical resource based on constraints or the context.

For example, let's say a hypothetical SaaS company needs to manage credits for multiple applications that register themselves on their platform (Ola credits, Uber credits). There can be a field in the User resource, say credits, which has a list of credits (logically) for all these applications. Now, we must ensure that credits for one application are not visible to any other application. All applications have access to all other fields but this field needs to be filtered. In my opinion, this field should have never been designed such that it ends up with data for all applications while building the User object/map/representation in memory. Share your thoughts about this in the comments below.

Conclusion

PERM is a flexible meta-model for building authorization models.