-
Notifications
You must be signed in to change notification settings - Fork 1
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 VariableDefinitions as optional elements in Rule (like in Policy) #3
Comments
What is the use case that motivates this enhancement? |
The XML extension mechanism only allows us to add child elements at the end, so VariableDefinition elements would have to appear last, which isn't ideal. The alternative to maintain compatibility with XACML 3.0 and use the same namespace would be to add all the changes we want into new elements for Rule, Policy and PolicySet, e.g., called AugmentedRule, AugmentedPolicy and AugmentedPolicySet, and allow Policy and PolicySet references to refer to either kind of policy or policy set. References only care about the ID. AugmentedPolicy could embed both Rule and AugmentedRule elements and AugmentedPolicySet could embed Policy, AugmentedPolicy, PolicySet and AugmentedPolicySet elements. One of the things I want to explore is flattening the structure by getting rid of PolicySet and letting Policy embed or reference other Policies, then we would only need AugmentedRule and AugmentedPolicy. Getting rid of Policy and letting PolicySet embed rules would amount to the same thing. |
The use case is for variables used in a Rule's Condition, Obligations or Advice (in order to simplify and/or optimize the Expressions) and for which the VariableDefinition - the value expression - depends on the Rule's Target. See the example of Policy down below.
Indeed, using VariableReferences in the Rule's Target is not my use case for this issue (I am fine with using the VariableDefinitions of the enclosing Policy for that). In my use case proposal, I need to use variables in Conditions, Obligations/Advice (not the Target), and their VariableDefinition expressions depend on the Rule's Target. That's why I put them after the Target. Below is an example of Policy that we could write with VariableDefinitions in Rules . In this example, the VariableDefinitions for <Policy PolicyId="Organisation_specific_P"
Version="1.0"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
<Target/>
<VariableDefinition VariableId="action_id">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="true"/>
</Apply>
</VariableDefinition>
<Rule RuleId="ACME_Company_R" Effect="Permit">
<Description>
Rule specific to ACME company's data protection policy.
The ACME company is fictional, for illustration purposes only.
</Description>
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACME</AttributeValue>
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:PolicyIdentifier/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="true"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<!-- Set the Variables to be used in the Condition - classification levels and other confidentiality category tags - according to ACME's policy. -->
<VariableDefinition VariableId="resource_classif_level">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#integer"
MustBePresent="true"
Path="if (//*:Classification = 'CONFIDENTIAL') then 3 else if (//*:Classification = 'INTERNAL') then 2 else if (//*:Classification = 'PUBLIC') then 1 else 0"/>
</Apply>
</VariableDefinition>
<VariableDefinition VariableId="subject_classif_level">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#integer"
MustBePresent="true"
Path="if (//*:Classification = 'CONFIDENTIAL') then 3 else if (//*:Classification = 'INTERNAL') then 2 else if (//*:Classification = 'PUBLIC') then 1 else 0"/>
</Apply>
</VariableDefinition>
<VariableDefinition VariableId="resource_cc_tags[Releasable To]">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:Category[@TagName='Releasable To']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</VariableDefinition>
<VariableDefinition VariableId="resource_cc_tags[Sensitive]">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:Category[@TagName='Sensitive']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</VariableDefinition>
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<VariableReference VariableId="action_id"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">READ</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
<VariableReference VariableId="subject_classif_level"/>
<VariableReference VariableId="resource_classif_level"/>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<VariableReference VariableId="action_id"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">WRITE</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
<VariableReference VariableId="subject_classif_level"/>
<VariableReference VariableId="resource_classif_level"/>
</Apply>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag-size">
<VariableReference VariableId="resource_cc_tags[Releasable To]"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">0</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
<VariableReference VariableId="resource_cc_tags[Releasable To]"/>
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
Path="//*:Category[@TagName='Releasable To']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag-size">
<VariableReference VariableId="resource_cc_tags[Sensitive]"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">0</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-subset">
<VariableReference VariableId="resource_cc_tags[Sensitive]"/>
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
Path="//*:Category[@TagName='Sensitive']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</Apply>
</Apply>
</Apply>
</Condition>
</Rule>
<Rule RuleId="Foo_Nation_R" Effect="Permit">
<Description>
Rule specific to "Foo" nation's data protection policy. The nation "Foo" is one of ACME company's clients.
The Foo nation is fictional, for illustration purposes only.
</Description>
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">FOO</AttributeValue>
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:PolicyIdentifier/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="true"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<!-- Set the Variables to be used in the Condition - classification levels and other confidentiality category tags - according to Foo Nation's policy. -->
<VariableDefinition VariableId="resource_classif_level">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#integer"
MustBePresent="true"
Path="if (//*:Classification = 'FOO SECRET') then 4 else if (//*:Classification = 'FOO CONFIDENTIAL') then 3 else if (//*:Classification = 'FOO RESTRICTED') then 2 else if (//*:Classification = 'FOO UNCLASSIFIED') then 1 else 0"/>
</Apply>
</VariableDefinition>
<VariableDefinition VariableId="subject_classif_level">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#integer"
MustBePresent="true"
Path="if (//*:Classification = 'FOO SECRET') then 4 else if (//*:Classification = 'FOO CONFIDENTIAL') then 3 else if (//*:Classification = 'FOO RESTRICTED') then 2 else if (//*:Classification = 'FOO UNCLASSIFIED') then 1 else 0"/>
</Apply>
</VariableDefinition>
<VariableDefinition VariableId="resource_cc_tags[Context]">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:Category[@TagName='Context']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</VariableDefinition>
<VariableDefinition VariableId="resource_cc_tags[Only]">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:Category[@TagName='Only']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</VariableDefinition>
<VariableDefinition VariableId="resource_cc_tags[Additional Sensitivity]">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:Category[@TagName='Additional Sensitivity']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</VariableDefinition>
<!--
etc.
For brevity, Variables for other confidentiality categories are omitted here.
-->
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<VariableReference VariableId="action_id"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">READ</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
<VariableReference VariableId="subject_classif_level"/>
<VariableReference VariableId="resource_classif_level"/>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<VariableReference VariableId="action_id"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">WRITE</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
<VariableReference VariableId="subject_classif_level"/>
<VariableReference VariableId="resource_classif_level"/>
</Apply>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag-size">
<VariableReference VariableId="resource_cc_tags[Context]"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">0</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-subset">
<VariableReference VariableId="resource_cc_tags[Context]"/>
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
Path="//*:Category[@TagName='Context']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag-size">
<VariableReference VariableId="resource_cc_tags[Only]"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">0</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-subset">
<VariableReference VariableId="resource_cc_tags[Only]"/>
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
Path="//*:Category[@TagName='Only']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag-size">
<VariableReference VariableId="resource_cc_tags[Additional Sensitivity]"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">0</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
<VariableReference VariableId="resource_cc_tags[Additional Sensitivity]"/>
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
Path="//*:Category[@TagName='Additional Sensitivity']/*:GenericValue/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false"/>
</Apply>
</Apply>
<!--
etc.
For brevity, Apply Expressions for other confidentiality categories are omitted here.
-->
</Apply>
</Condition>
</Rule>
<Rule RuleId="EU_R" Effect="Permit">
<Description>
Rule specific to EU data protection policy, in case ACME Company is based in the EU.
This example is for illustration purposes only, i.e. not official in any way.
</Description>
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">EU</AttributeValue>
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
Path="//*:PolicyIdentifier/text()"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="true"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<!-- Set the Variables to be used in the Condition - classification levels - according to EU policy. -->
<VariableDefinition VariableId="resource_classif_level">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
<AttributeSelector Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#integer"
MustBePresent="true"
Path="if (//*:Classification = 'EU SECRET') then 4 else if (//*:Classification = 'EU CONFIDENTIAL') then 3 else if (//*:Classification = 'EU RESTRICTED') then 2 else if (//*:Classification = 'UNCLASSIFIED') then 1 else 0"/>
</Apply>
</VariableDefinition>
<VariableDefinition VariableId="subject_classif_level">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
<AttributeSelector Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#integer"
MustBePresent="true"
Path="if (//*:Classification = 'EU SECRET') then 4 else if (//*:Classification = 'EU CONFIDENTIAL') then 3 else if (//*:Classification = 'EU RESTRICTED') then 2 else if (//*:Classification = 'UNCLASSIFIED') then 1 else 0"/>
</Apply>
</VariableDefinition>
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<VariableReference VariableId="action_id"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">READ</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
<VariableReference VariableId="subject_classif_level"/>
<VariableReference VariableId="resource_classif_level"/>
</Apply>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<VariableReference VariableId="action_id"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">WRITE</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
<VariableReference VariableId="subject_classif_level"/>
<VariableReference VariableId="resource_classif_level"/>
</Apply>
</Apply>
</Apply>
</Apply>
</Condition>
</Rule>
</Policy> |
I understand the alternative and in this case, for a long-term solution, I would agree/prefer to break the compatibility (new XACML schema) and modify the Rule type definition directly.
I agree completely with the idea of getting rid of PolicySet and letting Policy embed/reference others! :-) This would also remove/solve the issue #9 at the same time. So this change to the schema and the change for this issue (VariableDefinitions in Rule) could be done in the same new version of XACML. |
Doesn't this following formulation give the same results using variable definitions at the policy level?
All I've done is move the variable definitions before the rules and prefixed the identifiers of the ones that are overloaded and rule-specific. As far as I can see, the only dependency a variable definition can have on a target is whether it gets evaluated. It evaluates to the same value regardless of where the definition is put. If the goal is to avoid evaluating variable definitions that aren't needed then an extension isn't required for that. I only evaluate a variable definition on the first variable reference to it. |
Yes, I understand you have a solution that works for you, but such behavior (evaluating only on the first reference) is not mandatory per XACML standard, it may be different for another implementation than yours (eager vs lazy evaluation). So if we take the point of view of the average policy writer, who wants to write policies in the optimal way regardless of the PDP implementation, and, more importantly, who wants to follow the best practice Minimize the scope of variables, as he/she should, the possibility to declare variables (VariableDefinitions) in the smallest block possible (where they are used only) would be very much appreciated (e.g. in a Rule for variables used only in that Rule). I think it is a noticeable enhancement towards that goal if we can offer that possibility to policy writers. Quote from the recommendation:
|
I take the point of view that policy writers shouldn't have to be concerned with what is or isn't an optimal way to write policies for different PDPs. Even with this change, lazy evaluation is still better because evaluation of variable definitions before the condition in a rule can still be wasted effort. In your example, if the action isn't READ or WRITE then the evaluations of the variable definitions aren't needed. From the performance point of view I see the justification for this change as providing a way for implementations that have chosen a sub-optimal strategy for evaluating variables to be a bit less sub-optimal when there is a better performing strategy available that isn't hard to implement and requires no change to the standard. We should encourage PDP implementors to do things well so that policy writers don't have to make allowances. On the question of minimizing scope, given how my PAP abstracts the handling of variable definitions my policy writers wouldn't see a difference with this change. Scope is not something they need to be concerned with, so minimizing it is not relevant to them. The PAP takes care of it. If we are talking about this change on its own I wouldn't consider it worthwhile since it involves extra coding for me for no benefit. But I'll tolerate it if it is bundled with other things that I would find useful. |
OK on standby for now then. |
See the pull request #10 for the proposed changes to the XACML 3.0 core spec (especially the tab Files changed) . This changes the XACML core XSD and therefore breaks compatibility with XACML 3.0.
See also @steven-legg 's alternative to maintain compatibility.
The text was updated successfully, but these errors were encountered: