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

Simplify combiner parameters #14

Open
steven-legg opened this issue Feb 28, 2024 · 15 comments
Open

Simplify combiner parameters #14

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

Comments

@steven-legg
Copy link

steven-legg commented Feb 28, 2024

There are four varieties of combiner parameters yet none of the standardized combining algorithms take parameters. The four varieties are CombinerParameters, PolicySetCombinerParameters, PolicyCombinerParameters and RuleCombinerParameters.

The question arises, does any non-standard combining algorithm use them?

@steven-legg steven-legg added this to the xacml-core-4.0 milestone Feb 28, 2024
@steven-legg steven-legg self-assigned this Feb 28, 2024
@steven-legg steven-legg closed this as not planned Won't fix, can't repro, duplicate, stale Feb 28, 2024
@steven-legg
Copy link
Author

There is a non-trivial amount of XSD for something no one seems to be using.

We can simplify the XSD if we remove combiner parameters completely, but we can simplify things a bit for XACML 4.0 while keeping the functionality for anyone who happens to be making use of combiner parameters and wants to migrate to XACML 4.0.

We drop PolicySetCombinerParameters because of the merger of PolicySet into Policy. PolicyCombinerParameters and RuleCombinerParameters extend CombinerParameters by adding an XML attribute identifying a policy or rule, respectively, by ID. Since CombinerParameters is a list of arbitrary CombinerParameter elements that wrap an XACML attribute and apply a parameter name, the task of the policy and rule identifying XML attributes in PolicyCombinerParameters and RuleCombinerParameters could be taken on by a CombinerParameter instead. Thus we can drop PolicyCombinerParameters and RuleCombinerParameters as well, leaving only CombinerParameters. A CombinerParameter element is more verbose than an XML attribute, but this is a capability no one seems to be making use of anyway.

We could choose to set aside two combiner parameter names for indicating policy and rule IDs and describe how they are intended to be used, or not worry about it and leave it to the implementer to come up with a solution for their non-standard combining algorithm . There isn't a need for consistency between different, non-standard combining algorithms.

@steven-legg steven-legg reopened this May 3, 2024
@cdanger cdanger added the enhancement New feature or request label Jul 8, 2024
@cdanger
Copy link

cdanger commented Sep 28, 2024

On my side, I don't know and don't have any use case for PoliyCombinerParameters and RuleCombinerParameters, therefore I welcome any simplification of the schema there :-) . I am not sure what xml schema you have in mind in your third paragraph though, maybe give an example of what it would lok like?

