Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a ternary conditional operator function #13

Open
steven-legg opened this issue Feb 27, 2024 · 2 comments
Open

Add a ternary conditional operator function #13

steven-legg opened this issue Feb 27, 2024 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@steven-legg
Copy link

The proposed feature is a new XACML function that implements a ternary conditional operator such as is available in many programming languages, for example, with the syntax (a ? b : c).

In XACML terms the function would take three arguments. The first argument must evaluate to a primitive boolean value. If that value is true then the result of the function is the result of evaluating the second argument. If the value is false then the result of the function is the result of evaluating the third argument. The second and third arguments must evaluate to the same primitive type, or both to a bag of the same primitive type.

Potential URIs include:
urn:oasis:names:tc:xacml:3.0:function:conditional
urn:oasis:names:tc:xacml:3.0:function:ternary-if

@steven-legg steven-legg self-assigned this Feb 27, 2024
@cdanger cdanger added the enhancement New feature or request label Feb 29, 2024
@cdanger
Copy link

cdanger commented Feb 29, 2024

I support this.

My typical use case is when the attribute values are strings representing levels of something and you want to map them to integers in order to compare them.

For example, say we have a subject attribute 'clearance_level' and resource attribute 'classification_level'. Both may take string values "RESTRICTED", "CONFIDENTIAL", "SECRET" which represent levels of classification/clearance in ascending order ("RESTRICTED" is lower than "CONFIDENTIAL", etc.); and we want the policy to return Permit if one of the subject's clearance levels is greater than or equal to the resource's classification level. If we map these values to integers (RESTRICTED -> 1, CONFIDENTIAL -> 2, etc.), then we can use simple integer comparison.

To do this, we could use the ternary conditional operator (multiple times) to compute the corresponding integer variables:

  • clearance_int (integer): ($clearance_level = "SECRET") ? 3 : ( ($clearance_level = "CONFIDENTIAL") ? 2 : ( ($clearance_level = "RESTRICTED") ? 1 : 0 ) )
  • classification_int (integer): same expression with classification_level instead of clearance_level.

Now the PDP can return Permit if clearance_int ≥ classification_int .

Side note: currently with XACML 3.0, one way to do something similar consists to put the classification (resp. clearance) in XML form in the resource's (resp. subject's) Attributes/Content, and use an XPath 2.0 expression such as the following: for $classification in //*:Classification/text() return if ($classification = 'SECRET') then 3 else if ($classification = 'CONFIDENTIAL') then 2 else if ($classification = 'RESTRICTED ') then 1 else 0 .

If XACML supports XPath 3.0 in the future, the expression could be rewritten like this: let $classification := //*:Classification/text() , return if ($classification = 'SECRET') then 3 else if ($classification = 'CONFIDENTIAL') then 2 else if ($classification = 'RESTRICTED ') then 1 else 0.

However, the main drawback of this XPath workaround is that it requires XPath support which is not mandatory in XACML, and it works only for XML stuff in elements, not for named attributes, whereas the ternary conditional operator would work for named attributes.

@cdanger cdanger added this to the xacml-core-3.1 milestone Mar 9, 2024
@cdanger
Copy link

cdanger commented Mar 10, 2024

Another simpler use case is to be able to assign a default value in a VariableDefinition if it is based on some input that may be null/undefined. For example, we want to set the value of a variable classif_level from a request attribute (AttributeDesignator) named classification-level, but set the value UNCLASSIFIED by default if this request attribute is missing or the bag of attribute values is empty.

In other words, let's s say we have a classif_level_bag variable defined like this: <VariableDefinition VariableId="classif_level_bag"><AttributeDesignator DataType="string" Category="resource" AttributeId='classification-level' MustBePresent="false" /></VariableDefinition>

The resulting bag is expected to have a single string value or to be empty if the attribute is missing/undefined or has no value. It would be more convenient to have a corresponding variable as a string, so we can use the ternary conditional operator to set a classif_level (string) variable to the default value "UNCLASSIFIED" if the bag is empty (pseudo-code):

string-bag-size($classif_level_bag) == 0 ? "UNCLASSIFIED" : string-one-and-only($classif_level_bag)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants