Download your copy of our State of Authorization: Playbook Edition Get it now »

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.

Background

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 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.


  Join us on LinkedIn for more insights
Archived under:
About the author

As Chief Technology Officer, David has experience leading the design and development of Salesforce’s identity offering including customer identity and access management (CIAM). He is a founding member of IDPro, a co-author of the OASIS XACML standard, and an expert on standard-based authorization as part of an overall IAM implementation.