Multi-value comparisons in XACML

There's a bit of a mismatch in the XACML specification, in that most of the functions operate on single arguments but attributes are always returned in bags.  This is fine when comparing values in the <SubjectMatch> (and similar) elements as the multi-valued nature of the four AttributeDesignator elements is handled automatically; comparing values in the <Condition> requires a little more effort.

Luckily there are two classes of functions that allow comparison between a single value and bags of values, or between two bags of values.

Comparing a single value to a bag of values

For example, let's say we need to check of the attribute "department" is equal to "Finance".  You could do a simple string-equality check as follows:

<Apply FunctionId="string-equal">
    <AttributeValue DataType="#string">Finance</AttributeValue>
    <SubjectAttributeDesignator AttributeId="department" DataType="#string" />
</Apply>

This is well and good until the "department" attribute is multi-valued.  In that case, the "string-equal" function will try to compare a string to a bag of strings and fail with either a syntax error or processing error.

There are a two functions to help here, "any-of" and "all-of".  Both are boolean functions that allow a constant to be compared to a bag of values, with "any-of" returning true if one of the bag members causes a match and "all-of" returning true if all of the bag members return a match.

Our example above can be re-written as:

<code><Apply FunctionId="any-of">
 <Function FunctionId="string-equal"/>
 <AttributeValue DataType="#string">Finance</AttributeValue>
 <SubjectAttributeDesignator 
  AttributeId="department" DataType="#string" />
</Apply>

The "string-equal" function is applied to "Finance" and each attribute returned from the <SubjectAttributeDesignator>.  If any of these comparisons returns true, then the result of the "any-of" function is also true.

Comparing a bag of values to a bag of values

What if we needed to see if the "department" field was in a range of possible values, such as "Finance" OR "Human Resources"?  Using the "any-of" function would fail for the same reasons the original "string-equal" function failed, as a bag of values would be in the place where a single value was expected.

We can use functions such as "any-of-any" to solve this requirement.  "Any-of-any" applies a function between each element of two bags of values, returning true if at least one of these comparisons returns true.  Our example can be expressed as:

<Apply FunctionId="any-of-any">
 <Function FunctionId="string-equal"/>
 <Apply FunctionId="string-bag">
  <AttributeValue DataType="#string">Finance</AttributeValue>
  <AttributeValue DataType="#string">Human Resources</AttributeValue>
 </Apply>
 <SubjectAttributeDesignator
  AttributeId="department" DataType="#string" />
</Apply>

Notice that I've also used the "string-bag" function to convert a list of <AttributeValue> elements to a bag suitable for consumption by this function.

blog comments powered by Disqus