Search code examples
xacmlxacml3xacml2

How to deal with scoped roles when multiple roles can be activated in XACML


First the user can have multiple roles at the same time, and the role has scope. For example, one user has three roles: /scopeA/editor, /scopeA/programmer, /scopeB/editor

and /scopeA/editor has access to resource /scopeA/post /scopeA/programmer has access to resource /scopeA/bug

/scopeB/editor has access to resource /scopeB/post

so the question comes:

how can i declare a policy saying: if there is a role named "/XX/editor" in the role bag, then the corresponding user has access to "/YY/post", when "XX == YY"

I found a similar question here, and i proposed a way to solve the problem, but when it comes to multiple role(the role attribute value is a bag), my answer is not right. Because the role attribute value is a bag, I cannot just get the part between the first two slashes of the role attribute value, and compare to that of the resource attribute,

then i tried to find a higher-order bag function to do this, the "urn:oasis:names:tc:xacml:3.0:function:any-of" function can do this, but what about the first "function argument" of the any-of function?

here is what i do: the first argument of the any-of function is "string-equal", and the second argument is a function used to get the part between the first two slashes of the resouce-id, the third argument is the attribute value of the subject which is a bag.

so all i need to do is to define a function to get the part between the first two slashes, right?

is there a better way to do what i want? if anything is unclear, plz let me know, thanks~~


Solution

  • This is a great question. We call this issue the attributes of relations challenge. Essentially, a user has a role within a given context or scope as you call it.

    If I read a user's role from the db based on the user's identity only, then I would get back the list of roles independently of the scope e.g. editor, publisher, reviewer...

    This would lead to the risk I could edit a post outside the scope for which I have the right role.

    There are several ways to solve this issue. One way is to define stricter mappings in your policy information point.

    Using Policy Information Points

    Assume that the XACML request says: "Can Alice edit post 123?". Your policy would state (in ALFA syntax):

    policy editPost{
        target clause resourceType=="post" and actionId=="edit"
        apply firstApplicable
        rule allowEditors{
            target clause userRole=="editor"
            permit
        }
    }
    

    The notion of scope doesn't directly show up in the policy. The underlying mapping to the source of attributes would be as follows:

    • map userRole to the field role of the table usersRoleAssignment using SELECT role FROM usersRoleAssignment WHERE uid=? AND scope=?
      • uid would be mapped to the user identity that came in the XACML request.
      • scope would be a resource attribute that would also be mapped in the PIP as follows
    • map scope to the field scope of the table posts using SELECT scope FROM posts WHERE pid=?
      • pid would be mapped to the identifier of the post in question. That also came in the XACML request.

    This means that your attribute userRole should really be called scopedUserRole. The modeling I gave is just one example. There are several other ways you could model with the same effect. Either way, all the heavy lifting happens inside the PIPs. The main drawback is that you lose visibility of the semantics of your authorization logic.

    Using attributes values and functions

    Another way of achieving a similar result is to store the relationship between scope and role in the value itself. This is what you allude to in your question.

    You can use string functions such as string-starts-with or string-ends-with or string-contains to achieve what you're interested in. There is also a string-regexp-match function you can use.

    Details on the functions can be found in the XACML 3.0 specification.

    If the functions are not sufficient in XACML, you can:

    • implement your own
    • implement a PIP that can process your attribute values and produce new ones. More on PIPs here.

    Creating a new datatype called tuple

    The problem with XACML is that it flattens relationships. Using a new data type with multiple parts, i.e. a Tuple, would solve the issue. That would require custom coding though and quite some work.

    Using the XML content inside a XACML request

    If all the information comse from the XACML request, then it could be expressed as an XML payload as part of the <Content/> element inside a XACML request. You could then use attribute selectors and XPath to retrieve what you are interested in.

    HTH. Do check out both my blog and the Axiomatics blog for more tips.