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

Flatten the policy hierarchy #11

Open steven-legg opened 7 months ago

steven-legg commented 7 months ago

I don't see a strong reason for the separation between Policy and PolicySet. A single structure that combines the features of both would simplify the XML Schema, the specification and implementations. This single structure would inherit variable definitions and rules from Policy and inherit embedded and referenced Policy and PolicySet instances (which become the same thing) from PolicySet. Separate policy and policy set combining algorithms would no longer be necessary.

The new structure could be added as an extension to XACML 3.0 but given that the motivation is simplification it makes more sense for this to be part of revisions for version 4.0 that drop the existing Policy and PolicySet elements. The new structure could then take up the name Policy or PolicySet, but a new name, like RuleSet, would avoid confusion with concepts in XACML 3.0.

I often find the lack of a simple descriptive term for the collection of Policies and PolicySets awkward. If Policy wasn't an element name then it would be possible to unambiguously talk about "XACML policy" which is understood to be a collection of RuleSets (say).

The new structure would look something like this in XSD:

    <xs:element name="RuleSet" type="xacml:RuleSetType"/>
    <xs:complexType name="RuleSetType">
        <xs:sequence>
            <xs:element ref="xacml:Description" minOccurs="0"/>
            <xs:element ref="xacml:PolicyIssuer" minOccurs="0"/>
            <xs:element ref="xacml:Defaults" minOccurs="0"/>
            <xs:element ref="xacml:Target"/>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="xacml:RuleSet"/>
                <xs:element ref="xacml:Rule"/>
                <xs:element ref="xacml:RuleSetIdReference"/>
                <xs:element ref="xacml:CombinerParameters"/>
                <xs:element ref="xacml:RuleSetCombinerParameters"/>
                <xs:element ref="xacml:RuleCombinerParameters"/>
                <xs:element ref="xacml:VariableDefinition"/>
            </xs:choice>
            <xs:element ref="xacml:ObligationExpressions" minOccurs="0"/>
            <xs:element ref="xacml:AdviceExpressions" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="RuleSetId" 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>

This change would resolve #9.

Most of the standard policy combining algorithms have a rule combining algorithm counterpart that operates in a compatible way. The exceptions are the only-one-applicable policy combining algorithm from the core and the on-permit-apply-second policy combining algorithm from the XACML 3.0 Additional Combining Algorithms Profile. Neither of these policy combining rules has a corresponding rule combining algorithm.

The motivation for the on-permit-apply-second algorithm was to work around the limitation that targets aren't as expressive as conditions. Issue #2 would remove that limitation so I propose that we don't carry forward on-permit-apply-second to XACML 4.0. Combining algorithms are an extension point so an implementation can keep it as a proprietary extension, and apply it to rules as well, if desired.

The only-one-applicable algorithm is an odd one. It requires checking just the targets of the child policies and policy sets before fully evaluating one candidate. The other algorithms always fully evaluate a child. One solution of #2 is that targets become normal expressions (like conditions), which means that a rule would have two expressions. One is enough, but if we discard one (either Target or Condition) it has implications for how only-one-applicable is to be applied to rules. I would be all for dropping only-one-applicable in XACML 4.0. Does anyone remember the use case(s) it is supposed to address? Perhaps they can be supported another way.

If Target becomes like Condition, or is swapped to be a Condition, (#2) then one oddity is that variables can be used in the Target/Condition before they are defined by a VariableDefinition. It's not a technical problem since rules (and now inline rule sets) can already forward reference a variable, but we have the option to order variable definitions before rules if we want to. We could put the variable definitions (and imports, #12) before the Target/Condition:

            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="xacml:VariableDefinition"/>
                <xs:element ref="xacml:ImportVariable"/>
            </xs:choice>
            <xs:element ref="xacml:Target"/>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="xacml:RuleSet"/>
                <xs:element ref="xacml:Rule"/>
                <xs:element ref="xacml:RuleSetIdReference"/>
                <xs:element ref="xacml:CombinerParameters"/>
                <xs:element ref="xacml:RuleSetCombinerParameters"/>
                <xs:element ref="xacml:RuleCombinerParameters"/>
                <!-- Maybe still allow VariableDefinition and ImportVariable here. -->
            </xs:choice>
cdanger commented 7 months ago

Fully approve, this greatly improves/simplifies the XACML model in the future. Except, if we are going for XACML 4.0, i.e. with breaking changes, I'd rather stick with "Policy" instead of the new term "RuleSet" (we're essentially making the definition of Policy more generic, in particular a Policy can have child Policies). This is consistent with the element "PolicyIssuer" which is still here in your RuleSet definition btw.

steven-legg commented 7 months ago

I initially left PolicyIssuer alone because both Policy and PolicySet include it. The "Policy" prefix isn't being used to distinguish between Policy and PolicySet usage so it isn't an immediate candidate to be renamed RuleSetIssuer. I suspect that "Policy" was prefixed to "Issuer" to differentiate the element from the various "Issuer" attributes, which are referring to attribute issuers. I was intending to raise the name of the element for discussion.

steven-legg commented 7 months ago

The consensus of the active TC members is that the combined structure will be named Policy in XACML 4.0. So PolicyIssuer can keep its name.

Applying #2, #4, #6, #12 and #16 as well gives this definition:

    <xs:element name="Policy" type="xacml:PolicyType"/>
    <xs:complexType name="PolicyType">
        <xs:sequence>
            <xs:element ref="xacml:Description" minOccurs="0"/>
            <xs:element ref="xacml:PolicyIssuer" minOccurs="0"/>
            <xs:element ref="xacml:PolicyDefaults" minOccurs="0"/>
            <!-- Parameters if the policy is parameterized, more info in issue #4 -->
            <xs:element ref="xacml:Parameter" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="xacml:Target" minOccurs="0" />
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="xacml:Policy"/>
                <xs:element ref="xacml:Rule"/>
                <xs:element ref="xacml:PolicyReference"/>
                <xs:element ref="xacml:ParameterizedPolicyReference"\>
                <xs:element ref="xacml:CombinerParameters"/>
                <xs:element ref="xacml:PolicyCombinerParameters"/>
                <xs:element ref="xacml:RuleCombinerParameters"/>
                <xs:element ref="xacml:VariableDefinition"/>
                <xs:element ref="xacml:ImportVariable"/>
            </xs:choice>
            <xs:element ref="xacml:NoticeExpression" minOccurs="0" maxOccurs="unbounded"/>
        </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>

A more suitable name for ImportVariable (verb + noun) might be VariableImport or ImportedVariable (adjective + noun, like its siblings).

cdanger commented 7 months ago

@steven-legg FYI I edited your comment just to add the missing Version attribute.

steven-legg commented 7 months ago

FYI I edited your comment just to add the missing Version attribute.

I intentionally left it out in accordance with the simpler referencing in #16.

cdanger commented 6 months ago

For the sake of simplicity, could we replace <xs:element ref="xacml:NoticeExpressions" minOccurs="0"/> with <xs:element ref="xacml:NoticeExpression" minOccurs="0" maxOccurs="unbounded"/> ?

Looks equivalent to me, but ultimately removes the need for a NoticeExpressions (plural) type.

cdanger commented 2 months ago

Another suggestion: for a policy that is always applicable, Condition (formerly Target) is empty. For the sake of simplification, can we make it optional (minOccurs="0") like in Rules ?

<xs:element ref="xacml:Condition" minOccurs="0" />
cdanger commented 2 weeks ago

It was decided in #2 to keep the name <Target> in a Policy (but still use <Condition> in Rule) although Target is now the same type as a Condition (BooleanExpressionType). Updated the XML schema above accordingly.