oasis-tcs / xacml-spec

OASIS XACML TC: List for tracking issues and features for the OASIS XACML TC. https://github.com/oasis-tcs/xacml-spec
Other
4 stars 1 forks source link

Change Target type to an Expression #2

Open cdanger opened 1 year ago

cdanger commented 1 year ago

Add possibility to use any Expression in a Target element (like Condition):

First option - not backward-compatible:

Change the TargetType in the XACML core schema (new major release):

<xs:complexType name="TargetType">
   <xs:sequence>
          <xs:element ref="xacml:Expression" minOccurs="0" />
   </xs:sequence>
</xs:complexType> 

Second option - backward-compatible: Extend TargetType:

<xs:complexType name="ExpressionTargetType">
  <xs:complexContent>
    <xs:extension base="xacml:TargetType">
      <xs:sequence>
        <xs:element ref="xacml:Expression"  minOccurs="0"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

More info in @steven-legg 's comment.

See also the issue #1.

steven-legg commented 11 months ago

The Expression element needs to be optional.

We can make a backward compatible extension to TargetType, taking advantage of the fact that a Target can be empty.

<xs:complexType name="ExpressionTargetType">
  <xs:complexContent>
    <xs:extension base="xacml:TargetType">
      <xs:sequence>
        <xs:element ref="xacml:Expression"  minOccurs="0"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

In usage we can apply the derived type with the xsi:type attribute:

<Target xsi:type="xacml:ExpressionTargetType">
  <!-- AnyOf elements are allowed here. -->
  <!-- Followed by an Expression, e.g., a variable reference. -->
  <VariableReference VariableId="foobar"/>
</Target>

And we can define an element substitution group around Target:

<xs:element name="ExpressionTarget" type="xacml:ExpressionTargetType"
  substitutionGroup="xacml:Target"/>

In usage it would look like this:

<ExpressionTarget>
  <!-- AnyOf elements are allowed here. -->
  <VariableReference VariableId="foobar"/>
</ExpressionTarget>

If an ExpressionTarget has AnyOf elements and an Expression we just say they are all ANDed together. Multiple AnyOf elements are already ANDed together. The type and element can use the existing wd-17 namespace.

cdanger commented 11 months ago

The Expression element needs to be optional.

My bad, I forgot the minOccurs="0", now fixed.

We can make a backward compatible extension to TargetType, taking advantage of the fact that a Target can be empty.

<xs:complexType name="ExpressionTargetType">
  <xs:complexContent>
    <xs:extension base="xacml:TargetType">
      <xs:sequence>
        <xs:element ref="xacml:Expression"  minOccurs="0"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

[...] And we can define an element substitution group around Target:

<xs:element name="ExpressionTarget" type="xacml:ExpressionTargetType"
  substitutionGroup="xacml:Target"/>

[...] If an ExpressionTarget has AnyOf elements and an Expression we just say they are all ANDed together. Multiple AnyOf elements are already ANDed together. The type and element can use the existing wd-17 namespace.

OK. Would you apply these changes to the existing XACML schema? or add a separate XSD file with these new types/elements (but same target namespace)? Could you show what the new XSD looks like in the end?

steven-legg commented 11 months ago

OK. Would you apply these changes to the existing XACML schema? or add a separate XSD file with these new types/elements (but same target namespace)? Could you show what the new XSD looks like in the end?

There is probably an expectation that an XSD file won't be amended, but XML Schema lets a namespace be defined across multiple files, so we should do that. The extra file would look like this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xacml="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
  targetNamespace="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
  elementFormDefault="qualified" attributeFormDefault="unqualified">

  <!-- Include the Related and Nested Entities Profile schema, which in turn includes the core schema. -->
  <xs:include schemaLocation="https://docs.oasis-open.org/xacml/xacml-3.0-related-entities/v1.0/cs02/schemas/xacml-v3-entities-schema.xsd"/>

  <xs:complexType name="ExpressionTargetType">
    <xs:complexContent>
      <xs:extension base="xacml:TargetType">
        <xs:sequence>
          <xs:element ref="xacml:Expression"  minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:element name="ExpressionTarget" type="xacml:ExpressionTargetType"
    substitutionGroup="xacml:Target"/>

</xs:schema>
cdanger commented 11 months ago

OK sounds good. In this case, what is the proper standardisation practice (OASIS): should we update the XACML core specification document for that? or just do a new XACML Profile document (with this new XSD file attached)?

steven-legg commented 11 months ago

In this case, what is the proper standardisation practice (OASIS): should we update the XACML core specification document for that? or just do a new XACML Profile document (with this new XSD file attached)?

Either is proper.

If it is just this change then it is much easier to do a profile. However, we have a list of enhancements under consideration and some of them touch many parts of the core spec, so rewriting the core spec becomes more practical, either as 3.1 or 4.0. Most likely we would keep the same namespace for 3.1 and add to it with separate XSD files, or for 4.0 we would create a combined XSD file with a new namespace.

humantypo commented 11 months ago