In the meantime, I see one possibility to merge all xxxCombinerParameters into CombinerParameters using a type like this (also considering there's no more PolicySet in xacml 4.0):

<xs:complexType name="CombinerParametersType">
   <xs:sequence>
          <xs:choice minOccurs="0">
                <xs:element name="RuleIdRef" type="xs:string"/>
                <xs:element name="PolicyIdRef" type="xs:anyURI"/>
          </xs:choice>
          <!--  I changed minOccurs from 0 (XACML 3.0 schema) to *1* below because having CombinerParameters with zero CombinerParameter makes no sense (yet another issue in the XSD) -->
          <xs:element ref="xacml:CombinerParameter" minOccurs="1" maxOccurs="unbounded"/>
   </xs:sequence>
</xs:complexType>

If we add the constraint that a Rule ID must be different from any sibling Policy ID, i.e. any Rule/Policy ID is unique (within the same parent Policy), then we can simplify:

<xs:complexType name="CombinerParametersType">
   <xs:sequence>
          <xs:element ref="xacml:CombinerParameter" minOccurs="1" maxOccurs="unbounded"/>
   </xs:sequence>
   <!-- Replaces PolicyIdRef/RuleIdRef. The ID is enough to identify the Policy/Rule because of the constraint. -->
   <xs:attribute name="CombinedElementIdRef" type="xs:string" />
</xs:complexType>

@steven-legg
Copy link
Author

I am not sure what xml schema you have in mind in your third paragraph though, maybe give an example of what it would look like?

The first part was suggesting adding RuleIdRef and PolicyIdRef as optional XML attributes to CombinerParametersType with a constraint in prose that both can't be present. The simpler syntax is to leave CombinerParametersType alone and reserve RuleIdRef and PolicyIdRef as ParameterName values for a CombinerParameter element with standardized meanings. So do this:

<CombinerParameters>
  <CombinerParameter ParameterName="RuleIdRef>
    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">MyRule</AttributeValue>
  </CombinerParameter>
  <!-- More Parameters ->
</CombinerParameters>

instead of this:

<RuleCombinerParameters RuleIdRef="MyRule">
  <!-- More Parameters ->
</RuleCombinerParameters>

A combiner parameter can be anything, including a reference to a rule or a reference to a policy. The meaning can be anything, including "only apply the other parameters to the identified rule" (or policy). The policy reference would be anyURI type.

@steven-legg
Copy link
Author

If we add the constraint that a Rule ID must be different from any sibling Policy ID, i.e. any Rule/Policy ID is unique (within the same parent Policy)

Slightly off on a tangent ...

I can't find any statement in the core that rule IDs have to be unique within the same policy, though it is a reasonable expectation, and RuleCombinerParameters seems to be the only place where it matters - maybe. Would it really hurt if someone gave a bunch of rules the same ID so that the same set of parameters would apply to each of them? Similarly, if we make RuleIdRef and PolicyIdRef parameter names then would it really hurt if someone listed multiple RuleIdRef and PolicyIdRef parameters in the same CombiningParameters element with the intention that the set of parameters would apply to all of them?

There's no compelling reason to insist on rule IDs being unique within a policy and no compelling reason not to. We might do it for completeness.

@cdanger
Copy link

cdanger commented Oct 3, 2024

Well, just a question of semantics for me, using the term ID is a bit misleading if it's not unique in some scope. It's something else then, just a name. But also on my side, we use the RuleID for logging/troubleshooting purposes, when developers want to identify precisely which rule is being evaluated, which rule is causing the error (it's more user-friendly than just logging the index of the rule in the list for instance).

@steven-legg
Copy link
Author

Okay, we explicitly state that RuleID has to be unique within a policy and we allow multiple RuleIdRef and PolicyIdRef parameters in a CombiningParameters.

@steven-legg
Copy link
Author

So I'm looking at edits to fold PolicyCombinerParameters and RuleCombinerParameters into CombinerParameters and I'm wondering what version 3.0 was trying to achieve with this and related statements:

If multiple <CombinerParameters> elements occur within the same policy or policy set, they SHALL be considered equal to one <CombinerParameters> element containing the concatenation of all the sequences of <CombinerParameters> contained in all the aforementioned <CombinerParameters> elements, such that the order of occurrence of the <CombinerParameters> elements is preserved in the concatenation of the <CombinerParameter> elements.

There are no combining algorithms that take parameters therefore this requirement is inconsequential, so why constrain how such a combining algorithm might work? My best guess is that the intention was to discourage combining algorithms from attaching any significance to the position of combining parameters with respect to policies and rules. So the algorithm should work the same if all the combining parameters are bunched at the beginning or bunched at the end. Parameters meant for particular rules or policies are supposed to be expressed in RuleCombinerParameters and PolicyCombinerParameters instead of by proximity to the rule or policy. Can anyone see (or remember) another reason?

@cdanger
Copy link

cdanger commented Dec 20, 2024

No clue, never used it. @humantypo @Hal-Lockhart ?

@humantypo
Copy link

@steven-legg your "best guess" is my recollection as to the motivation.

@steven-legg
Copy link
Author

Capturing the consequences of this:

If multiple <CombinerParameters> elements occur within the same policy or policy set, they SHALL be considered equal to one <CombinerParameters> element containing the concatenation of all the sequences of <CombinerParameters> contained in all the aforementioned <CombinerParameters> elements, such that the order of occurrence of the <CombinerParameters> elements is preserved in the concatenation of the <CombinerParameter> elements.

and related statements for <RuleCombinerParameters> and <PolicyCombinerParameters> in a revision that folds PolicyCombinerParameters and RuleCombinerParameters into CombinerParameters and uses RuleID and PolicyID parameters is tending to be rather convoluted to define. The statements make it clear that the partitioning of CombinerParameter elements into different CombinerParameters elements is not consequential so I've got an idea for a different approach.

Firstly, we create a single list of CombinerParameter elements and discard CombinerParameters, RuleCombinerParameters and PolicyCombinerParameters. The list can go at the top of PolicyType (so that it appears just after the CombiningAlgId attribute in a Policy instance):

    <xs:complexType name="PolicyType">
        <xs:sequence>
            <xs:element ref="xacml:CombinerParameter" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="xacml:Description" minOccurs="0"/>
            <xs:element ref="xacml:PolicyIssuer" minOccurs="0"/>
            <xs:element ref="xacml:PolicyDefaults" minOccurs="0"/>
            <xs:element ref="xacml:Target" minOccurs="0"/>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="xacml:Policy"/>
                <xs:element ref="xacml:PolicyIdReference"/>
                <xs:element ref="xacml:VariableDefinition"/>
                <xs:element ref="xacml:Rule"/>
            </xs:choice>
            <xs:element ref="xacml:ObligationExpressions" minOccurs="0"/>
            <xs:element ref="xacml:AdviceExpressions" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="PolicyId" type="xs:anyURI" use="required"/>
        <xs:attribute name="Version" type="xacml:VersionType" use="required"/>
        <xs:attribute name="CombiningAlgId" type="xs:anyURI" use="required"/>
        <xs:attribute name="MaxDelegationDepth" type="xs:integer" use="optional"/>
    </xs:complexType>

The prose would reserve the RuleID and PolicyID parameter names, used as follows.

The CombinerParameter elements in the list preceding any with the names PolicyID or RuleID apply to the combining algorithm generally in the order they appear. CombinerParameters elements following a parameter with the name PolicyID or RuleID, up to but not including another CombinerParameter element with the name PolicyID or RuleID, specifically apply to the identified policy or rule.

An XACML 3.0 policy can be translated into XACML 4.0 without knowing anything about combining algorithms. All the parameters from the CombinerParameters elements are copied to the start of the list with their order retained. Each RuleCombinerParameters element is replaced by a parameter with the name RuleID and its contained parameters appended to the unified list. Each PolicyCombinerParameters element is replaced by a parameter with the name PolicyID and its contained parameters appended to the unified list.

What it means if CombinerParameters has multiple parameters having the names PolicyID or RuleID is no longer a concern.

A unified list at the top isn't actually necessary. The CombinerParameter elements could be interspersed in the choice with policies and rules, but separating them removes the temptation to ascribe meaning to their adjacency to rules and policies.

@cdanger
Copy link

cdanger commented Jan 10, 2025

OK, does the CombinerParameterType definition stays the same as in XACML 3.0 in this case? any change?

Also I just realized we have something else called Parameter now in (parameterized) policies (see #11), so we'll need a different name for that to avoid the confusion with CombinerParameter.

@humantypo
Copy link

"...with their order retained"

This seems straightforward when aggregating a Policy, but I'm curious as to how order is preserved in a Policy Set?

@cdanger
Copy link

cdanger commented Jan 11, 2025

Indeed, let's take a concrete XACML 3.0 PolicySet example, trying to cover most cases:

<?xml version="1.0" encoding="UTF-8"?>
<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="test" Version="1.0"
   PolicyCombiningAlgId="urn:test:my-custom-combining-alg">
   <Target />
   <CombinerParameters>
      <CombinerParameter ParameterName="p1">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">a</AttributeValue>
      </CombinerParameter>
      <CombinerParameter ParameterName="p2">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">b</AttributeValue>
      </CombinerParameter>
   </CombinerParameters>
   <PolicyCombinerParameters PolicyIdRef="P1">
      <CombinerParameter ParameterName="p3">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">c</AttributeValue>
      </CombinerParameter>
      <CombinerParameter ParameterName="p4">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">d</AttributeValue>
      </CombinerParameter>
   </PolicyCombinerParameters>
   <CombinerParameters>
      <CombinerParameter ParameterName="p5">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">e</AttributeValue>
      </CombinerParameter>
      <CombinerParameter ParameterName="p6">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">f</AttributeValue>
      </CombinerParameter>
   </CombinerParameters>
   <PolicySetCombinerParameters PolicySetIdRef="PS1">
      <CombinerParameter ParameterName="p7">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">g</AttributeValue>
      </CombinerParameter>
      <CombinerParameter ParameterName="p8">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">h</AttributeValue>
      </CombinerParameter>
   </PolicySetCombinerParameters>
   <CombinerParameters>
      <CombinerParameter ParameterName="p9">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">i</AttributeValue>
      </CombinerParameter>
      <CombinerParameter ParameterName="p10">
         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">j</AttributeValue>
      </CombinerParameter>
   </CombinerParameters>
   <PolicyIdReference>P1</PolicyIdReference>
   <PolicySetIdReference>PS1</PolicySetIdReference>
</PolicySet>

How would this translate to XACML 4.0?

@steven-legg
Copy link
Author

How would this translate to XACML 4.0?

Noting that policy sets becomes policies, PolicyId must be a URI and an empty target must be omitted, it becomes:

<?xml version="1.0" encoding="UTF-8"?>
<Policy xmlns="urn:oasis:names:tc:xacml:4.0:core:schema" PolicyId="http://example.com/test" Version="1.0"
   CombiningAlgId="urn:test:my-custom-combining-alg">
   <CombinerParameter ParameterName="p1">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">a</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p2">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">b</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p5">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">e</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p6">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">f</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p9">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">i</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p10">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">j</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="PolicyId">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://example.com/P1</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p3">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">c</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p4">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">d</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="PolicyId">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://example.com/PS1</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p7">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">g</AttributeValue>
   </CombinerParameter>
   <CombinerParameter ParameterName="p8">
       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">h</AttributeValue>
   </CombinerParameter>
   <PolicyIdReference>http://example.com/P1</PolicyIdReference>
   <PolicyIdReference>http://example.com/PS1</PolicyIdReference>
</Policy>

For CombinerParameters we have:

If multiple <CombinerParameters> elements occur within the same policy, they SHALL be considered equal to one <CombinerParameters> element containing the concatenation of all the sequences of <CombinerParameters> [sic] contained in all the aforementioned <CombinerParameters> elements, such that the order of occurrence of the <CombinerParameters> elements is preserved in the concatenation of the <CombinerParameter> elements.

and for PolicyCombinerParameters we have:

If multiple <PolicyCombinerParameters> elements reference the same policy, they SHALL be considered equal to one <PolicyCombinerParameters> element containing the concatenation of all the sequences of <CombinerParameters> [sic] contained in all the aforementioned <PolicyCombinerParameters> elements, such that the order of occurrence of the <PolicyCombinerParameters> elements is preserved in the concatenation of the <CombinerParameter> elements.

These requirements imply that multiple <CombinerParameters> elements can be combined and multiple <PolicyCombinerParameters> elements for the same policy can be combined without changing the meaning. However, this would change the relative order of <CombinerParameters> to <PolicyCombinerParameters> so we can't attach any meaning to that relative order (and I can shuffle all the <CombinerParameters> to the front).

@steven-legg
Copy link
Author

OK, does the CombinerParameterType definition stays the same as in XACML 3.0 in this case? any change?

No change.

Also I just realized we have something else called Parameter now in (parameterized) policies (see #11), so we'll need a different name for that to avoid the confusion with CombinerParameter.

Well, they are different, but if you wanted to avoid any suggestion that they are somehow related then Parameter could become ReferenceParameter or PolicyParameter.

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

3 participants