In XACML what is the StringOneAndOnly function?

Example of policies can be:
Managers can view documents in their city.
Users can edit documents they own
Each policy uses attributes. In the examples above, the policies use the following attributes:
A user’s role e.g. manager
An action e.g. view, edit.
A resource type e.g. document
A user’s city e.g. Kalamazoo
A document’s city e.g. Tallahassee
What are attributes?
Conceptually, attributes are a set of key-value pairs. You can use any number of attributes in your authorization policies. They are used to describe the user, the action, the resource, and the context. In XACML attributes are defined as:
An identifier e.g. user.location
A datatype e.g. string. There are nearly 20 datatypes to choose from in XACML from integer and double to date, time, and boolean.
A category e.g. access-subject. There are 4 default categories in XACML that are regularly used in policies. The category is akin to the grammatical function of the attribute in the sentence.
Optionally an attribute can also have an issuer i.e. who issued the value for the attribute.
Attributes are always bags of values.
By default, XACML attributes are always bags of values. This means that by default the XACML Policy Decision Point (PDP) will always consider an attribute to be a bag of values even if this bag contains a single value or none at all.
This means that when comparing attributes together we will have to think about the fact attributes are bags of values. To that effect, XACML provides a series of bag functions to manipulate the bags. These functions are defined in Annex A, part 3, section 10 of the XACML specification. They include:
urn:oasis:names:tc:xacml:x.x:function:type-one-and-only
urn:oasis:names:tc:xacml:x.x:function:type-bag-size
urn:oasis:names:tc:xacml:x.x:function:type-is-in
urn:oasis:names:tc:xacml:x.x:function:type-bag
In this week’s Question of the Week, we will focus on urn:oasis:names:tc:xacml:x.x:function:type-one-and-only.
Understanding type-one-and-only
When comparing two attributes together e.g. the user’s location to the document’s location, we will be using the method called stringEqual (using ALFA notation, the Abbreviated Language For Authorization). This method takes in two single values. This means we must be sure there is a single value for the user’s city and the document’s city. We cannot for instance write stringEqual(user.city, document.city).
To be able to compare two attributes we must therefore convert the bag of values into a single value. In order to achieve this, we have the type-one-and-only family of functions:
urn:oasis:names:tc:xacml:1.0:function:string-one-and-only
urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only
urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only
urn:oasis:names:tc:xacml:1.0:function:double-one-and-only
urn:oasis:names:tc:xacml:1.0:function:time-one-and-only
urn:oasis:names:tc:xacml:1.0:function:date-one-and-only
urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only
urn:oasis:names:tc:xacml:1.0:function:anyURI-one-and-only
urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only
urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only
urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-one-and-only
urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-one-and-only
urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only
urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only
urn:oasis:names:tc:xacml:2.0:function:ipAddress-one-and-only
urn:oasis:names:tc:xacml:2.0:function:dnsName-one-and-only
All the functions have the same effect. They take a bag of values and convert it into a single value. In a way they act like a funnel or a sieve which keeps a single value.
These functions only work if the bag contains a single value. So what if the bag contains more than one value? The function will throw an Indeterminate (one of the four possible XACML decisions) with a status code stating the number of input values was incorrect:
urn:oasis:names:tc:xacml:1.0:function:string-one-and-only expects a bag that contains a single element, got a bag with xx elements
If the bag contains a value, type-one-and-only returns that value
If the bag is empty, type-one-and-only returns Indeterminate
If the bag has more than one value, type-one-and-only returns Indeterminate.
Avoiding errors – Preventing the Indeterminate response
To avoid Indeterminate we can use the bag-size function to determine the size of a bag, i.e. type-bag-size. With this function, we can verify the size of the bag before using the type-one-and-only function. This avoids the Indeterminate case.
Before
In this example (ALFA), the policy does not check whether there are any values in either attribute bag. This rule can therefore yield an Indeterminate.
rule checkLocation{
permit
condition stringOneAndOnly(user.city)==stringOneAndOnly(document.city)
}
After
In this example (ALFA), we use the stringBagSize to check whether each bag does contain a single value. If it is the case, we use the stringOneAndOnly to extract that value. This prevents the rule from returning Indeterminate.
rule checkLocation{ permit condition stringBagSize(user.city)==1 && stringBagSize(document.city)==1 && stringOneAndOnly(user.city)==stringOneAndOnly(document.city) }
Conclusion
Attributes are always bags of values in XACML but that doesn’t mean the attribute will have multiple values. XACML provides functions to extract a single value from these bags so that it can be used in comparisons. The StringOneAndOnly function belongs to a family of functions known as ‘type-one-and-only’. There are other bag functions that also come in handy to process attributes.