Curious as to what the intended (system) context is for these variables? Policy?

The reason I ask is for the use case of something being a PDP (or PEP?) wide variable vs. something that the author may wish to be limited to a finer (or wider) context.

steven-legg commented 11 months ago

Curious as to what the intended (system) context is for these variables? Policy?

Assuming this is not a question meant for issue #3, the variable references here are just examples of an expression. A VariableReference is the most compact complete example of an expression element. Anything else would have required start and end tags and text content.

humantypo commented 11 months ago

Ah, I see this is being discussed in several subsequent issues. Sorry. I am just catching up now.

steven-legg commented 8 months ago

If we change Target to be just like Condition for XACML 4.0 then we don't need to do anything to TargetType. We can just swap the Target element for a Condition element, i.e., Policy and PolicySet (or RuleSet #11) have a Condition instead of a Target. RuleType doesn't need both a Target and a Condition (but see only-one-applicable, Issue#11) so we just drop the Target from RuleType. We can then drop Target and TargetType completely.

cdanger commented 6 months ago

Agreed. No further comment on my part. @steven-legg @humantypo do you see anything else to discuss on this?

steven-legg commented 2 months ago

I'd like to apply this revision to the XACML 4.0 core spec and close the issue.

I think we are agreed that a target will be the same as a condition: a single child element from the expression substitution group. The <AnyOf>, <AllOf> and <Match> elements will go away. That still leaves some choices.

  1. We keep the <Target> element as a child of a policy and <Condition> as a child of a rule:
    <xs:element name="Target" type="xacml:TargetType"/>
    <xs:complexType name="TargetType">
    <xs:sequence>
        <xs:element ref="xacml:Expression"/>
    </xs:sequence>
    </xs:complexType>
    • The rationale for doing this is that the consequences of the child expression being true are different in the two cases. If a target is true we evaluate all the child policies and rules and combine their results according to the combining algorithm. If a condition is true then the result of the rule is its effect. Different names for the wrappers in the two cases makes for a distinct separation in the descriptions of the processing.
  1. Same as 1, but we can economise on the XSD:

    <xs:element name="Condition" type="xacml:BooleanExpressionType"/>
    <xs:element name="Target" type="xacml:BooleanExpressionType"/>
    <xs:complexType name="BooleanExpressionType">
    <xs:sequence>
        <xs:element ref="xacml:Expression"/>
    </xs:sequence>
    </xs:complexType>
  2. We throw out the <Target> element and replace it with a <Condition> element as a child of the policy. It is slightly less XSD but doesn't have the supposed benefits of (1).

  3. We could replace <Condition> with <Target> instead, but if we are only going to keep one then <Condition> seems the more generally useful choice.

I'm inclined to choose (1) or (2) over (3) or (4).

Rules have both a target and a condition that are ANDed together. The only reason for having a target is if we keep the only-one-applicable combining algorithm. It was defined only as a policy combining algorithm but with the distinction between policy and rule combining algorithms disappearing we need to either extend it to apply to rules (which argues for rules having a target, though not absolutely necessary) or we throw it out (so rules don't need a target). The only-one-applicable algorithm is an oddball that requires special processing and I would vote to throw it out and take targets out of rules.

I can see a less convenient way of simulating only-one-applicable using first-applicable and variables if anyone really objects.

cdanger commented 2 months ago
  • The expression in a condition is mandatory, but the <Condition> element is optional. I suggest we do the same for a target and make the <Target> element optional in a policy.

Fully agree, but you already know that :wink: .

I'm inclined to choose (1) or (2) over (3) or (4).

I'm inclined to choose either (2) or (3).

Why (3) ? Well, in your previous comment, I thought you were proposing to drop Target completely, so I was getting ready for that choice already :wink: (it simplifies not only the XSD for also the spec itself as several paragraphs would be obsolete and disappear). I am not too worried about losing the (2)'s benefits. (Regarding the first one, there are two different sections Policy evaluation and Rule evaluation and in each one we can describe what to do with the Condition result accordingly, as was done with Target in XACML 3.0. That's enough for me.) However, I admit that if we remove the Target element completely, it may be awkward and even confusing for the reader to talk about target and applicable policies in the spec, and these terms are used together in many places of the spec (e.g. the expression applicable by virtue of its target); so we would have to redefine or clarify those terms in the new XACML 4.0 model, but I haven't given it much thought. So (3) is probably more challenging in terms of semantics, and I would agree with choice (2) as an alternative. But still has a slight preference for (3) for the simplification of the language model.

The only reason for having a target is if we keep the only-one-applicable combining algorithm. It was defined only as a policy combining algorithm but with the distinction between policy and rule combining algorithms disappearing we need to either extend it to apply to rules (which argues for rules having a target, though not absolutely necessary) or we throw it out (so rules don't need a target). The only-one-applicable algorithm is an oddball that requires special processing and I would vote to throw it out and take targets out of rules.

Do you remember what was the original use case for only-one-applicable ?

As far as I am concerned, I am OK to extend it to rules. We just have clarify somewhere that a rule is now said applicable if (and only if) its Condition evaluates to true. In other words, isApplicable(ruleX) = evaluate (ruleX's Condition). Similarly, the definition of first-applicable should be changed as well, to remove target from the applicability check. For now, the description says things like : For a particular rule, if the target matches and the condition evaluates to "True", then... [...] For a particular rule selected in the evaluation, if the target evaluates to "False" or the condition evaluates to "False", then... [...]

I can see a less convenient way of simulating only-one-applicable using first-applicable and variables if anyone really objects.

Could you give a small example to get an idea ?

humantypo commented 2 months ago

However, I admit that if we remove the Target element completely, it may be awkward and even confusing for the reader to talk about target and applicable policies in the spec…

I think this extends beyond just the description in the spec. People generally think of protecting something under specific circumstances. Removing Target could make the general description of what a policy is supposed to do in Business Speak more difficult. While the mechanics are programmatically similar, the semantics of what a Target is and what a Condition is different at the abstract level IMO.

cdanger commented 2 months ago

OK I'm fine with choice (2) then.

steven-legg commented 2 months ago

Could you give a small example to get an idea ?

I don't have a real-world example, but the structure would be like this, assuming XACML 4.0:

<Policy PolicyId="http://example.com/example/only-one-applicable-policy"
  Version="1.0"
  CombiningAlgId="urn:oasis:names:tc:xacml:4.0:combining-algorithm:first-applicable">

  <VariableDefinition VariableId="target/policy1">
    ...
  </VariableDefinition>

  <VariableDefinition VariableId="target/policy2">
    ...
  </VariableDefinition>

  <VariableDefinition VariableId="target/policy3">
    ...
  </VariableDefinition>

  <Rule RuleId="no-more-than-one-applicable" Effect="Permit">
    <Description>
      Evaluates to Indeterminate if more than one target is true.
      Otherwise, NotApplicable.
    </Description>
    <Condition>
      <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:n-of">
          <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">2</AttributeValue>
          <VariableReference VariableId="target/policy1"/>
          <VariableReference VariableId="target/policy2"/>
          <VariableReference VariableId="target/policy3"/>
        </Apply>
        <!-- An expression that always evaluates to Indeterminate. -->
        <AttributeDesignator
          Category="http://example.com/no-such-category"
          AttributeId="http://example.com/no-such-attribute"
          DataType="http://www.w3.org/2001/XMLSchema#string"
          MustBePresent="true"/>
      </Apply>
    </Condition>
  </Rule>

  <!-- If we get here then zero or one policy is applicable. -->

  <Policy PolicyId="http://example.com/example/policy1"
    Version="1.0"
    CombiningAlgId="urn:oasis:names:tc:xacml:4.0:combining-algorithm:...">
    <Target>
      <VariableReference VariableId="target/policy1"/>
    </Target>
    ...
  </Policy>

  <Policy PolicyId="http://example.com/example/policy2"
    Version="1.0"
    CombiningAlgId="urn:oasis:names:tc:xacml:4.0:combining-algorithm:...">
    <Target>
      <VariableReference VariableId="target/policy2"/>
    </Target>
    ...
  </Policy>

  <Policy PolicyId="http://example.com/example/policy3"
    Version="1.0"
    CombiningAlgId="urn:oasis:names:tc:xacml:4.0:combining-algorithm:...">
    <Target>
      <VariableReference VariableId="target/policy3"/>
    </Target>
    ...
  </Policy>

  <!-- If we get here then the result is NotApplicable. -->

</Policy>

I notice that the descriptions of the logical functions don't account for Indeterminate arguments properly.

steven-legg commented 2 months ago

Do you remember what was the original use case for only-one-applicable ?

Its original URI harks back to XACML 1.0 which is well before my involvement in the TC.

steven-legg commented 2 months ago

Similarly, the definition of first-applicable should be changed as well, to remove target from the applicability check.

Already done in XACML 4.0. The first-applicable algorithm (and every other combining algorithm except only-one-applicable) completely evaluates a child policy or rule before combining the result. This is equivalent to the algorithm as described in XACML 3.0, which didn't need to mention targets since 7.11 and 7.12 accounted for them. The only-one-applicable rule is the odd one out because the target needs to be evaluated separately.

humantypo commented 2 months ago

To be honest I don't recall what the use case was for only-one-applicable, if one was explicitly provided. It may have been a byproduct of "completeness" in trying to account for as yet to be determined use cases...

cdanger commented 2 months ago

OK so... Based on latest comments and @steven-legg 's workaround using first-applicable algorithm, I don't object to removing only-one-applicable from the spec (and therefore Target out of Rules).

steven-legg commented 1 month ago

I will make changes to the core draft according to option 2, drop <Target> from RuleType, make <Target> optional in a policy and discard the only-one-applicable combining algorithm.

steven-legg commented 1 month ago

The proposed changes have been made to the core draft and the copy in the wiki has been updated.

steven-legg commented 1 month ago

xacml-v4.0-csd01-diff.txt Here are the differences.