Handling multi-valued attributes in ALFA – How “bag” can it get?
See how you can leverage the power of ALFA to help your Policy Decision Point (PDP) handle multi-valued attributes.
Attribute-based access control (ABAC) leverages attributes in combination with a set of policies to determine authorization decisions. A request is sent from an application, API, or another component that acts as a policy enforcement point (PEP). The policy decision point (PDP) receives the request and applies it to the authorization policies that it has in place. While doing so, the PDP might leverage one or more policy information points (PIP) in order to retrieve additional attribute values.
Attributes are bags of values
An example
- Incoming request: “Can Tintin enter the EU?”
- Policy:
- “Belgian citizens can enter the EU” and,
- “Citizens of Borduria cannot enter the EU.”
This means that the PDP will have to try to determine the values for those attributes it needs as it is evaluating the request against the policy. The PDP needs to resolve what citizenship(s) Tintin has. Is he French? Belgian? But being both French and Belgian is not exclusive.
So how does the PDP handle that?
Introducing multi-valued attributes
This is where the power of Abbreviated Language for Authorization (ALFA) comes into play. Every attribute in ALFA is considered a bag of values. Think of it as an unordered array of values. In our example where the PDP is resolving the user citizenship(s) through a PIP, it might do so by executing a SQL query against a relational database for example. This might result in multiple values (Belgian and French), and these two values are placed in the bag. Depending on how the policy is configured, it is enough that the bag contains the correct value in order for that target or condition to evaluate to true and, in our case, get a Permit decision.
Handling bags – ALFA Functions
There are several functions within ALFA that can operate on bags.
The following lists some of the functions that may be useful when handling bags.
Handling single-valued bags
If it is explicitly known that an attribute will only contain one value it is possible to use a function to convert it to a single value. This is done by using the *OneAndOnly functions.
There are several such functions that operate on the different datatypes supported in ALFA:
- anyURIOneAndOnly
- base64BinaryOneAndOnly
- booleanOneAndOnly
- dateOneAndOnly
- dateTimeOneAndOnly
- doubleOneAndOnly
- hexBinaryOneAndOnly
- integerOneAndOnly
- rfc822NameOneAndOnly
- stringOneAndOnly
- timeOneAndOnly
- x500NameOneAndOnly
- dnsNameOneAndOnly
- ipAddressOneAndOnly
- dayTimeDurationOneAndOnly
- yearMonthDurationOneAndOnly
Checking for values inside bags
There are other functions that operate on bags of values; one example is StringIsIn that returns true if one string value is in a bag of string values.
This function also exists for other datatypes too:
- anyURIIsIn
- base64BinaryIsIn
- booleanIsIn
- dateIsIn
- dateTimeIsIn
- doubleIsIn
- hexBinaryIsIn
- integerIsIn
- rfc822NameIsIn
- stringIsIn
- timeIsIn
- x500NameIsIn
- dayTimeDurationIsIn
- yearMonthDurationIsIn
Measuring the size of bags
Sometimes knowing how many roles a user has could be interesting. In this case we want to measure how many values the role attribute has.
To do so there is a function type called *BagSize():
- anyURIBagSize
- base64BinaryBagSize
- booleanBagSize
- dateBagSize
- dateTimeBagSize
- doubleBagSize
- hexBinaryBagSize
- integerBagSize
- rfc822NameBagSize
- stringBagSize
- timeBagSize
- x500NameBagSize
- dnsNameBagSize
- ipAddressBagSize
- dayTimeDurationBagSize
- yearMonthDurationBagSize
ALFA Example
The following sample ALFA policy contains 3 uses of bag functions:
- stringOneAndOnly: a person who is exclusively Belgian has access.
- stringBagSize: any user who bears no citizenship is denied access.
- stringAtLeastOneMemberOf: we deny access to citizens of a certain set of countries. If the user has at least one citizenship of the 3 countries listed then access is denied.
- stringAtLeastOneMemberOf: we allow access to citizens of an EU country. It doesn’t matter that the user has more than one citizenship.
namespace com.axiomatics.example{
import Attributes.*
policy citizenship{
target clause actionId == "enter" and area == "European Union"
apply denyOverrides
/**
* In this example, a person who is exclusively Belgian has access
*/
rule Belgians{
permit
condition stringBagSize(user.citizenship)==1 && stringOneAndOnly(user.citizenship)=="Belgium"
}
/**
* In this example, any user who bears no citizenship is denied access
*/
rule denyNoCitizenship{
deny
condition stringBagSize(user.citizenship)==0
}
/**
* In this example we deny access to citizens of a certain set of countries. If the user has at least one citizenship of
* the 3 countries listed then access is denied
*/
rule denyBannedCountries{
deny
condition stringAtLeastOneMemberOf(user.citizenship,stringBag("San Theodoros","Borduria","Sondonesia"))
}
/**
* Allow an EU citizen other than Belgians access
*/
rule allowEUCitizens{
permit
condition not(user.citizenship=="Belgium") && stringAtLeastOneMemberOf(user.citizenship,euCountries)
}
}
}
Conclusion
Every attribute in ALFA is considered a bag of values. This means that one attribute definition can hold multiple values. For example, in the case of a citizenship attribute, the values it holds could be both Belgian and French.
Learn more
Check out https://alfa.guide for up-to-date content on ALFA, more samples, and the authoritative list of datatypes and functions.
Have 30 minutes? Let's show you a demo!
See how our award-winning solution can help you meet today's access control and Zero Trust needs.
Request a demoJoin us on LinkedIn for more insights
