+
2023 State of Authorization Report offers guidance on critical issues impacting authorization Learn more  

Should I Define the Authorization Logic in the Policy or an External Datasource?

There are different approaches to expressing authorization logic. What’s the best way? It’s not as simple as the right or wrong way in this case unfortunately. Let’s take a look at the pro’s and con’s of the more typical approaches we see here at Axiomatics when we work with our customers.

All (or most of) the logic in the policy

In this case we’re obviously talking about the XACML policy. This is an Attribute Based Access Control (ABAC) approach that leverages attributes and policies to make runtime authorization decisions.

Defining the authorization logic in the policy itself means that all aspects of the XACML authorization policy language can be leveraged. A well structured policy can be authored such that it’s easy to understand by simply looking at the policy itself.

An example expressed in ALFA could look something like this:

policyset financial{
  apply firstApplicable
  //Note, no target defined. Always enter the global policy

  /* Policy for transactions */
  policy transaction{
    target clause resourceType=="transaction"
    apply firstApplicable

    /*Rule defining view access
    Anyone can view */
    rule view{
      target clause action=="view"
      permit
    }

    /*Rule defining approve access
    * Only managers can approve if the transaction belongs to the
    * same department as the user */
    rule approve{
      target clause action=="approve" and user.role=="manager"
      condition transaction.department == user.department
      permit
    }
  }

As you can see it’s very easy to read what the policy actually achieves and what the needed attributes and building blocks in order to reach a decision are.

Obviously the Policy Decision Point (PDP) that has this policy loaded might need policy information points (PIP) configured in order to resolve some of the attributes used in the policy. We typically find that these are already available within the organization as they are attributes that are already in use. They could come from the directory where users are defined or a database where transactions (in our example) are stored.

The policy is not only human-readable, it’s also a policy structured in such a way that the Axiomatics Reverse Query (ARQ) authorization engine can read it and generate understandable responses based on the request and the policy. If we consider the above policy and then consider these pseudo authorization requests it should give an idea what an ARQ request and response could look like.

  • Question: Can Alice view transaction tr123?
  • Answer: Permit
  • Comment: All users can view all transactions according to the policy

Here’s another example:

  • Question: Can Bob approve tr123?
  • Answer: Unknown
  • Comment: By just looking at the policy and the request. The role, transaction and user department attributes are needed in order to get to a decision. If the role=manager and user.department=dept67 and transaction.department=dept67 then the decision would be Permit.

An open ended authorization request (suitable for ARQ) could look something like this:

  • Question: What transactions can Bob approve?
  • Answer: Transactions in department dept67
  • Comment: assuming Bob is still a manager and still belongs to department detp67, then he can also approve all transactions for that department. This is fairly easy to also determine from looking at the policy.

However, it should be noted that when moving towards an ABAC architecture from for example RBAC. Much of the access definitions already exists somewhere. They might already be defined in a database or a directory somewhere and are ready to be used. In such case there might be additional work to define the policy in a new way (the ABAC way).

Pro’s and Con’s

  • Human readable policy
  • Works well with ARQ
  • Simple PIP configurations that are clear
  • Possible need for redefining data structures
  • Additional policy work up-front

Define the logic in underlying data sources

Let’s look at the complete opposite scenario where almost all of the logic for access is defined in a data source.

Underlying data sources, also known as Policy Information Points, or in short PIP. This is a data source that the PDP leverages at run-time to resolve attribute data.

It is definitely possible to define the actual access in an underlying data source. This is basically what is referred to as an Access Control List (ACL) where the different resources, the subjects (users) and the type of access they have is defined in a table.

Example of an ACL. Let’s call this the TR_access_table for future reference. 

ResourceId

User

Permission

tr123

Alice

View

tr124

Alice

View

tr125

Alice

View

tr123

Bob

View

tr123

Bob

Approve

tr124

Bob

View

tr125

Bob

View

tr123

Carol

View

tr124

Carol

View

tr125

Carol

View

tr125

Carol

Approve

In this example we’re missing the details of the user’s role, the department of the user and the department of the resource (transaction). However there is enough information here to determine if a user is allowed to view and/or approve a given transaction.

Here’s a policy example in ALFA notation where all of the logic is expressed in a PIP:

policyset financial1{
  apply firstApplicable
  //Note, no target defined. Always enter the global policy
 
  //Policy for transactions
  policy transaction{
    apply firstApplicable //Note, no target defined.

    //Rule allowing access if hasAccess is true
    rule access{
  &nb sp;   target clause hasAccess==true
      permit
    }
  }
}

The key attribute that basically controls all access here is the hasAccess attribute. So what would the definition of resolving that attribute look like in a PIP? Let’s look at what it could be implemented as using a SQL PIP and use the table above that we’d implemented. 

The request would be similar (or the same even) to the previous example where most of the logic would be implemented in the policy. Something like “Can Alice view transaction tr123?”

The request would probably be broken out to include a couple of key attributes:

  • User=Alice>
  • Action (permission) = View
  • ResourceId=tr123 

A SQL PIP can use these key attributes and configured so that the hasAccess attribute is fetched from the SQL database by defining the SQL query as follows:

SELECT ‘TRUE’ FROM TR_access_table WHERE User=’Alice’ AND Permission=’View’ AND ResourceId=’tr123’;

With this the SQL PIP would populate the attribute hasAccess with the value TRUE based on the first row in the TR_access_table and the 3 key values that the PIP is using. Thus in the end we get a Permit decision.

However note here that although we can see in the policy that if hasAccess==true the decision is going to be Permit and we really can’t determine why that’s the case. In fact even if we look at the policy and the TR_access_table table we can’t really see why. Why is it that Bob has the Approve permission for tr123 but not Alice? We can only see that it’s defined like that but someone must have ultimately made the decision at some point and then defined that into the ACL. 

The ARQ query in this scenario also becomes very interesting since ARQ can only see one attribute in the policy. So regardless the ARQ responses would basically say that if hasAccess is true then access is permitted without knowing how hasAccess would get the true value that doesn’t really help much. 

It should be noted that ACL-like definitions in underlying data sources can sometimes be useful. One such case is where there are hierarchical relationships between subject or resource attributes. It might be easier to define that hierarchical relationship in for example a database table and have the PIP resolve that rather than trying to fully implement that within the policy itself.

Pro’s and Con’s

  • Re-use existing access definitions (ACL’s)
  • Can handle some scenarios well, such as hierarchy for example
  • Doesn’t work with ARQ
  • Very complex PIP configurations
  • Very difficult if not impossible to understand the underlying reason for access

Conclusion

There is no exact right or wrong way here. The different approaches at hand have their own pro’s and con’s and to add to that it’s possible to combine them into a hybrid approach where some of the logic is in the policy and some is externalized to a data source. It all depends on what data that’s already in systems available and what type of authorization use cases that are being implemented. When moving from an already existing environment where much of the logic is already defined in an external data source it could be easy to start with that approach. We see that on a regular basis and can work with that. But in the majority of cases we strongly recommend to express the authorization logic in the policy itself. The pro’s of this approach outweighs the cons and managing and maintaining a structured authorization system becomes easy. This approach also helps bring out the power of leveraging the ARQ capability fully.

Archived under:
  Join us on LinkedIn for more insights
About the author