Search code examples
authorizationaccess-controlxacmlabacbalana

XACML 3.0 and Multiple Resources


I'm trying to figure out how to implement an authorization mechanism using Balana's XACML implementation (WSO2's entitlements engine is based on Balana).

When a user is requesting access for a single resource (for example, bob wants to read a medical record), things are straightforward.

However, let's say bob wants to read all his patients' medical records. The first issue here is that there needs to be a way to figure out who are his patients. I also need to get attributes for his patients' each individual record. The thing is, I'm trying to sort this situation out while keeping the number of requests for attributes to my PIPs to a minimum.

To rephrase what I'm aiming for: I am trying to evaluate whether Bob has access to multiple medical records (the records are unknown at the time the decision request is created) based on attributes returned by the PIPs (and I want my PIPs to have as few interactions as possible with the database, for example).

In a nutshell, what I've discovered is that when attempting to control access to a collection of resources with XACML, things get tricky.

I have found a few options here:

  1. My request contains the subject, action, resource ID and scope. I use XACML Multiple Decision profile: the PDP knows that children/descendant resources are targeted, so it will create multiple Evaluation contexts, for each child/descendant (but the attributes of the resources have not been found). Then, using the PIPs, it will retrieve attributes for each individual evaluation context (for example, get bob's doctor ID, then get the doctor ID of each individual resource). If, for example, my PIP is querying the database, it will perform a lot of queries for each individual attribute for each individual request, so there is a heavy impact on performance.

  2. My request contains the subject, action, resource ID. I no longer use the Multiple Decision profile. However, before creating the evaluation context and asking the PDP evaluate my requests, I know that my resource is actually a collection so I somehow get all children/descendants and all their attributes and only after I have all this information, I manually create individual decision requests for each child/descendant, and stuff in there all corresponding attributes. So I'm giving the PDP a fat decision request, that contains almost all necessary attributes. Because decision requests have almost all attributes in the evaluation context, there is no need for my PIPs to be interrogated. The advantage here is that i got all my information before the PDP evaluates the decisions, so the work that the PIPs have to do is kept to a bare minimum. However, I'm not sure whether I'm supposed to find the children/descendants and all their attributes before reaching the PDP (somewhere in the Context Handler, as the XACML spec says).

  3. My request contains the subject, action, resource ID. I use the Multiple Decision Profile. I have a component that can find Children/Descendant resources, and some PIPs. All these components use a repository, which hypothetically is called MedicalRecordsRepository. This repo, when requesting children/descendant IDs, also gets all attributes from the database and stores all this information in a cache. So afterwards, when having multiple evaluation contexts that are evaluated individually, if the PIP is requested to return an attribute, it will get the attribute from the repo's cache. So, database interaction is kept to a minimum. However, the problem is the repository component and its cache.

I have read the specs, I dug around, but I have not found any solution to this problem yet. Does anyone have any ideas? Thanks in advance!


Solution

  • In a nutshell, what I've discovered is that when attempting to control access to a collection of resources with XACML, things get tricky.

    You are right. XACML addresses transactional and functional access control well. It does not handle data access control so well.

    • transactional access control: Can Alice view medical record #1?
    • functional access control: Can Alice view medical records?
    • data access control: Which medical records can Alice view?

    I am not sure I fully grasp your three approaches but you do highlight the relevant problems namely

    • not knowing how many items there are
    • retrieving attributes from an external attribute source (imagine 10 attributes per medical record multiplied by 1,000,000 records - thats 10M lookups)

    In my experience, multiple decision profile requests work well when you are in the thousands of requests. Beyond that, I would consider Axiomatics Reverse Query (disclaimer - I work for Axiomatics). The Reverse Query addresses your problem by exposing an API that lets you ask open-ended questions such as

    • Which medical records can Alice view?

    The response will be the set of conditions that must be met. For instance if the following is your policy (using ALFA notation):

    XACML Policy using ALFA Notation

    policy accessMedicalRecord{
        target clause com.axiomatics.examples.actionId == "view" and objectType == "medical record"
        apply firstApplicable
        /**
         * Doctors can view medical records of patients they are assigned to
         */
        rule allowRegularAccess{
            target clause user.role == "doctor"
            condition patient.assignedDoctor == user.identifier
            permit
        }               
    }
    

    Sample ARQ Request / Response

    • Request: Which medical records can Alice, the doctor, view?
    • Response: Permit if patient.assignedDoctor == "Alice"

    The answer can be translated into a query language e.g. SQL:

    • SELECT id FROM MED_RECORDS WHERE assignedDoc = 'Alice';

    It could be another query language too. You then use that to query the source of the data e.g. a SQL Database and retrieve the relevant medical records.

    See also this Stackoverflow Q&A.