Search code examples
securityxacmlabac

ABAC PIP Attributes Request


How shall PIPs resolve correct attribute values? Which kind of interface should it have to be able to resolve the attribute value? For example, I need to get user roles and in this case I just need to pass an attribute for the user id. Let's now make this task more complicated. What if I have context under which user role might be changed, so a single user id is not enough here. In this case, I need to pass the access level for which we are trying to get the user role.

So on this example we can see, that interface will change every time, and the only suitable one will be that accepts everything.

How are PIP usually implemented in this case?

Update

Example: We have the following hierarchy:

Level 0           1          2
Organization < tenants < documents.    

Symbol < means right is a child of the left operand.

User might have role admin or user on each level. If user has admin role on level n then he is able to access anything on this level and level n+1,n+2,n+3.... In the same time user will have role user on all levels n-1, n-2, n-3....

Example:

    user        admin      admin
Organization < tenants < documents

This is the first part. The second part of it is about documents. Let's say, we have a few attributes such as publicTenant and publicDocument. Resolution of each other on different levels are not relevant and also requires knowledge not only of the userId but also the level on which we are working and resource attributes like organizationId, tenantId and documentId to resolve correctly not only role of the user, but also resource attributes.

How can this be implemented correctly in ABAC? Current solution is hybrid with ACL/RBAC/ABAC. ACL and RBAC are hidden under ABAC and used as attributes of subject, but this doesn't feel right.


Solution

  • The following approach is based on XACML model. If you need a solution that better handle cases where some of the resource attributes are missing from requests, let us know. I can update my answer, but the solution is more complex since it adds more checks for empty/undefined attributes.

    I use a simplified syntax but you can easily translate to XACML with these few conventions:

    • If the Target is not mentioned for a Policy(Set) or Rule, it means it is empty (applies to any request).
    • In the example, predicates like if attribute x = 'XXX' translate to a XACML Target /AnyOf/AllOf/Match with MatchId='string-equal', AttributeValue 'XXX' and the corresponding AttributeDesignator for attribute x.
    • Subject (resp. resource) attribute identifiers are prefixed with subject. (resp. resource.).
    • The policy/rule combining algorithm is implicitly set to deny-unless-permit everywhere.

    The PolicySet would look like this:

    • PolicySet 'root'

      • Policy 'Organization Level'

        • Rule 'Admin Role': Permit if subject.organization-level-role = 'Admin'
        • Rule 'User Role': Permit if subject.organization-level-role = 'User' and ... other conditions to restrict what the User role can do at organization level ... (if too complex to fit in a Rule, you can change these Rules to Policies and the enclosing Policy to a PolicySet)
      • Policy 'Tenant Level'

        • Rule 'Admin Role': Permit if subject.tenant-level-role = 'Admin'
        • Rule 'User Role': Permit if subject.tenant-level-role = 'User' and ... other conditions to restrict what the User role can do at tenant level ... (if too complex to fit in a Rule, you can change these Rules to Policies and the enclosing Policy to a PolicySet)
      • Policy 'Document level'

        • Rule 'Admin Role': Permit if subject.document-level-role = 'Admin'
        • Rule 'User Role': Permit if subject.document-level-role = 'User' and ... other conditions to restrict what the User role can do at document level ...

    For this to work, you would need to implement one or more PIPs to resolve the following subject attributes (you could do everything in one PIP, especially if all the user roles are managed by the same system, it's up to you):

    • subject.organization-level-role: organization-level subject roles; to get this, the PIP requires the following attributes as input: subject.userId, resource.organizationId
    • subject.tenant-level-role: tenant-level subject roles; to get this, the PIP requires the following attributes as input: subject.userId, resource.organizationId, resource.tenantId
    • subject.document-level-role: document-level subject roles; to get this, the PIP requires the following attributes as input: subject.userId, resource.organizationId, resource.tenantId, resource.documentId.

    A few comments on the PIP implementation:

    • The PIP(s) may return an empty bag for each of these, if the subject does not have any role assigned at the corresponding level.
    • If the cost to fetch the user roles from the role management system is high, the PIP could be optimized by getting all of them at once (at all levels) from the role management system, the first time one of the subject attributes above is requested during the policy evaluation, then keep it in cache, and return from cache when another one of these subject attributes is requested. A lot of caching optimizations is possible here.