Is one XACML file per user a good approach?

103 views Asked by At

Scenario:

I'm developing a custom PAP for WSO2 IS 5.0.0. I have simple rules to administrate such as:

The user Bob can read Orders of branch XYZ?

The user Bob can create Invoices of branch PTO?

I'm thinking to write one Policy per user with many rules, each rule containing the resource and action as target and testing branch and user in conditions.

Here is an example:

<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="UserPolicy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
   <Target></Target>
   <Rule Effect="Permit" RuleId="Rule-User-1">
      <Target>
         <AnyOf>
            <AllOf>
               <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match">
                  <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">/api/Orders/*</AttributeValue>
                  <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
               </Match>
               <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                  <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">GET</AttributeValue>
                  <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
               </Match>
            </AllOf>
         </AnyOf>
      </Target>
      <Condition>
         <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
               <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"></Function>
               <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">[email protected]</AttributeValue>
               <AttributeDesignator AttributeId="http://wso2.org/claims/emailaddress" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
            </Apply>
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
               <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
                  <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"></Function>
                  <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">XYZ</AttributeValue>
                  <AttributeDesignator AttributeId="branch" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
               </Apply>
               <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
                  <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"></Function>
                  <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">PTO</AttributeValue>
                  <AttributeDesignator AttributeId="branch" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
               </Apply>            
            </Apply>
         </Apply>
      </Condition>
   </Rule>
   <Rule Effect="Permit" RuleId="Rule-User-2">
            <Target>
         <AnyOf>
            <AllOf>
               <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match">
                  <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">/api/Orders/*</AttributeValue>
                  <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
               </Match>
               <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                  <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">POST</AttributeValue>
                  <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
               </Match>
            </AllOf>
         </AnyOf>
      </Target>
      <Condition>
         <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
               <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"></Function>
               <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">[email protected]</AttributeValue>
               <AttributeDesignator AttributeId="http://wso2.org/claims/emailaddress" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
            </Apply>
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
               <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
                  <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"></Function>
                  <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">PTO</AttributeValue>
                  <AttributeDesignator AttributeId="branch" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
               </Apply>            
            </Apply>
         </Apply>
      </Condition>
   </Rule>
   <Rule Effect="Deny" RuleId="DenyRule-User"></Rule>
</Policy>        

Problem:

As we see above, for one permission question I have too many lines. I'm working with an ERP system and it can have many resources (APIs) and an user can have many branches in it context to access. I think with this approach of one file per user I'll have big files and I don't know if it could cause bad performance to PDP and to my ERP as well.

Question:

Someone see here a better approach?

1

There are 1 answers

0
David Brossard On BEST ANSWER

No, it's not a good approach.

You are using XACML as you would an ACL or an RBAC system. Instead you want to model your authorization in terms of higher-level policies.

Your requirements are:

The user Bob can read Orders of branch XYZ?

In this example, why can Bob read orders in branch XYZ? Does the user belong to that branch? In other words, what the authorization logic? For instance, would the following be an adequate rewrite?

A user with the role == manager can do the action == view 
on a resource of type==order if order.branch == user.branch.

The rewrite scales better because it works for any user, any order, and any branch.

The user Bob can create Invoices of branch PTO?

Similarly you could rewrite this example as follows:

A user with the role == purchase manager can do the action == create 
on a resource of type==invoice if order.branch == user.branch.

What I have done is identify the building blocks (or attributes) in your requirements and rewritten your requirement as an authorization rule. From there on, you can choose to implement the rule using ALFA (). If you use the ALFA plugin for Eclipse, the result will be converted on the fly to XACML 3.0.

This is what it looks like in the Axiomatics Policy Server:

Axiomatics Policy Server - Policy Editor

I hope this helps, David.