I have a XACML request like this (pseudo-xacml):
<Request>
<Attributes Category="resource">
<Attribute AttributeId="product">
<AttributeValue>A</AttributeValue>
</Attribute>
<Attribute AttributeId="market">
<AttributeValue>M2</AttributeValue>
<AttributeValue>M3</AttributeValue>
</Attribute>
<Attribute AttributeId="slice">
<AttributeValue>fus</AttributeValue>
<AttributeValue>do</AttributeValue>
<AttributeValue>rah</AttributeValue>
</Attribute>
</Attributes>
<Attributes Category="subject">
<Attribute AttributeId="product-market-slice-access">
<AttributeValue>A:::M2:::fus</AttributeValue>
<AttributeValue>A:::M2:::do</AttributeValue>
<AttributeValue>A:::M2:::rah</AttributeValue>
<AttributeValue>A:::M3:::fus</AttributeValue>
<AttributeValue>A:::M3:::do</AttributeValue>
<!--<AttributeValue>A:::M3:::rah</AttributeValue>--> <!-- Missing attribute, permission denied! -->
</Attribute>
</Attributes>
</Request>
I wish to create a policy that denies access with the above request, and permits access if the subject is given the missing attribute (commented out).
Is there a way to express this in a XACML/ALFA policy?
If there was a function in XACML that could "join" bags (think sql-join) that would be helpful. That way I could use a combination of the functions "AnyOfAll" and "String-Equal".
Pseudo-xml of wanted function:
<WantedFunction>
<Input>
<Separator>:::</Separator>
<Bag>
<AttributeValue>A</AttributeValue>
<AttributeValue>B</AttributeValue>
</Bag>
<Bag>
<AttributeValue>M2</AttributeValue>
<AttributeValue>M3</AttributeValue>
</Bag>
<Bag>
<AttributeValue>fus</AttributeValue>
<AttributeValue>do</AttributeValue>
<AttributeValue>rah</AttributeValue>
</Bag>
</Input>
<Output>
<Bag>
<AttributeValue>A:::M2:::fus</AttributeValue>
<AttributeValue>A:::M2:::do</AttributeValue>
<AttributeValue>A:::M2:::rah</AttributeValue>
<AttributeValue>A:::M3:::fus</AttributeValue>
<AttributeValue>A:::M3:::do</AttributeValue>
<AttributeValue>A:::M3:::rah</AttributeValue>
<AttributeValue>B:::M2:::fus</AttributeValue>
<AttributeValue>B:::M2:::do</AttributeValue>
<AttributeValue>B:::M2:::rah</AttributeValue>
<AttributeValue>B:::M3:::fus</AttributeValue>
<AttributeValue>B:::M3:::do</AttributeValue>
<AttributeValue>B:::M3:::rah</AttributeValue>
</Bag>
</Output>
</WantedFunction>
This is a great question and I'm glad to see you're using ALFA as well. Let me shed some light on it.
The request
First of all, in a XACML request, sending an attribute as two separate attributes is the same as sending it as a single attribute. For instance, the following two requests are the same.
Request Example 1
Request Example 2
Attributes are bags
In XACML, an attribute is always a bag. It's always multi-valued even if it contains zero or one value. This means that if you want to operate on the attribute, you need to remember it's a bag. For instance, if you want to concatenate market with slice, you'd either have to convert it to a single value (and that only works if it's indeed a single value) or use higher-order functions. A higher-order function is a function that takes another function as a parameter e.g. AllOf.
Concatenating multi-valued attributes
An option would be to use stringConcatenate but that function only operates on atomic values. You could use map to apply it to a bag but unfortunately in your case, you would need a map capable of working on multiple bags.
The solution: using multiple decision requests
Rather than sending all the values in one lump request, you could use the Multiple Decision Profile (MDP) which lets you send multiple requests in one go for instance:
The answer would contain as many decisions as the product of the combinations (1x3x3 in this case).
In your case, you would combine all the decisions into a single one. If all Permit then Permit else Deny. There is a parameter in MDP to do that. It's called CombinedDecision.
With that in mind, here's what the policy will look like (using ALFA notation):
Sample Request - MDP