diff options
| author | Jakob L. Kreuze | 2023-12-21 13:20:58 -0500 |
|---|---|---|
| committer | Jakob L. Kreuze | 2023-12-21 13:20:58 -0500 |
| commit | be7067d632aa665c20f96d3b344a84c95b0f8ff8 (patch) | |
| tree | fc5564a72cc42c8a21d3e943f645afcaae78f5a5 /benchmarks | |
| parent | 5918f84a1a05881d93d9fab83104feca9981bfaa (diff) | |
Check-in remaining files
Diffstat (limited to 'benchmarks')
| -rw-r--r-- | benchmarks/Xacml.lean | 1111 | ||||
| -rw-r--r-- | benchmarks/authzforce-harness.bash | 23 | ||||
| -rw-r--r-- | benchmarks/collection.sh | 2 | ||||
| -rw-r--r-- | benchmarks/excluded.txt | 1822 | ||||
| -rw-r--r-- | benchmarks/hyperfine-iia001.json | 212 | ||||
| -rw-r--r-- | benchmarks/hyperfine-iia003.json | 208 | ||||
| -rw-r--r-- | benchmarks/hyperfine-iia006.json | 206 | ||||
| -rw-r--r-- | benchmarks/lean-harness.bash | 7 | ||||
| -rw-r--r-- | benchmarks/rego-harness.bash | 12 | ||||
| -rw-r--r-- | benchmarks/rego/iia003.json | 1 | ||||
| -rw-r--r-- | benchmarks/rego/iia003.rego | 815 | ||||
| -rw-r--r-- | benchmarks/rego/iia006.json | 1 | ||||
| -rw-r--r-- | benchmarks/rego/iia006.rego | 827 | ||||
| -rw-r--r-- | benchmarks/rego/iia007.rego | 829 | ||||
| -rw-r--r-- | benchmarks/rego/iia1.json | 1 | ||||
| -rw-r--r-- | benchmarks/rego/iia1.rego | 815 |
16 files changed, 6892 insertions, 0 deletions
diff --git a/benchmarks/Xacml.lean b/benchmarks/Xacml.lean new file mode 100644 index 0000000..8211c74 --- /dev/null +++ b/benchmarks/Xacml.lean @@ -0,0 +1,1111 @@ +------------------------------------------------------------------------ +---- Atoms ------------------------------------------------------------- +------------------------------------------------------------------------ +-- +-- # References +-- +-- - 7.6 Match evaluation +-- +------------------------------------------------------------------------ + +inductive MatchResult where + | is_match : MatchResult + | no_match : MatchResult + | indeterminate : MatchResult +deriving DecidableEq, BEq, Repr + +inductive Decision where + | permit : Decision + | deny : Decision + | indeterminate : Decision + | not_applicable : Decision +deriving DecidableEq, BEq, Repr + +-- This type is used to implement the semantics described in § 7.10 (Extended +-- Indeterminate). It is only relevant to combining algorithms. +inductive Decision' where + | permit : Decision' + | deny : Decision' + | indeterminate : Decision' + | indeterminate_d : Decision' + | indeterminate_p : Decision' + | indeterminate_dp : Decision' + | not_applicable : Decision' +deriving DecidableEq, BEq, Repr + +def Decision'.downcast : Decision' → Decision + | Decision'.permit => Decision.permit + | Decision'.deny => Decision.deny + | Decision'.indeterminate => Decision.indeterminate + | Decision'.indeterminate_d => Decision.indeterminate + | Decision'.indeterminate_p => Decision.indeterminate + | Decision'.indeterminate_dp => Decision.indeterminate + | Decision'.not_applicable => Decision.not_applicable + +instance : Coe Decision' Decision where + coe := Decision'.downcast + +inductive EffectType where + | permit : EffectType + | deny : EffectType +deriving DecidableEq, BEq, Repr + +namespace EffectType + def to_decision (e : EffectType) : Decision := + match e with + | EffectType.permit => Decision.permit + | EffectType.deny => Decision.deny + + def to_decision' (e : EffectType) : Decision' := + match e with + | EffectType.permit => Decision'.permit + | EffectType.deny => Decision'.deny +end EffectType + +------------------------------------------------------------------------ +---- Values ------------------------------------------------------------ +------------------------------------------------------------------------ +-- +-- From A.2 Data-types: "Although XML instances represent all data-types +-- as strings, an XACML PDP must operate on types of data that, while +-- they have string representations, are not just strings. Types such as +-- Boolean, integer, and double MUST be converted from their XML string +-- representations to values that can be compared with values in their +-- domain of discourse, such as numbers." +-- +-- The standard enumerates the types that must be supported by any +-- conforming implementaiton. This is represented in `XmlType`, and +-- `Value` is the representation of a value payload with its associated +-- type. +-- +------------------------------------------------------------------------ + +inductive XmlType + | string : XmlType + | boolean : XmlType + | integer : XmlType + | double : XmlType + | time : XmlType + | date : XmlType + | dateTime : XmlType + | anyURI : XmlType + | hexBinary : XmlType + | base64Binary : XmlType + | dayTimeDuration : XmlType + | yearMonthDuration : XmlType + | x500Name : XmlType + | rfc822Name : XmlType + | ipAddress : XmlType + | dnsName : XmlType +deriving DecidableEq, BEq, Repr + +def Primitive : Type := XmlType × String +deriving DecidableEq, BEq, Repr + +def Primitive.mk (type : XmlType) (inner : String) : Primitive := (type, inner) + +notation:65 "#<" lhs:65 "," rhs:66 ">" => Primitive.mk lhs rhs + +instance : Coe Bool Primitive where + coe b := + match b with + | true => #<XmlType.boolean, "True"> + | false => #<XmlType.boolean, "False"> + +-- Per 7.4 Expression evaluation, +-- +-- "XACML defines an evaluation result of "Indeterminate", which is said +-- to be the result of an invalid expression, or an operational error +-- occurring during the evaluation of the expression." + +instance : Coe (Option Primitive) Primitive where + coe b := + match b with + | Option.none => #<XmlType.boolean, "Indeterminate"> + | Option.some a => a + +structure Bag where + contents: List Primitive +deriving BEq, DecidableEq, Repr + +-- def Bag.beq (b₁ b₂ : Bag) : Bool := +-- b₁.contents.all (fun x => b₂.contents.count x == b₁.contents.count x) + +-- instance : BEq Bag where +-- beq := Bag.beq + +inductive Value where + | primitive (p : Primitive) : Value + | bag (b : Bag) : Value +deriving DecidableEq, Repr + +def Value.beq (v₁ v₂ : Value) : Bool := + match v₁ with + | Value.primitive p₁ => + match v₂ with + | Value.primitive p₂ => p₁ == p₂ + | Value.bag _ => false + | Value.bag b₁ => + match v₂ with + | Value.primitive _ => false + | Value.bag b₂ => b₁ == b₂ + +instance : BEq Value where + beq := Value.beq + +instance : Coe (Option Value) Value where + coe b := + match b with + | Option.none => Value.primitive (#<XmlType.boolean, "Indeterminate">) + | Option.some a => a + +instance : Coe (Option Value) MatchResult where + coe b := + match b with + | Option.some (Value.primitive (XmlType.boolean, "True")) => MatchResult.is_match + | Option.some (Value.primitive (XmlType.boolean, "False")) => MatchResult.no_match + | _ => MatchResult.indeterminate + +------------------------------------------------------------------------ +---- Attributes--------------------------------------------------------- +------------------------------------------------------------------------ +-- +-- # References +-- +-- - 5.46 Element <Attribute> +-- - 5.42 Element <Request> +-- +-- Attributes are categories into <Attributes> elements. In this +-- implementation, categories are rolled up - every attribute carries +-- the category of its enclosing <Attributes> element. +-- +------------------------------------------------------------------------ + +structure Attribute where + category : String + identifier : String + issuer : Option String + value : Primitive +deriving DecidableEq, Repr + +def Attribute.beq (a₁ a₂ : Attribute) : Bool := + match a₁ with + | { category := category₁, + identifier := identifier₁, + issuer := issuer₁, + value := value₁ } => + match a₂ with + | { category := category₂, + identifier := identifier₂, + issuer := issuer₂, + value := value₂ } => + category₁ == category₂ + && identifier₁ == identifier₂ + && issuer₁ == issuer₂ + && value₁ == value₂ + +instance : BEq Attribute where + beq := Attribute.beq + +-- More than one attribute with a particular (category, identifier, issuer) can +-- exist in a `Request`. Indeed, this is how poly-valued attributes are +-- represented. + +def Request : Type := List Attribute +deriving Repr + +--- + +def Identifier : Type := String +deriving DecidableEq, BEq, Repr + +inductive RuleCombinatorAlgorithm where + | deny_overrides : RuleCombinatorAlgorithm + | ordered_deny_overrides : RuleCombinatorAlgorithm + | permit_overrides : RuleCombinatorAlgorithm + | ordered_permit_overrides : RuleCombinatorAlgorithm + | deny_unless_permit : RuleCombinatorAlgorithm + | permit_unless_deny : RuleCombinatorAlgorithm + | first_applicable : RuleCombinatorAlgorithm + | legacy_deny_overrides : RuleCombinatorAlgorithm + | legacy_ordered_deny_overrides : RuleCombinatorAlgorithm + | legacy_permit_overrides : RuleCombinatorAlgorithm + | legacy_ordered_permit_overrides : RuleCombinatorAlgorithm + +namespace RuleCombinatorAlgorithm + -- The output of a combining algorithm which does not track the extended set + -- of “Indeterminate” values MUST be treated as “Indeterminate{DP}” for the + -- value “Indeterminate” by a combining algorithm which tracks the extended + -- set of “Indeterminate” values. A combining algorithm which does not track + -- the extended set of “Indeterminate” values MUST treat the output of a + -- combining algorithm which tracks the extended set of “Indeterminate” values + -- as an “Indeterminate” for any of the possible values of the extended set of + -- “Indeterminate”. + + def eval_deny_overrides (results : List Decision') : Decision' := + if results.elem Decision'.deny then Decision'.deny else + if results.elem Decision'.indeterminate_dp then Decision'.indeterminate_dp else + if results.elem Decision'.indeterminate_d ∧ results.elem Decision'.indeterminate_p then Decision'.indeterminate_dp else + if results.elem Decision'.indeterminate_d then Decision'.indeterminate_d else + if results.elem Decision'.permit then Decision'.permit else + if results.elem Decision'.indeterminate_p then Decision'.indeterminate_p else + Decision'.not_applicable + def eval_ordered_deny_overrides : List Decision' -> Decision' := eval_deny_overrides + + def eval_permit_overrides (results : List Decision') : Decision' := + if results.elem Decision'.permit then Decision'.permit else + if results.elem Decision'.indeterminate_dp then Decision'.indeterminate_dp else + if results.elem Decision'.indeterminate_d ∧ results.elem Decision'.indeterminate_p then Decision'.indeterminate_dp else + if results.elem Decision'.indeterminate_p then Decision'.indeterminate_p else + if results.elem Decision'.deny then Decision'.deny else + if results.elem Decision'.indeterminate_d then Decision'.indeterminate_d else + Decision'.not_applicable + def eval_ordered_permit_overrides : List Decision' -> Decision' := eval_permit_overrides + + def eval_deny_unless_permit (results : List Decision') : Decision' := + if results.elem Decision'.permit then Decision'.permit else Decision'.deny + + def eval_permit_unless_deny (results : List Decision') : Decision' := + if results.elem Decision'.deny then Decision'.deny else Decision'.permit + + -- The non-normative part of the specification asserts that "If an error + -- occurs while evaluating the target or condition of a rule, then the + -- evaluation SHALL halt, and the policy shall evaluate to "Indeterminate", + -- with the appropriate error status." + -- + -- This behavior isn't spelled out in the normative part, because errors are + -- represented as an Indeterminate. + def eval_first_applicable (results : List Decision') : Decision' := + match (results.filter (fun d => d != Decision'.not_applicable)).get? 0 with + | some a => a + | none => Decision'.not_applicable + + def eval_legacy_deny_overrides (results : List Decision') : Decision' := + -- Note that "any rule having Effect=Deny evaluates to Indeterminate" + -- corresponds to indeterminate_d, and "any rule having Effect=Permit + -- evaluates to Indeterminate" corresponds to indeterminate_p. + if results.elem Decision'.deny then Decision'.deny else + if results.elem Decision'.indeterminate_d then Decision'.indeterminate else + if results.elem Decision'.permit then Decision'.permit else + if results.elem Decision'.indeterminate_p then Decision'.indeterminate else + Decision'.not_applicable + def eval_legacy_ordered_deny_overrides : List Decision' -> Decision' := eval_legacy_deny_overrides + + -- See the comment for `eval_legacy_deny_overrides_rule`. + def eval_legacy_permit_overrides (results : List Decision') : Decision' := + if results.elem Decision'.permit then Decision'.permit else + if results.elem Decision'.indeterminate_p then Decision'.indeterminate else + if results.elem Decision'.deny then Decision'.deny else + if results.elem Decision'.indeterminate_d then Decision'.indeterminate else + Decision'.not_applicable + def eval_legacy_ordered_permit_overrides : List Decision' -> Decision' := eval_legacy_permit_overrides +end RuleCombinatorAlgorithm + +inductive PolicyCombinatorAlgorithm where + | deny_overrides : PolicyCombinatorAlgorithm + | ordered_deny_overrides : PolicyCombinatorAlgorithm + | permit_overrides : PolicyCombinatorAlgorithm + | ordered_permit_overrides : PolicyCombinatorAlgorithm + | deny_unless_permit : PolicyCombinatorAlgorithm + | permit_unless_deny : PolicyCombinatorAlgorithm + | first_applicable : PolicyCombinatorAlgorithm + | only_one_applicable : PolicyCombinatorAlgorithm + | legacy_deny_overrides : PolicyCombinatorAlgorithm + | legacy_ordered_deny_overrides : PolicyCombinatorAlgorithm + | legacy_permit_overrides : PolicyCombinatorAlgorithm + | legacy_ordered_permit_overrides : PolicyCombinatorAlgorithm + +namespace PolicyCombinatorAlgorithm + def eval_deny_overrides := RuleCombinatorAlgorithm.eval_deny_overrides + def eval_ordered_deny_overrides := RuleCombinatorAlgorithm.eval_ordered_deny_overrides + def eval_permit_overrides := RuleCombinatorAlgorithm.eval_permit_overrides + def eval_ordered_permit_overrides := RuleCombinatorAlgorithm.eval_ordered_permit_overrides + def eval_deny_unless_permit := RuleCombinatorAlgorithm.eval_deny_unless_permit + def eval_permit_unless_deny := RuleCombinatorAlgorithm.eval_permit_unless_deny + def eval_first_applicable := RuleCombinatorAlgorithm.eval_first_applicable + + -- The non-normative part of the specification asserts that "If an error + -- occurs while evaluating the target or condition of a rule, then the + -- evaluation SHALL halt, and the policy shall evaluate to "Indeterminate", + -- with the appropriate error status." + -- + -- This behavior isn't spelled out in the normative part, because errors are + -- represented as an Indeterminate. + def eval_only_one_applicable (results : List Decision') : Decision' := + match results.filter (fun d => d != Decision'.not_applicable) with + | [] => Decision'.not_applicable + | [a] => a + | _ => Decision'.indeterminate + + def eval_legacy_deny_overrides (results : List Decision') : Decision' := + if results.elem Decision'.deny then Decision'.deny else + if results.elem Decision'.indeterminate then Decision'.deny else + if results.elem Decision'.permit then Decision'.permit else + Decision'.not_applicable + def eval_legacy_ordered_deny_overrides : List Decision' -> Decision' := eval_legacy_deny_overrides + + -- See the comment for `eval_legacy_deny_overrides`. + def eval_legacy_permit_overrides (results : List Decision') : Decision' := + if results.elem Decision'.permit then Decision'.permit else + if results.elem Decision'.deny then Decision'.deny else + if results.elem Decision'.indeterminate then Decision'.indeterminate else + Decision'.not_applicable + def eval_legacy_ordered_permit_overrides : List Decision' -> Decision' := eval_legacy_permit_overrides +end PolicyCombinatorAlgorithm + +inductive StatusCode + | ok : StatusCode + | missing_attribute : StatusCode + | syntax_error : StatusCode + | processing_error : StatusCode +deriving DecidableEq, BEq, Repr + +structure AttributeDesignator where + category : String + identifier : String + type : XmlType + issuer : Option String + must_be_present : Bool +deriving DecidableEq, BEq, Repr + +namespace AttributeDesignator + -- A named attribute SHALL match an attribute if the values of their + -- respective Category, AttributeId, DataType and Issuer attributes + -- match. The attribute designator’s Category MUST match, by + -- identifier equality, the Category of the <Attributes> element in + -- which the attribute is present. The attribute designator’s + -- AttributeId MUST match, by identifier equality, the AttributeId of + -- the attribute. The attribute designator’s DataType MUST match, by + -- identifier equality, the DataType of the same attribute. + -- + -- If the Issuer attribute is present in the attribute designator, + -- then it MUST match, using the + -- “urn:oasis:names:tc:xacml:1.0:function:string-equal” function, the + -- Issuer of the same attribute. If the Issuer is not present in the + -- attribute designator, then the matching of the attribute to the + -- named attribute SHALL be governed by AttributeId and DataType + -- attributes alone. + def matches? (designator : AttributeDesignator) (attr : Attribute) : Bool := + attr.category == designator.category + && attr.identifier == designator.identifier + && attr.value.fst == designator.type + && (attr.issuer == Option.none ∨ attr.issuer == designator.issuer) + + def eval (designator : AttributeDesignator) (context : List Attribute) : Sum Value (List StatusCode) := + let found := context.filter designator.matches? + let found := found.map (fun x => x.value) + if designator.must_be_present then + match found with + | [] => Sum.inr $ [StatusCode.missing_attribute] + | _ => Sum.inl $ Value.bag (Bag.mk found) + else Sum.inl $ Value.bag (Bag.mk found) +end AttributeDesignator + +def matches? (designator : AttributeDesignator) (attr : Attribute) : Prop := + designator.category == attr.category ∧ + designator.identifier == attr.identifier ∧ + designator.type == attr.value.fst ∧ + match (designator.issuer, attr.issuer) with + | (none, _) => True + | (some issuer₁, some issuer₂) => issuer₁ == issuer₂ + | _ => False + +def FunctionID : Type := String +deriving DecidableEq, BEq, Repr + +-- "The <Expression> element is not used directly in a policy. The <Expression> +-- element signifies that an element that extends the ExpressionType and is a +-- member of the <Expression> element substitution group SHALL appear in its +-- place." +-- +-- We omit the `<xacml:AttributeSelector>` case because this model of XACML does +-- not include it, and we exclude the `<xacml:VariableReference>` case because +-- we erase variable references in the compiler. + +inductive Expression where + -- Note well that `apply` accepts a list of Values, not a list of Expressions, + -- as its arguments. The compiler is responsible for ensuring that the + -- arguments in a function call are fully evaluated. + -- + -- Lean is quite strict about recursion being bounded, which is a little hard + -- to prove in our case! Fortunately, we can punt the job of proving that to + -- the compiler. + | apply (function : FunctionID) (args: List Value) : Expression + | attribute_designator (inner : AttributeDesignator) : Expression + | attribute_value (inner : Value) : Expression + | function (function : FunctionID) : Expression +deriving DecidableEq, BEq, Repr + +namespace Expression + def apply_eval (name : FunctionID) (args : List Value) : Option Value := + if name == "urn:oasis:names:tc:xacml:1.0:function:string-equal" then + match args with + | [Value.primitive (XmlType.string, lhs), + Value.primitive (XmlType.string, rhs)] => + Value.primitive (lhs == rhs) + | _ => Value.primitive (#<XmlType.boolean, "Indeterminate">) + else if name == "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal" then + match args with + | [Value.primitive (XmlType.anyURI, lhs), + Value.primitive (XmlType.anyURI, rhs)] => + Value.primitive (lhs == rhs) + | _ => Value.primitive (#<XmlType.boolean, "Indeterminate">) + else if name == "urn:oasis:names:tc:xacml:1.0:function:integer-equal" then + match args with + | [Value.primitive (XmlType.integer, lhs), + Value.primitive (XmlType.integer, rhs)] => + Value.primitive (lhs == rhs) + | _ => Value.primitive (#<XmlType.boolean, "Indeterminate">) + else Option.none + + def eval (expression : Expression) (context : Request) : Option Value := + -- The return type of `<Apply>` may be made more specific by type unification. + -- + -- The evaluation result can be specified to be "Indeterminate"; we encode + -- this as `Option.none` here for ergonomics, but we do give an instance for + -- `Coe (Option Value) Value`. + -- + -- § 7.6 enumerates but does not describe the semantics for: + -- + -- - <xacml:AttributeValue> + -- - <xacml:AttributeDesignator> + -- - <xacml:AttributeSelector> + -- - <xacml:Apply> + -- - <xacml:Function> + -- - <xacml:VariableReference> + match expression with + | Expression.apply name args => apply_eval name args + | Expression.attribute_designator inner => + match inner.eval context with + | Sum.inl res => res + | Sum.inr _ => Option.none + | Expression.attribute_value inner => some inner + | _ => Option.none +end Expression + +structure Match where + function : Identifier + designator : AttributeDesignator + value : Value +deriving DecidableEq, BEq, Repr +def AllOf : Type := List Match +deriving DecidableEq, BEq, Repr +def AnyOf : Type := List AllOf +deriving DecidableEq, BEq, Repr +def Target : Type := List AnyOf +deriving DecidableEq, BEq, Repr + +instance : Membership AllOf AnyOf where + mem := fun x y => y.contains x + +namespace Match + -- The evaluation semantics for a matching element is as follows. + -- + -- 1. If an operational error were to occur while evaluating the + -- <AttributeDesignator> or <AttributeSelector> element, then the + -- result of the entire expression SHALL be "Indeterminate". + -- + -- 2. If the <AttributeDesignator> or <AttributeSelector> element were + -- to evaluate to an empty bag, then the result of the expression + -- SHALL be "False". + -- + -- 3. Otherwise, the MatchId function SHALL be applied between the + -- <AttributeValue> and each element of the bag returned from the + -- <AttributeDesignator> or <AttributeSelector> element. + -- a. If at least one of those function applications were to evaluate + -- to "True", then the result of the entire expression SHALL be + -- "True". + -- b. Otherwise, if at least one of the function applications results + -- in "Indeterminate", then the result SHALL be "Indeterminate". + -- c. Finally, if all function applications evaluate to "False", then + -- the result of the entire expression SHALL be "False". + def eval (m : Match) (context : Request) : Option Value := + match m with + | Match.mk fn designator value => + match designator.eval context with + | Sum.inl result => + let results := match result with + -- Otherwise, the MatchId function SHALL be applied between the + -- <AttributeValue> and each element of the bag returned from the + -- <AttributeDesignator> or <AttributeSelector> element. + | (Value.bag (Bag.mk attrs)) => + attrs.map fun attr => + let args := [value, Value.primitive attr] + (Expression.apply fn args).eval context + | (Value.primitive attr) => + -- TODO: Prove that this case is impossible. + let args := [value, Value.primitive attr] + [(Expression.apply fn args).eval context] + + let results := results.map (fun (x : Option Value) => (x : Value)) + -- If at least one of those function applications were to evaluate to + -- "True", then the result of the entire expression SHALL be "True". + if results.elem (Value.primitive (#<XmlType.boolean, "True">)) then + (Value.primitive (#<XmlType.boolean, "True">)) + -- Otherwise, if at least one of the function applications results in + -- "Indeterminate", then the result SHALL be "Indeterminate". + else if results.elem (Value.primitive (#<XmlType.boolean, "Indeterminate">)) then + (Value.primitive (#<XmlType.boolean, "Indeterminate">)) + -- The `else` arm handles the following cases: + -- + -- If the <AttributeDesignator> or <AttributeSelector> element were to + -- evaluate to an empty bag, then the result of the expression SHALL + -- be "False". + -- + -- Finally, if all function applications evaluate to "False", then the + -- result of the entire expression SHALL be "False". + else + Value.primitive (#<XmlType.boolean, "False">) + -- If an operational error were to occur while evaluating the + -- <AttributeDesignator> or <AttributeSelector> element, then the result + -- of the entire expression SHALL be "Indeterminate". + | Sum.inr _ => Option.none +end Match + +namespace AllOf + def eval (conj : AllOf) (context : Request) : MatchResult := + let result := conj.map (fun x => x.eval context) + let result := result.map (fun (x : Option Value) => (x : Value)) + if result.all (fun x => x == Value.primitive (XmlType.boolean, "True")) then MatchResult.is_match + else if result.all (fun x => x != Value.primitive (XmlType.boolean, "False")) ∧ + result.elem (Value.primitive (XmlType.boolean, "Indeterminate")) + then MatchResult.indeterminate + else MatchResult.no_match +end AllOf + +namespace AnyOf + def eval (disj : AnyOf) (context : Request) : MatchResult := + -- match disj with + -- | [] => MatchResult.is_match + -- | List.cons x xs => match x.eval context with + -- | MatchResult.is_match => MatchResult.is_match + -- | MatchResult.no_match => + -- let rest := AnyOf.eval xs context + -- if rest == MatchResult.no_match then MatchResult.no_match else rest + -- | MatchResult.indeterminate => + -- let rest := AnyOf.eval xs context + -- if rest == MatchResult.no_match then MatchResult.indeterminate else rest + if disj.isEmpty then MatchResult.is_match else + let result := disj.map (fun x => x.eval context) + if result.any (fun x => x == MatchResult.is_match) then MatchResult.is_match + else if result.elem MatchResult.indeterminate then MatchResult.indeterminate + else MatchResult.no_match +end AnyOf + +namespace Target + def eval (target : Target) (context : Request) : MatchResult := + match target with + -- An empty target matches any request. + | [] => MatchResult.is_match + | xs => + let results := xs.map (fun disj => disj.eval context) + -- Otherwise the target value SHALL be "Match" if all the AnyOf + -- specified in the target match values in the request context. + if results.all (fun result => result == MatchResult.is_match) then + MatchResult.is_match + -- Otherwise, if any one of the AnyOf specified in the target is “No + -- Match”, then the target SHALL be “No Match”. + else if results.any (fun result => result == MatchResult.no_match) then + MatchResult.no_match + -- Otherwise, the target SHALL be “Indeterminate”. + else MatchResult.indeterminate +end Target + +structure Obligation where + assignments : List Attribute + identifier : String +deriving DecidableEq, BEq, Repr + +structure Advice where + assignments : List Attribute + identifier : String +deriving DecidableEq, BEq, Repr + +structure AttributeAssignmentExpression where + category : String + identifier : String + issuer : Option String + expression : Expression +deriving DecidableEq, BEq, Repr + +namespace AttributeAssignmentExpression + def eval (assignment : AttributeAssignmentExpression) (context : Request) : Option Attribute := + match assignment.expression.eval context with + | some (Value.primitive inner) => + Attribute.mk + assignment.category + assignment.identifier + assignment.issuer + inner + | _ => none +end AttributeAssignmentExpression + +structure ObligationExpression where + assignments : List AttributeAssignmentExpression + identifier : String + fulfill_on : Decision +deriving DecidableEq, BEq, Repr + +namespace ObligationExpression + def eval (obligation : ObligationExpression) (context : Request) : Option Obligation := + let assignments := obligation.assignments.map (fun x => AttributeAssignmentExpression.eval x context) + if assignments.all Option.isSome then + Obligation.mk + (List.filterMap id assignments) + obligation.identifier + else none +end ObligationExpression + +structure AdviceExpression where + assignments : List AttributeAssignmentExpression + identifier : String + applies_to : Decision +deriving DecidableEq, BEq, Repr + +namespace AdviceExpression + def eval (advice : AdviceExpression) (context : Request) : Option Advice := + let assignments := advice.assignments.map (fun x => AttributeAssignmentExpression.eval x context) + if assignments.all Option.isSome then + Advice.mk + (List.filterMap id assignments) + advice.identifier + else none +end AdviceExpression + +structure ResultAuxiliary where + status : Option (List StatusCode) + obligations : List Obligation + advice : List Advice +deriving DecidableEq, BEq, Repr + +structure ResultAuxiliary' where + status : Option (List StatusCode) + obligations : List ObligationExpression + advice : List AdviceExpression +deriving DecidableEq, BEq, Repr + +def collect_option {α : Type} (xs : List (Option α)) : Option (List α) := + match xs with + | [] => some [] + | some x :: xs' => + match collect_option xs' with + | some xs' => some (x :: xs') + | none => none + | none :: _ => none + +namespace ResultAuxiliary' + def eval (result : ResultAuxiliary') (context : Request) : Option ResultAuxiliary := + let advice := + collect_option (List.map (fun x => AdviceExpression.eval x context) result.advice) + let obligations := + collect_option (List.map (fun x => ObligationExpression.eval x context) result.obligations) + match (obligations, advice) with + | (some obligations, some advice) => + some { status := result.status, obligations, advice } + | _ => none +end ResultAuxiliary' + +structure MissingAttributeDetail where + category : String + identifier : String + issuer : Option String + value : Option Value + type : XmlType +deriving DecidableEq, BEq, Repr + +def Result : Type := Decision' × (Option ResultAuxiliary) +def Result' : Type := Decision' × (Option ResultAuxiliary') + +namespace Result' + def eval (result : Result') (context : Request) : Result := + match result.snd with + | some aux => + let advices := aux.advice.map (fun advice => AdviceExpression.eval advice context) + let obligations := aux.obligations.map (fun x => ObligationExpression.eval x context) + if advices.any Option.isNone || obligations.any Option.isNone then + (Decision'.indeterminate, none) + else + ( + result.fst, + ResultAuxiliary.mk + aux.status + (List.filterMap id obligations) + (List.filterMap id advices) + ) + | none => (result.fst, none) +end Result' + +structure Rule where + target : Target + condition : Option Expression + effect : EffectType + obligations : List ObligationExpression + advice : List AdviceExpression + +namespace Rule + def eval (rule : Rule) (context : Request) : Result' := + let (decision : Decision') := + -- The "no target" case is handled within `Target.eval`, returning + -- `MatchResult.is_match` when the target is empty. + match rule.target.eval context with + | MatchResult.is_match => + let condition := + match rule.condition with + | some condition => + -- The condition value SHALL be "True" if the <Condition> element + -- evaluates to "True". + let result := condition.eval context + if result == some (Value.primitive (#<XmlType.boolean, "True">)) then result + -- Its value SHALL be "False" if the <Condition> element evaluates to + -- "False". + else if result == some (Value.primitive (#<XmlType.boolean, "False">)) then result + -- The condition value SHALL be "Indeterminate", if the expression + -- contained in the <Condition> element evaluates to "Indeterminate." + else Value.primitive (#<XmlType.boolean, "Indeterminate">) + -- The condition value SHALL be "True" if the <Condition> element is absent. + | none => Value.primitive (#<XmlType.boolean, "True">) + match condition with + | some (Value.primitive (XmlType.boolean, "False")) => Decision'.not_applicable + | some (Value.primitive (XmlType.boolean, "True")) => + match rule.effect with + | EffectType.permit => Decision'.permit + | EffectType.deny => Decision'.deny + -- | (#<XmlType.boolean, "Indeterminate">) => + | _ => + if rule.effect == EffectType.permit then + Decision'.indeterminate_p else + Decision'.indeterminate_d + | MatchResult.no_match => Decision'.not_applicable + | MatchResult.indeterminate => + if rule.effect == EffectType.permit then + Decision'.indeterminate_p else + Decision'.indeterminate_d + let advices := + rule.advice.filter + (fun advice => advice.applies_to == (decision : Decision)) + let obligations := + rule.obligations.filter + (fun obligation => obligation.fulfill_on == (decision : Decision)) + ( + decision, + ResultAuxiliary'.mk + none + obligations + advices + ) +end Rule + +structure Policy where + combinator : RuleCombinatorAlgorithm + target : Target + obligations : List ObligationExpression + advice : List AdviceExpression + +namespace Policy + def eval (policy : Policy) (child_results : List Result') (context : Request) : Result' := + let combinator := + match policy.combinator with + | RuleCombinatorAlgorithm.deny_overrides => RuleCombinatorAlgorithm.eval_deny_overrides + | RuleCombinatorAlgorithm.ordered_deny_overrides => RuleCombinatorAlgorithm.eval_ordered_deny_overrides + | RuleCombinatorAlgorithm.permit_overrides => RuleCombinatorAlgorithm.eval_permit_overrides + | RuleCombinatorAlgorithm.ordered_permit_overrides => RuleCombinatorAlgorithm.eval_ordered_permit_overrides + | RuleCombinatorAlgorithm.deny_unless_permit => RuleCombinatorAlgorithm.eval_deny_unless_permit + | RuleCombinatorAlgorithm.permit_unless_deny => RuleCombinatorAlgorithm.eval_permit_unless_deny + | RuleCombinatorAlgorithm.first_applicable => RuleCombinatorAlgorithm.eval_first_applicable + | RuleCombinatorAlgorithm.legacy_deny_overrides => RuleCombinatorAlgorithm.eval_legacy_deny_overrides + | RuleCombinatorAlgorithm.legacy_ordered_deny_overrides => RuleCombinatorAlgorithm.eval_legacy_ordered_deny_overrides + | RuleCombinatorAlgorithm.legacy_permit_overrides => RuleCombinatorAlgorithm.eval_legacy_permit_overrides + | RuleCombinatorAlgorithm.legacy_ordered_permit_overrides => RuleCombinatorAlgorithm.eval_legacy_ordered_permit_overrides + let (decision : Decision') := combinator (List.map Prod.fst child_results) + let (decision : Decision') := + match policy.target.eval context with + | MatchResult.is_match => decision + | MatchResult.no_match => Decision'.not_applicable + | MatchResult.indeterminate => + match decision with + | Decision'.not_applicable => Decision'.not_applicable + | Decision'.permit => Decision'.indeterminate_p + | Decision'.deny => Decision'.indeterminate_d + | Decision'.indeterminate => Decision'.indeterminate_dp + | Decision'.indeterminate_dp => Decision'.indeterminate_dp + | Decision'.indeterminate_p => Decision'.indeterminate_p + | Decision'.indeterminate_d => Decision'.indeterminate_d + let advices := + policy.advice.filter + (fun advice => advice.applies_to == (decision : Decision)) + ++ + List.join + (child_results.filterMap + (fun x => match x.snd with + | some y => y.advice + | none => none)) + let obligations := + policy.obligations.filter + (fun obligation => obligation.fulfill_on == (decision : Decision)) + ++ + List.join + (child_results.filterMap + (fun x => match x.snd with + | some y => y.obligations + | none => none)) + ( + decision, + ResultAuxiliary'.mk + none + obligations + advices + ) +end Policy + +structure PolicySet where + combinator : PolicyCombinatorAlgorithm + target : Target + obligations : List ObligationExpression + advice : List AdviceExpression + +namespace PolicySet + def eval (policyset : PolicySet) (child_results : List Result') (context : Request) : Result' := + let combinator := + match policyset.combinator with + | PolicyCombinatorAlgorithm.deny_overrides => PolicyCombinatorAlgorithm.eval_deny_overrides + | PolicyCombinatorAlgorithm.ordered_deny_overrides => PolicyCombinatorAlgorithm.eval_ordered_deny_overrides + | PolicyCombinatorAlgorithm.permit_overrides => PolicyCombinatorAlgorithm.eval_permit_overrides + | PolicyCombinatorAlgorithm.ordered_permit_overrides => PolicyCombinatorAlgorithm.eval_ordered_permit_overrides + | PolicyCombinatorAlgorithm.deny_unless_permit => PolicyCombinatorAlgorithm.eval_deny_unless_permit + | PolicyCombinatorAlgorithm.permit_unless_deny => PolicyCombinatorAlgorithm.eval_permit_unless_deny + | PolicyCombinatorAlgorithm.first_applicable => PolicyCombinatorAlgorithm.eval_first_applicable + | PolicyCombinatorAlgorithm.only_one_applicable => PolicyCombinatorAlgorithm.eval_only_one_applicable + | PolicyCombinatorAlgorithm.legacy_deny_overrides => PolicyCombinatorAlgorithm.eval_legacy_deny_overrides + | PolicyCombinatorAlgorithm.legacy_ordered_deny_overrides => PolicyCombinatorAlgorithm.eval_legacy_ordered_deny_overrides + | PolicyCombinatorAlgorithm.legacy_permit_overrides => PolicyCombinatorAlgorithm.eval_legacy_permit_overrides + | PolicyCombinatorAlgorithm.legacy_ordered_permit_overrides => PolicyCombinatorAlgorithm.eval_legacy_ordered_permit_overrides + let (decision : Decision') := combinator (List.map Prod.fst child_results) + let (decision : Decision') := + match policyset.target.eval context with + | MatchResult.is_match => decision + | MatchResult.no_match => Decision'.not_applicable + | MatchResult.indeterminate => + match decision with + | Decision'.not_applicable => Decision'.not_applicable + | Decision'.permit => Decision'.indeterminate_p + | Decision'.deny => Decision'.indeterminate_d + | Decision'.indeterminate => Decision'.indeterminate_dp + | Decision'.indeterminate_dp => Decision'.indeterminate_dp + | Decision'.indeterminate_p => Decision'.indeterminate_p + | Decision'.indeterminate_d => Decision'.indeterminate_d + let advices := + policyset.advice.filter + (fun advice => advice.applies_to == (decision : Decision)) + ++ + List.join + (child_results.filterMap + (fun x => match x.snd with + | some y => y.advice + | none => none)) + let obligations := + policyset.obligations.filter + (fun obligation => obligation.fulfill_on == (decision : Decision)) + ++ + List.join + (child_results.filterMap + (fun x => match x.snd with + | some y => y.obligations + | none => none)) + ( + decision, + ResultAuxiliary'.mk + none + obligations + advices + ) +end PolicySet + +inductive PolicyElement where + | PolicySet (ps : PolicySet) + | Policy (p : Policy) + | Rule (r : Rule) + +def PolicyElement.eval (context : Request) : PolicyElement -> List Result' -> Result' + | PolicySet ps, results => ps.eval results context + | Policy p, results => p.eval results context + | Rule r, _ => r.eval context + +inductive ElementTree where + | Node (e : PolicyElement) (xs : List ElementTree) + +def ElementTree.eval' (context : Request) : ElementTree -> List Result' -> Result' + | ElementTree.Node e [], results => PolicyElement.eval context e results + | ElementTree.Node e (x :: xs), results => + ElementTree.eval' + context + (ElementTree.Node e xs) + ((ElementTree.eval' context x []) :: results) + +def ElementTree.eval (context : Request) (et : ElementTree) : Result' := + ElementTree.eval' context et [] + +-- let results := policy.rules.map (fun rule => rule.eval context) + +def is_indeterminate (x : Expression) : Bool := + match x with + | Expression.attribute_value (Value.primitive (XmlType.boolean, "Indeterminate")) => true + | _ => false + +def make_response + (decision : Decision) + (status : Option (List StatusCode)) + (obligations : List Obligation) + (advice : List Advice) +: Decision × ResultAuxiliary := + let obligations := obligations.map (fun expr => Obligation.mk expr.assignments expr.identifier) + let advice := advice.map (fun expr => Advice.mk expr.assignments expr.identifier) + -- If any of the attribute assignment expressions in an obligation or + -- advice expression with a matching FulfillOn or AppliesTo attribute + -- evaluates to “Indeterminate”, then the whole rule, policy, or + -- policy set SHALL be “Indeterminate”. If the FulfillOn or AppliesTo + -- attribute does not match the result of the combining algorithm or + -- the rule evaluation, then any indeterminate in an obligation or + -- advice expression has no effect. + -- if obligations. + let decision := + -- if obligations.any + -- (fun obligation => obligation.assignments.any + -- (fun assignment => is_indeterminate assignment.expression)) ∨ + -- advice.any + -- (fun advice => advice.assignments.any + -- (fun assignment => is_indeterminate assignment.expression)) + -- then + -- Decision.indeterminate + -- else + decision + ( + decision, + ResultAuxiliary.mk + status + (obligations.map (fun expr => Obligation.mk expr.assignments expr.identifier)) + (advice.map (fun expr => Advice.mk expr.assignments expr.identifier)) + ) + +def combine_response_aux (x y : ResultAuxiliary) : ResultAuxiliary := + match (x, y) with + | (ResultAuxiliary.mk status₁ obligations₁ advice₁, + ResultAuxiliary.mk _ obligations₂ advice₂) => + ResultAuxiliary.mk + status₁ + (obligations₁ ++ obligations₂) + (advice₁ ++ advice₂) + +def Choice : Type := List (Decision × ResultAuxiliary) +deriving DecidableEq, BEq, Repr + +def xml_of_decision (decision : Decision) := + match decision with + | Decision.permit => "<Decision>Permit</Decision>" + | Decision.deny => "<Decision>Deny</Decision>" + | Decision.indeterminate => "<Decision>Indeterminate</Decision>" + | Decision.not_applicable => "<Decision>NotApplicable</Decision>" + +def string_of_status_code (code : StatusCode) := + match code with + | StatusCode.ok => "urn:oasis:names:tc:xacml:1.0:status:ok" + | StatusCode.missing_attribute => "urn:oasis:names:tc:xacml:1.0:status:missing-attribute" + | StatusCode.syntax_error => "urn:oasis:names:tc:xacml:1.0:status:syntax-error" + | StatusCode.processing_error => "urn:oasis:names:tc:xacml:1.0:status:processing-error" + +def xml_of_status_code (status : List StatusCode) := + match status with + | primary :: [] => String.join [ + "<StatusCode Value=\"", + string_of_status_code primary, + "\"/>"] + | primary :: rest => String.join [ + "<StatusCode Value=\"", + string_of_status_code primary, + "\">", + xml_of_status_code rest, "</StatusCode>"] + | _ => "" + +def xml_of_status (status : List StatusCode) := + match status with + | [] => "" + | codes => String.join ["<Status>", xml_of_status_code codes, "</Status>"] + +def xml_of_xmltype : XmlType -> String + | XmlType.string => "http://www.w3.org/2001/XMLSchema#string" + | XmlType.boolean => "http://www.w3.org/2001/XMLSchema#boolean" + | XmlType.integer => "http://www.w3.org/2001/XMLSchema#integer" + | XmlType.double => "http://www.w3.org/2001/XMLSchema#double" + | XmlType.time => "http://www.w3.org/2001/XMLSchema#time" + | XmlType.date => "http://www.w3.org/2001/XMLSchema#date" + | XmlType.dateTime => "http://www.w3.org/2001/XMLSchema#dateTime" + | XmlType.dayTimeDuration => "http://www.w3.org/2001/XMLSchema#dayTimeDuration" + | XmlType.yearMonthDuration => "http://www.w3.org/2001/XMLSchema#yearMonthDuration" + | XmlType.anyURI => "http://www.w3.org/2001/XMLSchema#anyURI" + | XmlType.hexBinary => "http://www.w3.org/2001/XMLSchema#hexBinary" + | XmlType.base64Binary => "http://www.w3.org/2001/XMLSchema#base64Binary" + | XmlType.rfc822Name => "urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name" + | XmlType.x500Name => "urn:oasis:names:tc:xacml:1.0:data-type:x500Name" + | XmlType.ipAddress => "urn:oasis:names:tc:xacml:2.0:data-type:ipAddress" + | XmlType.dnsName => "urn:oasis:names:tc:xacml:2.0:data-type:dnsName" + +def xml_of_attribute_assignment (assignment : Attribute) := + String.join [ + "<AttributeAssignment AttributeId=\"", + assignment.identifier, + "\" DataType=\"", + xml_of_xmltype assignment.value.fst, + "\" Category=\"", + assignment.category, + (match assignment.issuer with + | some issuer => String.join ["\" Issuer=\"", issuer] + | none => ""), + "\"/>" + ] + +def xml_of_obligation (obligation : Obligation) := + String.join [ + "<Obligation ObligationId=\"", + obligation.identifier, + "\">", + String.join (List.map xml_of_attribute_assignment obligation.assignments), + "</Obligation>" + ] + +def xml_of_obligations (obligations : List Obligation) := + String.join ["<Obligations>", String.join (List.map xml_of_obligation obligations), "</Obligations>"] + +def xml_of_advice (advice : Advice) := + String.join [ + "<Advice AdviceId=\"", + advice.identifier, + "\">", + String.join (List.map xml_of_attribute_assignment advice.assignments), + "</Advice>" + ] + +def xml_of_advices (advices : List Advice) := + String.join ["<AssociatedAdvice>", String.join (List.map xml_of_advice advices), "</AssociatedAdvice>"] + +def xml_of_response (response : Result) := + String.join [ + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", + "<Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">", + "<Result>", + xml_of_decision response.fst, + (match response.snd with + | some {status, obligations, advice} => + String.join [ + (match status with + | some status => xml_of_status status + | none => "<Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status>"), + (match obligations with + | [] => "" + | _ => xml_of_obligations obligations), + (match advice with + | [] => "" + | _ => xml_of_advices advice) + ] + | none => ""), + "</Result>", + "</Response>" + ] diff --git a/benchmarks/authzforce-harness.bash b/benchmarks/authzforce-harness.bash new file mode 100644 index 0000000..f339446 --- /dev/null +++ b/benchmarks/authzforce-harness.bash @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +NAME="$(basename $1)" +if [ $NAME = "IIA001" ]; then + NAME="IIA1" +fi + +cat > /tmp/pdp.xml <<EOF +<?xml version="1.0" encoding="UTF-8"?> +<pdp xmlns="http://authzforce.github.io/core/xmlns/pdp/8" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + version="8.0"> + <policyProvider id="rootPolicyProvider" xsi:type="StaticPolicyProvider"> + <policyLocation>$1/Policy.xml</policyLocation> + </policyProvider> + <rootPolicyRef>urn:oasis:names:tc:xacml:2.0:conformance-test:$NAME:policy</rootPolicyRef> + <ioProcChain> + <requestPreproc>urn:ow2:authzforce:feature:pdp:request-preproc:xacml-json:default-lax</requestPreproc> + <resultPostproc>urn:ow2:authzforce:feature:pdp:result-postproc:xacml-json:default</resultPostproc> + </ioProcChain> +</pdp> +EOF +java -jar /tmp/authzforce-ce-core-pdp-cli-21.0.1.jar /tmp/pdp.xml $1/Request.xml diff --git a/benchmarks/collection.sh b/benchmarks/collection.sh new file mode 100644 index 0000000..e502788 --- /dev/null +++ b/benchmarks/collection.sh @@ -0,0 +1,2 @@ +export BENCHMARK=/tmp/core/pdp-testutils/src/test/resources/conformance/xacml-3.0-from-2.0-ct/mandatory/IIA001 +/tmp/hyperfine/target/release/hyperfine --export-json=hyperfine-iia001.json "bash authzforce-harness.bash $BENCHMARK" "bash lean-harness.bash $BENCHMARK" "bash rego-harness.bash $BENCHMARK" diff --git a/benchmarks/excluded.txt b/benchmarks/excluded.txt new file mode 100644 index 0000000..2bfb31b --- /dev/null +++ b/benchmarks/excluded.txt @@ -0,0 +1,1822 @@ +mandatory/IIA008/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-is-in + +mandatory/IIA009/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-is-in + +mandatory/IIA016_FIXED/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-equal +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIA017/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:time-bag-size + +mandatory/IIA018_FIXED/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIA019/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIA020_FIXED/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIA021/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIB008/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIB009/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIB014/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-equal + +mandatory/IIB015/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-equal + +mandatory/IIB026/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIB027/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIC001/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC002/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC004/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC007/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC008/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-is-in + +mandatory/IIC009/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-is-in + +mandatory/IIC010/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC011/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC012/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC013/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-add +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC014/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-add +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC015/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-add +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC016/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC017/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-subtract + +mandatory/IIC018/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-multiply +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC019/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-multiply +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC020/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-divide +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC021/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-divide +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC022/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:integer-mod +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC024/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:round + +mandatory/IIC025/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:floor + +mandatory/IIC026/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-abs +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC027/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-abs +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-subtract + +mandatory/IIC028/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-to-integer +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC029/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:integer-to-double + +mandatory/IIC030/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC031/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC032/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:integer-to-double + +mandatory/IIC033/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:integer-to-double + +mandatory/IIC034/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-equal +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC035/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-equal +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC038/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only + + +mandatory/IIC039/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only + + +mandatory/IIC040/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only + + +mandatory/IIC041/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only + + +mandatory/IIC042/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + + +mandatory/IIC043/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + + +mandatory/IIC044/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-equal +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + + +mandatory/IIC045/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-equal +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + + +mandatory/IIC046/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + + +mandatory/IIC047/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC048/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal +urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only + +mandatory/IIC049/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal +urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only + +mandatory/IIC050/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal +urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only + +mandatory/IIC051/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal +urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only + +mandatory/IIC056/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:or +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIC057/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:or +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIC058/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC059/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC060/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-subtract + +mandatory/IIC061/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-subtract + +mandatory/IIC062/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-greater-than +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC063/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-greater-than +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC064/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-greater-than +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC065/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-greater-than +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC066/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-greater-than +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIC067/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-greater-than +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIC068/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC069/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC070/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC071/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract + +mandatory/IIC072/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-subtract + +mandatory/IIC073/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-subtract + +mandatory/IIC074/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC075/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC076/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC077/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC078/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIC079/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIC080/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC081/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC082/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only + +mandatory/IIC083/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only + +mandatory/IIC084/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-match +urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only + +mandatory/IIC085/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-match +urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only + +mandatory/IIC086/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:and +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC087/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:and +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC090/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:or +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC091/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:or +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC094/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:n-of +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC095/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:n-of +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC100/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-normalize-space +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC101/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-normalize-to-lower-case +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC102/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC103/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC104/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC105/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC106/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC107/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC108/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-less-than +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC109/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC110/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-less-than +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC111/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-less-than +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC112/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC113/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC114/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-less-than +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIC115/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIC116/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC117/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only + +mandatory/IIC118/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-less-than +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC119/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only + +mandatory/IIC120/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:string-bag-size + +mandatory/IIC121/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-bag-size +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIC123/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC124/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-is-in + +mandatory/IIC125/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-bag +urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size +urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC126/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC127/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-is-in + +mandatory/IIC128/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-bag +urn:oasis:names:tc:xacml:1.0:function:integer-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only + +mandatory/IIC129/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC130/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-is-in + +mandatory/IIC131/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-bag +urn:oasis:names:tc:xacml:1.0:function:double-bag-size +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC132/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC133/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-is-in + +mandatory/IIC134/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-bag +urn:oasis:names:tc:xacml:1.0:function:date-bag-size +urn:oasis:names:tc:xacml:1.0:function:date-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC135/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:time-bag-size + +mandatory/IIC136/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-is-in + +mandatory/IIC137/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:time-bag +urn:oasis:names:tc:xacml:1.0:function:time-bag-size +urn:oasis:names:tc:xacml:1.0:function:time-one-and-only + +mandatory/IIC138/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC139/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-is-in + +mandatory/IIC140/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size +urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC141/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC142/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in + +mandatory/IIC143/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size +urn:oasis:names:tc:xacml:1.0:function:anyURI-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC144/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC145/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-is-in + +mandatory/IIC146/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size +urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC147/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC148/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-is-in + +mandatory/IIC149/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size +urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC158/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size + +mandatory/IIC159/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-is-in + +mandatory/IIC160/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size +urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only + +mandatory/IIC161/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size + +mandatory/IIC162/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-is-in + +mandatory/IIC163/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only + +mandatory/IIC165/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIC166/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIC167/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:all-of-any +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIC168/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:any-of-all +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIC169/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:all-of-all +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-regexp-match + +mandatory/IIC170/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-normalize-space + +mandatory/IIC171/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-bag-size +urn:oasis:names:tc:xacml:1.0:function:string-intersection + +mandatory/IIC172/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:string-bag + +mandatory/IIC173/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-bag-size +urn:oasis:names:tc:xacml:1.0:function:string-union + +mandatory/IIC174/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-subset + +mandatory/IIC175/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:string-bag +urn:oasis:names:tc:xacml:1.0:function:string-set-equals + +mandatory/IIC176/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-bag +urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size +urn:oasis:names:tc:xacml:1.0:function:boolean-intersection +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC177/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:boolean-bag + +mandatory/IIC178/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-bag +urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size +urn:oasis:names:tc:xacml:1.0:function:boolean-union +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC179/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-bag +urn:oasis:names:tc:xacml:1.0:function:boolean-subset + +mandatory/IIC180/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:boolean-bag +urn:oasis:names:tc:xacml:1.0:function:boolean-set-equals + +mandatory/IIC181/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-bag +urn:oasis:names:tc:xacml:1.0:function:integer-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:integer-intersection + +mandatory/IIC182/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:integer-bag + +mandatory/IIC183/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-bag +urn:oasis:names:tc:xacml:1.0:function:integer-bag-size +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:integer-union + +mandatory/IIC184/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-bag +urn:oasis:names:tc:xacml:1.0:function:integer-subset + +mandatory/IIC185/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-bag +urn:oasis:names:tc:xacml:1.0:function:integer-set-equals + +mandatory/IIC186/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-bag +urn:oasis:names:tc:xacml:1.0:function:double-bag-size +urn:oasis:names:tc:xacml:1.0:function:double-intersection +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC187/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:double-bag + +mandatory/IIC188/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-bag +urn:oasis:names:tc:xacml:1.0:function:double-bag-size +urn:oasis:names:tc:xacml:1.0:function:double-union +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC189/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-bag +urn:oasis:names:tc:xacml:1.0:function:double-subset + +mandatory/IIC190/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-bag +urn:oasis:names:tc:xacml:1.0:function:double-set-equals + +mandatory/IIC191/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-bag +urn:oasis:names:tc:xacml:1.0:function:date-bag-size +urn:oasis:names:tc:xacml:1.0:function:date-intersection +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC192/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:date-bag + +mandatory/IIC193/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-bag +urn:oasis:names:tc:xacml:1.0:function:date-bag-size +urn:oasis:names:tc:xacml:1.0:function:date-union +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC194/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-bag +urn:oasis:names:tc:xacml:1.0:function:date-subset + +mandatory/IIC195/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:date-bag +urn:oasis:names:tc:xacml:1.0:function:date-set-equals + +mandatory/IIC196/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:time-bag +urn:oasis:names:tc:xacml:1.0:function:time-bag-size +urn:oasis:names:tc:xacml:1.0:function:time-intersection + +mandatory/IIC197/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:time-bag + +mandatory/IIC198/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:time-bag +urn:oasis:names:tc:xacml:1.0:function:time-bag-size +urn:oasis:names:tc:xacml:1.0:function:time-union + +mandatory/IIC199/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-bag +urn:oasis:names:tc:xacml:1.0:function:time-subset + +mandatory/IIC200/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:time-bag +urn:oasis:names:tc:xacml:1.0:function:time-set-equals + +mandatory/IIC201/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size +urn:oasis:names:tc:xacml:1.0:function:dateTime-intersection +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC202/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag + +mandatory/IIC203/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size +urn:oasis:names:tc:xacml:1.0:function:dateTime-union +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC204/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag +urn:oasis:names:tc:xacml:1.0:function:dateTime-subset + +mandatory/IIC205/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:dateTime-bag +urn:oasis:names:tc:xacml:1.0:function:dateTime-set-equals + +mandatory/IIC206/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size +urn:oasis:names:tc:xacml:1.0:function:anyURI-intersection +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC207/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag + +mandatory/IIC208/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size +urn:oasis:names:tc:xacml:1.0:function:anyURI-union +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC209/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag +urn:oasis:names:tc:xacml:1.0:function:anyURI-subset + +mandatory/IIC210/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:anyURI-bag +urn:oasis:names:tc:xacml:1.0:function:anyURI-set-equals + +mandatory/IIC211/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size +urn:oasis:names:tc:xacml:1.0:function:x500Name-intersection + +mandatory/IIC212/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag + +mandatory/IIC213/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size +urn:oasis:names:tc:xacml:1.0:function:x500Name-union + +mandatory/IIC214/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag +urn:oasis:names:tc:xacml:1.0:function:x500Name-subset + +mandatory/IIC215/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:x500Name-bag +urn:oasis:names:tc:xacml:1.0:function:x500Name-set-equals + +mandatory/IIC216/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-intersection + +mandatory/IIC217/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag + +mandatory/IIC218/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-equal +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-union + +mandatory/IIC219/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-subset + +mandatory/IIC220/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag +urn:oasis:names:tc:xacml:1.0:function:rfc822Name-set-equals + +mandatory/IIC221/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size +urn:oasis:names:tc:xacml:1.0:function:hexBinary-intersection +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC222/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag + +mandatory/IIC223/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size +urn:oasis:names:tc:xacml:1.0:function:hexBinary-union +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC224/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag +urn:oasis:names:tc:xacml:1.0:function:hexBinary-subset + +mandatory/IIC225/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag +urn:oasis:names:tc:xacml:1.0:function:hexBinary-set-equals + +mandatory/IIC226/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size +urn:oasis:names:tc:xacml:1.0:function:base64Binary-intersection +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC227/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-at-least-one-member-of +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag + +mandatory/IIC228/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size +urn:oasis:names:tc:xacml:1.0:function:base64Binary-union +urn:oasis:names:tc:xacml:1.0:function:integer-equal + +mandatory/IIC229/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag +urn:oasis:names:tc:xacml:1.0:function:base64Binary-subset + +mandatory/IIC230/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag +urn:oasis:names:tc:xacml:1.0:function:base64Binary-set-equals + +mandatory/IIC350/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC351/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC352/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC353/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC354/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC355/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC356/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-less-than +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC357/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-greater-than +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC358/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-add +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only + +mandatory/IIC359/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:double-equal +urn:oasis:names:tc:xacml:1.0:function:double-one-and-only +urn:oasis:names:tc:xacml:1.0:function:double-subtract + +mandatory/IID001/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID002/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID003/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID004/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID005/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID006/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID007/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID008/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID009/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID010/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID011/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID012/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID013/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID014/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID015/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID016/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID017/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID018/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID019/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID020/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID021/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID022/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID023/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID024/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID025/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID026/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID027/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID028/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID300/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID301/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID302/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID303/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID304/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID305/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID306/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID307/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID308/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID309/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID310/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID311/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID312/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID313/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID314/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID315/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID316/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID317/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID318/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID319/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IID320/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID330/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID331/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID332/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID333/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID340/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID341/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID342/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IID343/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIF311/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA001/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA002/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA003/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA004/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA005/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA006/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA007/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA008/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA009/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA010/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA011/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA012/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA013/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA014/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA015/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA016/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA017/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA018/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA019/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA020/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA021/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA022/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA023/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA024/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA025/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA026/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA027/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA028/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA301/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA302/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA303/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA304/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA305/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA306/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA307/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA308/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA309/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA310/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA311/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA312/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA313/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA314/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA315/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA316/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA317/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA318/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA319/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA320/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA321/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA322/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA323/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA324/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA325/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal + +mandatory/IIIA326/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA327/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA328/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal +urn:oasis:names:tc:xacml:1.0:function:string-one-and-only + +mandatory/IIIA329/Policy.xml: +urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal +urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only +urn:oasis:names:tc:xacml:1.0:function:integer-subtract +urn:oasis:names:tc:xacml:1.0:function:string-equal diff --git a/benchmarks/hyperfine-iia001.json b/benchmarks/hyperfine-iia001.json new file mode 100644 index 0000000..5cfd002 --- /dev/null +++ b/benchmarks/hyperfine-iia001.json @@ -0,0 +1,212 @@ +{ + "results": [ + { + "command": "authzforce", + "mean": 1.8461527814999996, + "stddev": 0.06199174539502622, + "median": 1.8238858158, + "user": 5.36704266, + "system": 0.20038110000000003, + "min": 1.7681575743, + "max": 1.9531087263, + "times": [ + 1.7985675612999998, + 1.8072159603, + 1.7681575743, + 1.8040717123, + 1.8547239183, + 1.9046467713, + 1.8049998702999999, + 1.8405556713, + 1.9531087263, + 1.9254800493 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "command": "lean", + "mean": 4.419457606, + "stddev": 0.008869787618510696, + "median": 4.417610675300001, + "user": 4.370591760000001, + "system": 0.052795999999999996, + "min": 4.4061337973, + "max": 4.4311239923, + "times": [ + 4.4094097333, + 4.4160989583, + 4.4191223923, + 4.4280726193, + 4.4061337973, + 4.4246227593, + 4.4309326733, + 4.4138470893, + 4.4152120453000006, + 4.4311239923 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "command": "opa", + "mean": 0.04686065166507937, + "stddev": 0.0007439499827213784, + "median": 0.046807240300000004, + "user": 0.04948119015873017, + "system": 0.009103655555555559, + "min": 0.04563805730000001, + "max": 0.04922981230000001, + "times": [ + 0.0461474123, + 0.048303486300000004, + 0.04922981230000001, + 0.04705487430000001, + 0.047513765300000003, + 0.047122320300000006, + 0.0468518003, + 0.046828386300000004, + 0.04866176530000001, + 0.04631246530000001, + 0.04743980330000001, + 0.04692121330000001, + 0.046232237300000006, + 0.04820853530000001, + 0.046098580300000004, + 0.0464998053, + 0.046051025300000006, + 0.04594847430000001, + 0.0466571013, + 0.047440779300000006, + 0.04737457230000001, + 0.04633055130000001, + 0.048487699300000006, + 0.04748818430000001, + 0.047259265300000006, + 0.0467570813, + 0.046098668300000006, + 0.04598046630000001, + 0.04675927230000001, + 0.0469496723, + 0.0461157873, + 0.046176294300000004, + 0.0473107253, + 0.0468981113, + 0.0460657043, + 0.045878819300000005, + 0.0476590813, + 0.046807240300000004, + 0.04664132830000001, + 0.046108756300000005, + 0.046206166300000004, + 0.046065450300000005, + 0.04714411030000001, + 0.048273055300000006, + 0.04725586130000001, + 0.04637673330000001, + 0.04669826330000001, + 0.04711734730000001, + 0.0476596763, + 0.046422681300000004, + 0.047071346300000004, + 0.0469502373, + 0.046924527300000005, + 0.04647903330000001, + 0.046374657300000004, + 0.046936907300000004, + 0.046474964300000005, + 0.04658955630000001, + 0.046119356300000004, + 0.046911354300000006, + 0.0464168043, + 0.047443984300000006, + 0.04563805730000001 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + ] +} diff --git a/benchmarks/hyperfine-iia003.json b/benchmarks/hyperfine-iia003.json new file mode 100644 index 0000000..ecc7a79 --- /dev/null +++ b/benchmarks/hyperfine-iia003.json @@ -0,0 +1,208 @@ +{ + "results": [ + { + "command": "authzforce", + "mean": 1.8539233053999997, + "stddev": 0.07045118765524386, + "median": 1.8637640012, + "user": 5.5190032, + "system": 0.19728234, + "min": 1.7220111481999998, + "max": 1.9277803882, + "times": [ + 1.7220111481999998, + 1.7490110442, + 1.8364869041999998, + 1.8772167472, + 1.8431721002, + 1.9068409922, + 1.9116545762, + 1.8503112552, + 1.9147478982, + 1.9277803882 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "command": "lean", + "mean": 4.419570566399999, + "stddev": 0.010926697857862277, + "median": 4.4211140677, + "user": 4.3713518, + "system": 0.052455339999999996, + "min": 4.4019222472, + "max": 4.4339212692, + "times": [ + 4.4339212692, + 4.4114070332, + 4.416890663199999, + 4.4229281052, + 4.425064122199999, + 4.4252808622, + 4.4193000302, + 4.4051925292, + 4.4337988022, + 4.4019222472 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "command": "opa", + "mean": 0.04684904405245902, + "stddev": 0.0007265745663278671, + "median": 0.046686584200000006, + "user": 0.04951623770491803, + "system": 0.008924961311475412, + "min": 0.04590612720000001, + "max": 0.04947239020000001, + "times": [ + 0.047505085200000005, + 0.0477891012, + 0.04766807220000001, + 0.04757789120000001, + 0.046627629200000006, + 0.046532016200000005, + 0.04672034220000001, + 0.0460801522, + 0.04666791320000001, + 0.046594200200000005, + 0.047600413200000004, + 0.0461862882, + 0.046681552200000004, + 0.04754236220000001, + 0.04673284120000001, + 0.047990504200000006, + 0.04669201320000001, + 0.046056508200000006, + 0.046408807200000006, + 0.047217328200000006, + 0.047256917200000005, + 0.046044935200000005, + 0.045964099200000004, + 0.04947239020000001, + 0.047289161200000006, + 0.046399726200000005, + 0.046341788200000004, + 0.046582481200000005, + 0.04590612720000001, + 0.046078393200000005, + 0.047378041200000005, + 0.046084784200000006, + 0.047149540200000006, + 0.046272840200000005, + 0.04670162420000001, + 0.046520495200000005, + 0.04646542520000001, + 0.047481608200000004, + 0.048442480200000006, + 0.046686584200000006, + 0.045997991200000005, + 0.047016423200000004, + 0.046089728200000006, + 0.04778034120000001, + 0.0489142242, + 0.04689554320000001, + 0.046330581200000005, + 0.0460137752, + 0.0473294802, + 0.046463515200000007, + 0.0472964062, + 0.0465713462, + 0.046739780200000004, + 0.047043988200000005, + 0.0468881052, + 0.0469259912, + 0.0463439402, + 0.046318177200000005, + 0.046465140200000005, + 0.046179928200000005, + 0.04679681820000001 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + ] +} diff --git a/benchmarks/hyperfine-iia006.json b/benchmarks/hyperfine-iia006.json new file mode 100644 index 0000000..7d8d698 --- /dev/null +++ b/benchmarks/hyperfine-iia006.json @@ -0,0 +1,206 @@ +{ + "results": [ + { + "command": "authzforce", + "mean": 1.8722544155799998, + "stddev": 0.0448476189551403, + "median": 1.87713420668, + "user": 5.29085678, + "system": 0.19428865999999995, + "min": 1.8023647006799999, + "max": 1.93418314468, + "times": [ + 1.91022297268, + 1.8098531996799998, + 1.87232539068, + 1.8023647006799999, + 1.83828486468, + 1.90194070568, + 1.91359825268, + 1.88194302268, + 1.93418314468, + 1.85782790168 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "command": "lean", + "mean": 4.53456651428, + "stddev": 0.009934426084958611, + "median": 4.53884667318, + "user": 4.48431508, + "system": 0.05463736, + "min": 4.518855267679999, + "max": 4.54707742168, + "times": [ + 4.53892170468, + 4.54263477868, + 4.52490095668, + 4.54707742168, + 4.5387716416799995, + 4.540713494679999, + 4.52622729668, + 4.54329805368, + 4.52426452668, + 4.518855267679999 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "command": "opa", + "mean": 0.04826780581333333, + "stddev": 0.0009917655763182548, + "median": 0.04805647418, + "user": 0.050686930000000005, + "system": 0.009130410000000002, + "min": 0.04688597268, + "max": 0.051628061680000004, + "times": [ + 0.04802554868, + 0.04710740268, + 0.04863815768, + 0.048210658680000004, + 0.04965373968, + 0.05114789668, + 0.048087399680000004, + 0.04963996468, + 0.04848601568, + 0.04776453168, + 0.047728559680000004, + 0.04891648668, + 0.04876128368, + 0.04833371168, + 0.04959416168, + 0.04831524168, + 0.04784011068, + 0.04791020968, + 0.04737187868, + 0.048367496680000004, + 0.04715601768, + 0.04828764868, + 0.04840128568, + 0.04751085468, + 0.04908777768, + 0.04972917968, + 0.04848996868, + 0.04743947068, + 0.04810144268, + 0.04880705868, + 0.05105722568, + 0.04761976368, + 0.04743746368, + 0.04802172868, + 0.04780610868, + 0.04784965268, + 0.047334945680000004, + 0.04755185368, + 0.04794043268, + 0.04697354768, + 0.04813416268, + 0.04743428468, + 0.04769424868, + 0.04976519068, + 0.04848638568, + 0.051628061680000004, + 0.04754968568, + 0.04715066668, + 0.04769493568, + 0.04880571868, + 0.04883541968, + 0.04823892868, + 0.04769713568, + 0.04727608968, + 0.04817077868, + 0.04893817868, + 0.04800505268, + 0.04767638868, + 0.04749717868, + 0.04688597268 + ], + "exit_codes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + ] +} diff --git a/benchmarks/lean-harness.bash b/benchmarks/lean-harness.bash new file mode 100644 index 0000000..e59b3da --- /dev/null +++ b/benchmarks/lean-harness.bash @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +COMPILE_REQUEST="../xacml-proofs/compiler/_build/default/bin/request.exe" +COMPILE_POLICY="../xacml-proofs/compiler/_build/default/bin/main.exe" + +cat Xacml.lean <($COMPILE_REQUEST $1/Request.xml) <($COMPILE_POLICY $1/Policy.xml) > /tmp/test.lean +lean /tmp/test.lean diff --git a/benchmarks/rego-harness.bash b/benchmarks/rego-harness.bash new file mode 100644 index 0000000..48dbc5d --- /dev/null +++ b/benchmarks/rego-harness.bash @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +NAME="$(basename $1)" +if [ $NAME = "IIA001" ]; then + NAME="iia1" +elif [ $NAME = "IIA003" ]; then + NAME="iia003" +elif [ $NAME = "IIA006" ]; then + NAME="iia006" +fi + +opa eval -f raw --data rego/$NAME.rego -i rego/$NAME.json 'data.equivalence.allow' diff --git a/benchmarks/rego/iia003.json b/benchmarks/rego/iia003.json new file mode 100644 index 0000000..660d7c1 --- /dev/null +++ b/benchmarks/rego/iia003.json @@ -0,0 +1 @@ +{"request": [{"category":"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject","identifier":"urn:oasis:names:tc:xacml:1.0:subject:subject-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#string","value":"Julius Hibbert"}},{"category":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource","identifier":"urn:oasis:names:tc:xacml:1.0:resource:resource-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#anyURI","value":"http://medico.com/record/patient/BartSimpson"}},{"category":"urn:oasis:names:tc:xacml:3.0:attribute-category:action","identifier":"urn:oasis:names:tc:xacml:1.0:action:action-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#string","value":"read"}}]} diff --git a/benchmarks/rego/iia003.rego b/benchmarks/rego/iia003.rego new file mode 100644 index 0000000..87482c8 --- /dev/null +++ b/benchmarks/rego/iia003.rego @@ -0,0 +1,815 @@ +package equivalence + +import future.keywords.every +import future.keywords.if +import future.keywords.in + +######################################################################## +# Data Types +######################################################################## + +## MatchResult + +# - is_match => { "match_result": true } +# - no_match => { "match_result": false } +# - indeterminate => { "match_result": "indeterminate" } + +## Decision + +# - permit => { "decision": "permit" } +# - deny => { "decision": "deny" } +# - not_applicable => { "decision": "not_applicable" } +# - indeterminate => { "decision": "indeterminate" } + +## Extended Decision + +# - permit => { "decision_extended": "permit" } +# - deny => { "decision_extended": "deny" } +# - not_applicable => { "decision_extended": "not_applicable" } +# - indeterminate => { "decision_extended": "indeterminate" } +# - indeterminate_d => { "decision_extended": "indeterminate_d" } +# - indeterminate_p => { "decision_extended": "indeterminate_p" } +# - indeterminate_dp => { "decision_extended": "indeterminate_dp" } + +lift_decision_indeterminate({ "decision": "not_applicable" }) := { "decision": "not_applicable" } +lift_decision_indeterminate({ "decision": "permit" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "deny" }) := { "decision": "indeterminate_d" } +lift_decision_indeterminate({ "decision": "indeterminate" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_dp" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_p" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "indeterminate_d" }) := { "decision": "indeterminate_d" } + +## Value + +# - { "kind": "primitive", +# "type": string, +# "value": string } +# - { "kind": "bag", +# "values": ... } + +### Booleans + +true_value := { "kind": "primitive", "type": "boolean", "value": true } +false_value := { "kind": "primitive", "type": "boolean", "value": false } +indeterminate_value := { "kind": "primitive", "type": "boolean" } + +is_indeterminate(value) if { is_null(value.value) } + +## StatusCode + +# - ok => { "status": "ok" } +# - missing_attribute => { "status": "missing_attribute" } +# - syntax_error => { "status": "syntax_error" } +# - processing_error => { "status": "processing_error" } + +## AttributeDesignator + +# - { category : string +# identifier : string +# type : string +# issuer : string or null +# must_be_present : boolean } + +## Expression + +# - { "expression": "apply", +# "function": string, +# "args": [string, ...] } +# - { "expression": "attribute_designator", +# "inner": AttributeDesignator } +# - { "expression": "attribute_value", +# "inner": Value } +# - { "expression": "function" +# "function": string } + +## Match + +# - { "function": string, +# "designator": AttributeDesignator, +# "value": Value } + +## Obligation + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## ObligationExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "fulfill_on": Decision } + +## Advice + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## AdviceExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "applies_to": Decision } + +## AttributeAssignmentExpression + +# - { "category": string, +# "identifier": string, +# "issuer": string or null, +# "expression": Expression } + +## Target: [[[Expression, ...], ...], ...] + +## Rule + +# - { "target": Target, +# "condition": Expression or null, +# "effect": "permit" or "deny", +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## Policy + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## PolicySet + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +# We assume the request attributes are stored in `input.request` as an array or set of +# +# { category : string +# identifier : string +# issuer : string or null +# value : [Value, ...] } + +######################################################################## +# Match Functions +######################################################################## + +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:string-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": b }]) := true_value if { + a == b +} else := false_value +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": b }]) := true_value if { + a == b +} else := false_value + +######################################################################## +# AttributeDesignator +######################################################################## + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + not attribute.attr.issuer +} + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + attribute.attr.issuer == designator.issuer +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) > 1 +} + +evaluate_designator(designator) := xs[0] if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 1 +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + not designator.must_be_present +} + +evaluate_designator(designator) := { "status": "missing_attribute" } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + designator.must_be_present +} + +######################################################################### +# Match +######################################################################## + +evaluate_match(match) := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result.values + apply_xacml_function(match.function, [x, match.value]).value == true +} else := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + apply_xacml_function(match.function, [designator_result, match.value]).value == true +} else := { "match_result": indeterminate_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result + is_indeterminate(apply_xacml_function(match.function, [x, match.value])) +} else := { "match_result": false_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result +} else := { "match_result": indeterminate_value } + +# Last case runs when evaluating the designator results in an error. + +evaluate_all_of(conj) := { "match_result": true_value } if { + every x in conj { + evaluate_match(x).match_result.value == true + } +} else := { "match_result": "indeterminate" } if { + some x in conj + is_indeterminate(evaluate_match(x).match_result) +} else := { "match_result": "no_match" } + +evaluate_any_of([]) := { "match_result": true_value } +evaluate_any_of(disj) := { "match_result": true_value } if { + some x in disj + evaluate_all_of(x) == { "match_result": true_value } +} else := { "match_result": "indeterminate" } if { + some x in disj + evaluate_all_of(x) == { "match_result": true_value } +} else := { "match_result": "no_match" } + + +######################################################################## +# Target +######################################################################## + +evaluate_target([]) := { "match_result": true_value } +evaluate_target(xs) := { "match_result": true_value } if { + every disj in xs { + evaluate_any_of(disj).match_result.value == true + } +} else := { "match_result": false_value } if { + some disj in xs + evaluate_any_of(disj).match_result == "no_match" +} else := { "match_result": indeterminate_value } + +######################################################################## +# Expression +######################################################################## + +evaluate_expression({ "expression": "apply", "function": function_name, "args": args }) := x if { + x := apply_xacml_function(function_name, args) +} +evaluate_expression({ "expression": "attribute_designator", "inner": designator }) := x if { + x := evaluate_designator(designator) +} +evaluate_expression({ "expression": "attribute_value", "inner": value }) := x if { + x := value +} +evaluate_expression({ "expression": "function", "function": name }) := x if { + x := name +} + +######################################################################## +# Obligations and Advice +######################################################################## + +evaluate_attribute_assignment_expression(expr) := assignment { + { "kind": "primitive", "value": inner } = evaluate_expression(expr.expression) + assignment := { "category": expr.category, + "identifier": expr.identifier, + "issuer": expr.issuer, + "value": inner } +} + +evaluate_obligation_expression(obligation_expression) := obligation { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := obligation_expression.assignments[_]] + obligation := { "assignments": assignments, "identifier": obligation_expression.identifier } +} + +evaluate_advice_expression(advice_expression) := advice { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := advice_expression.assignments[_]] + advice := { "assignments": assignments, "identifier": advice_expression.identifier } +} + + +######################################################################## +# Rule +######################################################################## + +# Condition is specified and applicable +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + + is_object(rule.condition) + evaluate_expression(rule.condition) == true + + decision := rule.effect +} +# Condition is specified and not applicable +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == true + evaluate_expression(rule.condition) == false +} +# Condition is indeterminate +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "deny" +} +# Condition is unspecified +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + decision := rule.effect +} + +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == false +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} + +evaluate_rule_advices(rule) := { "advice": advice } if { + decision := evaluate_rule_decision(rule) + advice := [expr | expr := rule.advice[_]; expr.applies_to == decision ] +} + +evaluate_rule_obligations(rule) := { "obligations": obligations } if { + decision := evaluate_rule_decision(rule) + obligations := [expr | expr := rule.obligations[_]; expr.fulfill_on == decision ] +} + +######################################################################## +# Policy +######################################################################## + +evaluate_rule_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_rule_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_rule_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +# child_results := [result | rule := policy.rules[_]; result := evaluate_rule_decision(rule)] +evaluate_policy_decision(policy, child_results) := decision if { + evaluate_target(policy.target).match_result.value == true + decision := evaluate_rule_combinator(policy.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policy.target)) + decision := lift_decision_indeterminate(evaluate_rule_combinator(policy.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +# children_advice := [advice | rule := policy.rules[_]; expr := evaluate_rule_advices(rule); advice := expr[_]] +evaluate_policy_advices(policy, child_results, children_advice) := { "advice" : advice } if { + decision := evaluate_policy_decision(policy, child_results) + policy_advice := [expr | expr := policy.advice[_]; expr.applies_to == decision ] + advice := array.concat(policy_advice, children_advice) +} + +# children_obligations := [obligation | rule := policy.rules[_]; expr := evaluate_rule_obligations(rule); obligation := expr[_]] +evaluate_policy_obligations(policy, child_results, children_obligations) := { "obligations" : obligations } if { + decision := evaluate_policy_decision(policy, child_results) + policy_obligations := [expr | expr := policy.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policy_obligations, children_obligations) +} + +######################################################################## +# PolicySet +######################################################################## + +evaluate_policy_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_policy_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_policy_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("only_one_applicable", results) := result if { + applicable := [result | result := results[i]; result.decision_extended != "not_applicable"] + count(applicable) == 1 + result := applicable[0] +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_decision(policyset, child_results) := decision if { + evaluate_target(policyset.target).match_result.value == true + decision := evaluate_policy_combinator(policyset.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policyset.target)) + decision := lift_decision_indeterminate(evaluate_policy_combinator(policyset.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_advices(policyset, child_results, child_advice) := { "advice" : advice } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_advice := [expr | expr := policyset.advice[_]; expr.applies_to == decision ] + advice := array.concat(policyset_advice, child_advice) +} + +evaluate_policyset_obligations(policyset, child_results, child_obligations) := { "obligations" : obligations } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_obligations := [expr | expr := policyset.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policyset_obligations, child_obligations) +} + +IIA003_policy := { + "combinator": "deny_overrides", + "target": [], + "obligations": [], + "advice": [] +} + +IIA003_rule := { + "target": [[[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:2.0:conformance-test:attribute:bogus", + "category": "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "Physician" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:resource:resource-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": "http://medico.com/record/patient/BartSimpson" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "read" + }}], + [{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "write" + }}]]], + "effect": "permit", + "obligations": [], + "advice": [] +} + +allow := evaluate_policyset_decision(IIA003_policy, [evaluate_rule_decision(IIA003_rule)]) diff --git a/benchmarks/rego/iia006.json b/benchmarks/rego/iia006.json new file mode 100644 index 0000000..51b1edc --- /dev/null +++ b/benchmarks/rego/iia006.json @@ -0,0 +1 @@ +{"request": [{"category":"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject","identifier":"urn:oasis:names:tc:xacml:1.0:subject:subject-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#string","value":"Julius Hibbert"}},{"category":"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject","identifier":"urn:oasis:names:tc:xacml:2.0:conformance-test:some-attribute","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#string","value":"riddle me this"}},{"category":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource","identifier":"urn:oasis:names:tc:xacml:1.0:resource:resource-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#anyURI","value":"http://medico.com/record/patient/BartSimpson"}},{"category":"urn:oasis:names:tc:xacml:3.0:attribute-category:action","identifier":"urn:oasis:names:tc:xacml:1.0:action:action-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#string","value":"read"}}]} diff --git a/benchmarks/rego/iia006.rego b/benchmarks/rego/iia006.rego new file mode 100644 index 0000000..6a83b14 --- /dev/null +++ b/benchmarks/rego/iia006.rego @@ -0,0 +1,827 @@ +package equivalence + +import future.keywords.every +import future.keywords.if +import future.keywords.in + +######################################################################## +# Data Types +######################################################################## + +## MatchResult + +# - is_match => { "match_result": true } +# - no_match => { "match_result": false } +# - indeterminate => { "match_result": "indeterminate" } + +## Decision + +# - permit => { "decision": "permit" } +# - deny => { "decision": "deny" } +# - not_applicable => { "decision": "not_applicable" } +# - indeterminate => { "decision": "indeterminate" } + +## Extended Decision + +# - permit => { "decision_extended": "permit" } +# - deny => { "decision_extended": "deny" } +# - not_applicable => { "decision_extended": "not_applicable" } +# - indeterminate => { "decision_extended": "indeterminate" } +# - indeterminate_d => { "decision_extended": "indeterminate_d" } +# - indeterminate_p => { "decision_extended": "indeterminate_p" } +# - indeterminate_dp => { "decision_extended": "indeterminate_dp" } + +lift_decision_indeterminate({ "decision": "not_applicable" }) := { "decision": "not_applicable" } +lift_decision_indeterminate({ "decision": "permit" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "deny" }) := { "decision": "indeterminate_d" } +lift_decision_indeterminate({ "decision": "indeterminate" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_dp" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_p" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "indeterminate_d" }) := { "decision": "indeterminate_d" } + +## Value + +# - { "kind": "primitive", +# "type": string, +# "value": string } +# - { "kind": "bag", +# "values": ... } + +### Booleans + +true_value := { "kind": "primitive", "type": "boolean", "value": true } +false_value := { "kind": "primitive", "type": "boolean", "value": false } +indeterminate_value := { "kind": "primitive", "type": "boolean" } + +is_indeterminate(value) if { is_null(value.value) } + +## StatusCode + +# - ok => { "status": "ok" } +# - missing_attribute => { "status": "missing_attribute" } +# - syntax_error => { "status": "syntax_error" } +# - processing_error => { "status": "processing_error" } + +## AttributeDesignator + +# - { category : string +# identifier : string +# type : string +# issuer : string or null +# must_be_present : boolean } + +## Expression + +# - { "expression": "apply", +# "function": string, +# "args": [string, ...] } +# - { "expression": "attribute_designator", +# "inner": AttributeDesignator } +# - { "expression": "attribute_value", +# "inner": Value } +# - { "expression": "function" +# "function": string } + +## Match + +# - { "function": string, +# "designator": AttributeDesignator, +# "value": Value } + +## Obligation + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## ObligationExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "fulfill_on": Decision } + +## Advice + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## AdviceExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "applies_to": Decision } + +## AttributeAssignmentExpression + +# - { "category": string, +# "identifier": string, +# "issuer": string or null, +# "expression": Expression } + +## Target: [[[Expression, ...], ...], ...] + +## Rule + +# - { "target": Target, +# "condition": Expression or null, +# "effect": "permit" or "deny", +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## Policy + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## PolicySet + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +# We assume the request attributes are stored in `input.request` as an array or set of +# +# { category : string +# identifier : string +# issuer : string or null +# value : [Value, ...] } + +######################################################################## +# Match Functions +######################################################################## + +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:string-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": b }]) := true_value if { + a == b +} else := false_value +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": b }]) := true_value if { + a == b +} else := false_value + +######################################################################## +# AttributeDesignator +######################################################################## + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + not attribute.attr.issuer +} + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + attribute.attr.issuer == designator.issuer +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) > 1 +} + +evaluate_designator(designator) := xs[0] if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 1 +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + not designator.must_be_present +} + +evaluate_designator(designator) := { "status": "missing_attribute" } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + designator.must_be_present +} + +######################################################################### +# Match +######################################################################## + +evaluate_match(match) := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result.values + apply_xacml_function(match.function, [x, match.value]).value == true +} else := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + apply_xacml_function(match.function, [designator_result, match.value]).value == true +} else := { "match_result": indeterminate_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result + is_indeterminate(apply_xacml_function(match.function, [x, match.value])) +} else := { "match_result": false_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result +} else := { "match_result": indeterminate_value } + +# Last case runs when evaluating the designator results in an error. + +evaluate_all_of(conj) := { "match_result": true_value } if { + every x in conj { + evaluate_match(x).match_result.value == true + } +} else := { "match_result": "indeterminate" } if { + some x in conj + is_indeterminate(evaluate_match(x).match_result) +} else := { "match_result": "no_match" } + +evaluate_any_of([]) := { "match_result": true_value } +evaluate_any_of(disj) := { "match_result": true_value } if { + some x in disj + evaluate_all_of(x) == { "match_result": true_value } +} else := { "match_result": "indeterminate" } if { + some x in disj + evaluate_all_of(x) == { "match_result": true_value } +} else := { "match_result": "no_match" } + + +######################################################################## +# Target +######################################################################## + +evaluate_target([]) := { "match_result": true_value } +evaluate_target(xs) := { "match_result": true_value } if { + every disj in xs { + evaluate_any_of(disj).match_result.value == true + } +} else := { "match_result": false_value } if { + some disj in xs + evaluate_any_of(disj).match_result.value == false +} else := { "match_result": indeterminate_value } + +######################################################################## +# Expression +######################################################################## + +evaluate_expression({ "expression": "apply", "function": function_name, "args": args }) := x if { + x := apply_xacml_function(function_name, args) +} +evaluate_expression({ "expression": "attribute_designator", "inner": designator }) := x if { + x := evaluate_designator(designator) +} +evaluate_expression({ "expression": "attribute_value", "inner": value }) := x if { + x := value +} +evaluate_expression({ "expression": "function", "function": name }) := x if { + x := name +} + +######################################################################## +# Obligations and Advice +######################################################################## + +evaluate_attribute_assignment_expression(expr) := assignment { + { "kind": "primitive", "value": inner } = evaluate_expression(expr.expression) + assignment := { "category": expr.category, + "identifier": expr.identifier, + "issuer": expr.issuer, + "value": inner } +} + +evaluate_obligation_expression(obligation_expression) := obligation { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := obligation_expression.assignments[_]] + obligation := { "assignments": assignments, "identifier": obligation_expression.identifier } +} + +evaluate_advice_expression(advice_expression) := advice { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := advice_expression.assignments[_]] + advice := { "assignments": assignments, "identifier": advice_expression.identifier } +} + + +######################################################################## +# Rule +######################################################################## + +# Condition is specified and applicable +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + + is_object(rule.condition) + evaluate_expression(rule.condition) == true + + decision := rule.effect +} +# Condition is specified and not applicable +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == true + evaluate_expression(rule.condition) == false +} +# Condition is indeterminate +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "deny" +} +# Condition is unspecified +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + decision := rule.effect +} + +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == false +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} + +evaluate_rule_advices(rule) := { "advice": advice } if { + decision := evaluate_rule_decision(rule) + advice := [expr | expr := rule.advice[_]; expr.applies_to == decision ] +} + +evaluate_rule_obligations(rule) := { "obligations": obligations } if { + decision := evaluate_rule_decision(rule) + obligations := [expr | expr := rule.obligations[_]; expr.fulfill_on == decision ] +} + +######################################################################## +# Policy +######################################################################## + +evaluate_rule_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_rule_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_rule_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +# child_results := [result | rule := policy.rules[_]; result := evaluate_rule_decision(rule)] +evaluate_policy_decision(policy, child_results) := decision if { + evaluate_target(policy.target).match_result.value == true + decision := evaluate_rule_combinator(policy.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policy.target)) + decision := lift_decision_indeterminate(evaluate_rule_combinator(policy.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +# children_advice := [advice | rule := policy.rules[_]; expr := evaluate_rule_advices(rule); advice := expr[_]] +evaluate_policy_advices(policy, child_results, children_advice) := { "advice" : advice } if { + decision := evaluate_policy_decision(policy, child_results) + policy_advice := [expr | expr := policy.advice[_]; expr.applies_to == decision ] + advice := array.concat(policy_advice, children_advice) +} + +# children_obligations := [obligation | rule := policy.rules[_]; expr := evaluate_rule_obligations(rule); obligation := expr[_]] +evaluate_policy_obligations(policy, child_results, children_obligations) := { "obligations" : obligations } if { + decision := evaluate_policy_decision(policy, child_results) + policy_obligations := [expr | expr := policy.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policy_obligations, children_obligations) +} + +######################################################################## +# PolicySet +######################################################################## + +evaluate_policy_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_policy_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_policy_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("only_one_applicable", results) := result if { + applicable := [result | result := results[i]; result.decision_extended != "not_applicable"] + count(applicable) == 1 + result := applicable[0] +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_decision(policyset, child_results) := decision if { + evaluate_target(policyset.target).match_result.value == true + decision := evaluate_policy_combinator(policyset.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policyset.target)) + decision := lift_decision_indeterminate(evaluate_policy_combinator(policyset.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_advices(policyset, child_results, child_advice) := { "advice" : advice } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_advice := [expr | expr := policyset.advice[_]; expr.applies_to == decision ] + advice := array.concat(policyset_advice, child_advice) +} + +evaluate_policyset_obligations(policyset, child_results, child_obligations) := { "obligations" : obligations } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_obligations := [expr | expr := policyset.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policyset_obligations, child_obligations) +} + +IIA006_policy := { + "combinator": "deny_overrides", + "target": [], + "obligations": [], + "advice": [] +} + +IIA006_rule := { + "target": [[[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:subject:subject-id", + "category": "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "Julius Hibbert" + }}, + { "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:2.0:conformance-test:some-attribute", + "category": "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "riddle me this" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:resource:resource-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": "http://medico.com/record/patient/BartSimpson" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "read" + }}], + [{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "write" + }}]]], + "effect": "permit", + "obligations": [], + "advice": [] +} + +allow := evaluate_policyset_decision(IIA006_policy, [evaluate_rule_decision(IIA006_rule)]) diff --git a/benchmarks/rego/iia007.rego b/benchmarks/rego/iia007.rego new file mode 100644 index 0000000..b4aa619 --- /dev/null +++ b/benchmarks/rego/iia007.rego @@ -0,0 +1,829 @@ +package equivalence + +import future.keywords.every +import future.keywords.if +import future.keywords.in + +######################################################################## +# Data Types +######################################################################## + +## MatchResult + +# - is_match => { "match_result": true } +# - no_match => { "match_result": false } +# - indeterminate => { "match_result": "indeterminate" } + +## Decision + +# - permit => { "decision": "permit" } +# - deny => { "decision": "deny" } +# - not_applicable => { "decision": "not_applicable" } +# - indeterminate => { "decision": "indeterminate" } + +## Extended Decision + +# - permit => { "decision_extended": "permit" } +# - deny => { "decision_extended": "deny" } +# - not_applicable => { "decision_extended": "not_applicable" } +# - indeterminate => { "decision_extended": "indeterminate" } +# - indeterminate_d => { "decision_extended": "indeterminate_d" } +# - indeterminate_p => { "decision_extended": "indeterminate_p" } +# - indeterminate_dp => { "decision_extended": "indeterminate_dp" } + +lift_decision_indeterminate({ "decision": "not_applicable" }) := { "decision": "not_applicable" } +lift_decision_indeterminate({ "decision": "permit" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "deny" }) := { "decision": "indeterminate_d" } +lift_decision_indeterminate({ "decision": "indeterminate" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_dp" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_p" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "indeterminate_d" }) := { "decision": "indeterminate_d" } + +## Value + +# - { "kind": "primitive", +# "type": string, +# "value": string } +# - { "kind": "bag", +# "values": ... } + +### Booleans + +true_value := { "kind": "primitive", "type": "boolean", "value": true } +false_value := { "kind": "primitive", "type": "boolean", "value": false } +indeterminate_value := { "kind": "primitive", "type": "boolean" } + +is_indeterminate(value) if { is_null(value.value) } + +## StatusCode + +# - ok => { "status": "ok" } +# - missing_attribute => { "status": "missing_attribute" } +# - syntax_error => { "status": "syntax_error" } +# - processing_error => { "status": "processing_error" } + +## AttributeDesignator + +# - { category : string +# identifier : string +# type : string +# issuer : string or null +# must_be_present : boolean } + +## Expression + +# - { "expression": "apply", +# "function": string, +# "args": [string, ...] } +# - { "expression": "attribute_designator", +# "inner": AttributeDesignator } +# - { "expression": "attribute_value", +# "inner": Value } +# - { "expression": "function" +# "function": string } + +## Match + +# - { "function": string, +# "designator": AttributeDesignator, +# "value": Value } + +## Obligation + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## ObligationExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "fulfill_on": Decision } + +## Advice + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## AdviceExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "applies_to": Decision } + +## AttributeAssignmentExpression + +# - { "category": string, +# "identifier": string, +# "issuer": string or null, +# "expression": Expression } + +## Target: [[[Expression, ...], ...], ...] + +## Rule + +# - { "target": Target, +# "condition": Expression or null, +# "effect": "permit" or "deny", +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## Policy + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## PolicySet + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +# We assume the request attributes are stored in `input.request` as an array or set of +# +# { category : string +# identifier : string +# issuer : string or null +# value : [Value, ...] } + +######################################################################## +# Match Functions +######################################################################## + +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:string-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": b }]) := true_value if { + a == b +} else := false_value +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": b }]) := true_value if { + a == b +} else := false_value + +######################################################################## +# AttributeDesignator +######################################################################## + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + not attribute.attr.issuer +} + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + attribute.attr.issuer == designator.issuer +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) > 1 +} + +evaluate_designator(designator) := xs[0] if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 1 +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + not designator.must_be_present +} + +evaluate_designator(designator) := { "status": "missing_attribute" } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + designator.must_be_present +} + +######################################################################### +# Match +######################################################################## + +evaluate_match(match) := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result.values + apply_xacml_function(match.function, [x, match.value]).value == true +} else := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + apply_xacml_function(match.function, [designator_result, match.value]).value == true +} else := { "match_result": indeterminate_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result + is_indeterminate(apply_xacml_function(match.function, [x, match.value])) +} else := { "match_result": false_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result +} else := { "match_result": indeterminate_value, "status": designator_result.status } if { + designator_result := evaluate_designator(match.designator) +} + +# Last case runs when evaluating the designator results in an error. + +evaluate_all_of(conj) := { "match_result": true_value } if { + every x in conj { + evaluate_match(x).match_result.value == true + } +} else := { "match_result": "indeterminate", "status": x.status } if { + some x in conj + is_indeterminate(evaluate_match(x).match_result) +} else := { "match_result": "no_match" } + +evaluate_any_of([]) := { "match_result": true_value } +evaluate_any_of(disj) := { "match_result": true_value } if { + some x in disj + evaluate_all_of(x) == { "match_result": true_value } +} else := { "match_result": "indeterminate", "status": x.status } if { + some x in disj + is_indeterminate(evaluate_all_of(x)) +} else := { "match_result": "no_match" } + + +######################################################################## +# Target +######################################################################## + +evaluate_target([]) := { "match_result": true_value } +evaluate_target(xs) := { "match_result": true_value } if { + every disj in xs { + evaluate_any_of(disj).match_result.value == true + } +} else := { "match_result": false_value } if { + some disj in xs + evaluate_any_of(disj).match_result == "no_match" +} else := { "match_result": indeterminate_value } + +######################################################################## +# Expression +######################################################################## + +evaluate_expression({ "expression": "apply", "function": function_name, "args": args }) := x if { + x := apply_xacml_function(function_name, args) +} +evaluate_expression({ "expression": "attribute_designator", "inner": designator }) := x if { + x := evaluate_designator(designator) +} +evaluate_expression({ "expression": "attribute_value", "inner": value }) := x if { + x := value +} +evaluate_expression({ "expression": "function", "function": name }) := x if { + x := name +} + +######################################################################## +# Obligations and Advice +######################################################################## + +evaluate_attribute_assignment_expression(expr) := assignment { + { "kind": "primitive", "value": inner } = evaluate_expression(expr.expression) + assignment := { "category": expr.category, + "identifier": expr.identifier, + "issuer": expr.issuer, + "value": inner } +} + +evaluate_obligation_expression(obligation_expression) := obligation { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := obligation_expression.assignments[_]] + obligation := { "assignments": assignments, "identifier": obligation_expression.identifier } +} + +evaluate_advice_expression(advice_expression) := advice { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := advice_expression.assignments[_]] + advice := { "assignments": assignments, "identifier": advice_expression.identifier } +} + + +######################################################################## +# Rule +######################################################################## + +# Condition is specified and applicable +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + + is_object(rule.condition) + evaluate_expression(rule.condition) == true + + decision := rule.effect +} +# Condition is specified and not applicable +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == true + evaluate_expression(rule.condition) == false +} +# Condition is indeterminate +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "deny" +} +# Condition is unspecified +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + decision := rule.effect +} + +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == false +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} + +evaluate_rule_advices(rule) := { "advice": advice } if { + decision := evaluate_rule_decision(rule) + advice := [expr | expr := rule.advice[_]; expr.applies_to == decision ] +} + +evaluate_rule_obligations(rule) := { "obligations": obligations } if { + decision := evaluate_rule_decision(rule) + obligations := [expr | expr := rule.obligations[_]; expr.fulfill_on == decision ] +} + +######################################################################## +# Policy +######################################################################## + +evaluate_rule_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_rule_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_rule_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +# child_results := [result | rule := policy.rules[_]; result := evaluate_rule_decision(rule)] +evaluate_policy_decision(policy, child_results) := decision if { + evaluate_target(policy.target).match_result.value == true + decision := evaluate_rule_combinator(policy.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policy.target)) + decision := lift_decision_indeterminate(evaluate_rule_combinator(policy.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +# children_advice := [advice | rule := policy.rules[_]; expr := evaluate_rule_advices(rule); advice := expr[_]] +evaluate_policy_advices(policy, child_results, children_advice) := { "advice" : advice } if { + decision := evaluate_policy_decision(policy, child_results) + policy_advice := [expr | expr := policy.advice[_]; expr.applies_to == decision ] + advice := array.concat(policy_advice, children_advice) +} + +# children_obligations := [obligation | rule := policy.rules[_]; expr := evaluate_rule_obligations(rule); obligation := expr[_]] +evaluate_policy_obligations(policy, child_results, children_obligations) := { "obligations" : obligations } if { + decision := evaluate_policy_decision(policy, child_results) + policy_obligations := [expr | expr := policy.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policy_obligations, children_obligations) +} + +######################################################################## +# PolicySet +######################################################################## + +evaluate_policy_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_policy_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_policy_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("only_one_applicable", results) := result if { + applicable := [result | result := results[i]; result.decision_extended != "not_applicable"] + count(applicable) == 1 + result := applicable[0] +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_decision(policyset, child_results) := decision if { + evaluate_target(policyset.target).match_result.value == true + decision := evaluate_policy_combinator(policyset.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policyset.target)) + decision := lift_decision_indeterminate(evaluate_policy_combinator(policyset.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_advices(policyset, child_results, child_advice) := { "advice" : advice } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_advice := [expr | expr := policyset.advice[_]; expr.applies_to == decision ] + advice := array.concat(policyset_advice, child_advice) +} + +evaluate_policyset_obligations(policyset, child_results, child_obligations) := { "obligations" : obligations } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_obligations := [expr | expr := policyset.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policyset_obligations, child_obligations) +} + +IIA007_policy := { + "combinator": "deny_overrides", + "target": [], + "obligations": [], + "advice": [] +} + +IIA007_rule := { + "target": [[[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:subject:subject-id", + "category": "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": true + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "Julius Hibbert" + }}, + { "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:2.0:conformance-test:some-attribute", + "category": "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": true + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "riddle me this" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:resource:resource-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": "http://medico.com/record/patient/BartSimpson" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "read" + }}], + [{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "write" + }}]]], + "effect": "permit", + "obligations": [], + "advice": [] +} + +allow := evaluate_policyset_decision(IIA007_policy, [evaluate_rule_decision(IIA007_rule)]) diff --git a/benchmarks/rego/iia1.json b/benchmarks/rego/iia1.json new file mode 100644 index 0000000..660d7c1 --- /dev/null +++ b/benchmarks/rego/iia1.json @@ -0,0 +1 @@ +{"request": [{"category":"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject","identifier":"urn:oasis:names:tc:xacml:1.0:subject:subject-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#string","value":"Julius Hibbert"}},{"category":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource","identifier":"urn:oasis:names:tc:xacml:1.0:resource:resource-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#anyURI","value":"http://medico.com/record/patient/BartSimpson"}},{"category":"urn:oasis:names:tc:xacml:3.0:attribute-category:action","identifier":"urn:oasis:names:tc:xacml:1.0:action:action-id","value":{"kind":"primitive","type":"http://www.w3.org/2001/XMLSchema#string","value":"read"}}]} diff --git a/benchmarks/rego/iia1.rego b/benchmarks/rego/iia1.rego new file mode 100644 index 0000000..f7c2a04 --- /dev/null +++ b/benchmarks/rego/iia1.rego @@ -0,0 +1,815 @@ +package equivalence + +import future.keywords.every +import future.keywords.if +import future.keywords.in + +######################################################################## +# Data Types +######################################################################## + +## MatchResult + +# - is_match => { "match_result": true } +# - no_match => { "match_result": false } +# - indeterminate => { "match_result": "indeterminate" } + +## Decision + +# - permit => { "decision": "permit" } +# - deny => { "decision": "deny" } +# - not_applicable => { "decision": "not_applicable" } +# - indeterminate => { "decision": "indeterminate" } + +## Extended Decision + +# - permit => { "decision_extended": "permit" } +# - deny => { "decision_extended": "deny" } +# - not_applicable => { "decision_extended": "not_applicable" } +# - indeterminate => { "decision_extended": "indeterminate" } +# - indeterminate_d => { "decision_extended": "indeterminate_d" } +# - indeterminate_p => { "decision_extended": "indeterminate_p" } +# - indeterminate_dp => { "decision_extended": "indeterminate_dp" } + +lift_decision_indeterminate({ "decision": "not_applicable" }) := { "decision": "not_applicable" } +lift_decision_indeterminate({ "decision": "permit" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "deny" }) := { "decision": "indeterminate_d" } +lift_decision_indeterminate({ "decision": "indeterminate" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_dp" }) := { "decision": "indeterminate_dp" } +lift_decision_indeterminate({ "decision": "indeterminate_p" }) := { "decision": "indeterminate_p" } +lift_decision_indeterminate({ "decision": "indeterminate_d" }) := { "decision": "indeterminate_d" } + +## Value + +# - { "kind": "primitive", +# "type": string, +# "value": string } +# - { "kind": "bag", +# "values": ... } + +### Booleans + +true_value := { "kind": "primitive", "type": "boolean", "value": true } +false_value := { "kind": "primitive", "type": "boolean", "value": false } +indeterminate_value := { "kind": "primitive", "type": "boolean" } + +is_indeterminate(value) if { is_null(value.value) } + +## StatusCode + +# - ok => { "status": "ok" } +# - missing_attribute => { "status": "missing_attribute" } +# - syntax_error => { "status": "syntax_error" } +# - processing_error => { "status": "processing_error" } + +## AttributeDesignator + +# - { category : string +# identifier : string +# type : string +# issuer : string or null +# must_be_present : boolean } + +## Expression + +# - { "expression": "apply", +# "function": string, +# "args": [string, ...] } +# - { "expression": "attribute_designator", +# "inner": AttributeDesignator } +# - { "expression": "attribute_value", +# "inner": Value } +# - { "expression": "function" +# "function": string } + +## Match + +# - { "function": string, +# "designator": AttributeDesignator, +# "value": Value } + +## Obligation + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## ObligationExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "fulfill_on": Decision } + +## Advice + +# - { "assignments": [Attribute, ...], +# "identifier": string } + +## AdviceExpression + +# - { "assignments": [AttributeAssignmentExpression, ...], +# "identifier": string, +# "applies_to": Decision } + +## AttributeAssignmentExpression + +# - { "category": string, +# "identifier": string, +# "issuer": string or null, +# "expression": Expression } + +## Target: [[[Expression, ...], ...], ...] + +## Rule + +# - { "target": Target, +# "condition": Expression or null, +# "effect": "permit" or "deny", +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## Policy + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +## PolicySet + +# - { "combinator": string, +# "target": Target, +# "obligations": [ObligationExpression, ...], +# "advice": [AdviceExpression, ...] } + +# We assume the request attributes are stored in `input.request` as an array or set of +# +# { category : string +# identifier : string +# issuer : string or null +# value : [Value, ...] } + +######################################################################## +# Match Functions +######################################################################## + +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:string-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": b }]) := true_value if { + a == b +} else := false_value +apply_xacml_function( + "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + [{ "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": a }, + { "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": b }]) := true_value if { + a == b +} else := false_value + +######################################################################## +# AttributeDesignator +######################################################################## + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + not attribute.attr.issuer +} + +designator_matches(designator, attribute) if { + attribute.category == designator.category + attribute.identifier == designator.identifier + attribute.value.type == designator.type + attribute.attr.issuer == designator.issuer +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) > 1 +} + +evaluate_designator(designator) := xs[0] if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 1 +} + +evaluate_designator(designator) := { "kind": "bag", "values": xs } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + not designator.must_be_present +} + +evaluate_designator(designator) := { "status": "missing_attribute" } if { + xs := [y.value | y := input.request[_]; designator_matches(designator, y)] + count(xs) == 0 + designator.must_be_present +} + +######################################################################### +# Match +######################################################################## + +evaluate_match(match) := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result.values + apply_xacml_function(match.function, [x, match.value]).value == true +} else := { "match_result": true_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + apply_xacml_function(match.function, [designator_result, match.value]).value == true +} else := { "match_result": indeterminate_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result + + some x in designator_result + is_indeterminate(apply_xacml_function(match.function, [x, match.value])) +} else := { "match_result": false_value } if { + designator_result := evaluate_designator(match.designator) + + # Designator evaluates without error. + designator_result +} else := { "match_result": indeterminate_value } + +# Last case runs when evaluating the designator results in an error. + +evaluate_all_of(conj) := { "match_result": true_value } if { + every x in conj { + evaluate_match(x).match_result.value == true + } +} else := { "match_result": "indeterminate" } if { + some x in conj + is_indeterminate(evaluate_match(x).match_result) +} else := { "match_result": "no_match" } + +evaluate_any_of([]) := { "match_result": true_value } +evaluate_any_of(disj) := { "match_result": true_value } if { + some x in disj + evaluate_all_of(x) == { "match_result": true_value } +} else := { "match_result": "indeterminate" } if { + some x in disj + evaluate_all_of(x) == { "match_result": true_value } +} else := { "match_result": "no_match" } + + +######################################################################## +# Target +######################################################################## + +evaluate_target([]) := { "match_result": true_value } +evaluate_target(xs) := { "match_result": true_value } if { + every disj in xs { + evaluate_any_of(disj).match_result.value == true + } +} else := { "match_result": false_value } if { + some disj in xs + evaluate_any_of(disj).match_result.value == false +} else := { "match_result": indeterminate_value } + +######################################################################## +# Expression +######################################################################## + +evaluate_expression({ "expression": "apply", "function": function_name, "args": args }) := x if { + x := apply_xacml_function(function_name, args) +} +evaluate_expression({ "expression": "attribute_designator", "inner": designator }) := x if { + x := evaluate_designator(designator) +} +evaluate_expression({ "expression": "attribute_value", "inner": value }) := x if { + x := value +} +evaluate_expression({ "expression": "function", "function": name }) := x if { + x := name +} + +######################################################################## +# Obligations and Advice +######################################################################## + +evaluate_attribute_assignment_expression(expr) := assignment { + { "kind": "primitive", "value": inner } = evaluate_expression(expr.expression) + assignment := { "category": expr.category, + "identifier": expr.identifier, + "issuer": expr.issuer, + "value": inner } +} + +evaluate_obligation_expression(obligation_expression) := obligation { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := obligation_expression.assignments[_]] + obligation := { "assignments": assignments, "identifier": obligation_expression.identifier } +} + +evaluate_advice_expression(advice_expression) := advice { + assignments := [evaluate_attribute_assignment_expression(expr) | expr := advice_expression.assignments[_]] + advice := { "assignments": assignments, "identifier": advice_expression.identifier } +} + + +######################################################################## +# Rule +######################################################################## + +# Condition is specified and applicable +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + + is_object(rule.condition) + evaluate_expression(rule.condition) == true + + decision := rule.effect +} +# Condition is specified and not applicable +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == true + evaluate_expression(rule.condition) == false +} +# Condition is indeterminate +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + evaluate_target(rule.target).match_result.value == true + condition := evaluate_expression(rule.condition) + is_null(condition) + rule.effect == "deny" +} +# Condition is unspecified +evaluate_rule_decision(rule) := { "decision_extended": decision } { + evaluate_target(rule.target).match_result.value == true + decision := rule.effect +} + +evaluate_rule_decision(rule) := { "decision_extended": "not_applicable" } { + evaluate_target(rule.target).match_result.value == false +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_p" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} +evaluate_rule_decision(rule) := { "decision_extended": "indeterminate_d" } { + is_indeterminate(evaluate_target(rule.target)) + rule.effect == "permit" +} + +evaluate_rule_advices(rule) := { "advice": advice } if { + decision := evaluate_rule_decision(rule) + advice := [expr | expr := rule.advice[_]; expr.applies_to == decision ] +} + +evaluate_rule_obligations(rule) := { "obligations": obligations } if { + decision := evaluate_rule_decision(rule) + obligations := [expr | expr := rule.obligations[_]; expr.fulfill_on == decision ] +} + +######################################################################## +# Policy +######################################################################## + +evaluate_rule_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_rule_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_rule_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_rule_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +# child_results := [result | rule := policy.rules[_]; result := evaluate_rule_decision(rule)] +evaluate_policy_decision(policy, child_results) := decision if { + evaluate_target(policy.target).match_result.value == true + decision := evaluate_rule_combinator(policy.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policy.target)) + decision := lift_decision_indeterminate(evaluate_rule_combinator(policy.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +# children_advice := [advice | rule := policy.rules[_]; expr := evaluate_rule_advices(rule); advice := expr[_]] +evaluate_policy_advices(policy, child_results, children_advice) := { "advice" : advice } if { + decision := evaluate_policy_decision(policy, child_results) + policy_advice := [expr | expr := policy.advice[_]; expr.applies_to == decision ] + advice := array.concat(policy_advice, children_advice) +} + +# children_obligations := [obligation | rule := policy.rules[_]; expr := evaluate_rule_obligations(rule); obligation := expr[_]] +evaluate_policy_obligations(policy, child_results, children_obligations) := { "obligations" : obligations } if { + decision := evaluate_policy_decision(policy, child_results) + policy_obligations := [expr | expr := policy.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policy_obligations, children_obligations) +} + +######################################################################## +# PolicySet +######################################################################## + +evaluate_policy_combinator("deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate_dp" } if { + some result in results + result.decision_extended == "indeterminate_dp" +} else := { "decision_extended": "indeterminate_dp" } if { + some result1 in results + some result2 in results + result1.decision_extended == "indeterminate_d" + result1.decision_extended == "indeterminate_p" +} else := { "decision_extended": "indeterminate_p" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate_d" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("deny_unless_permit", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } + +evaluate_policy_combinator("permit_unless_deny", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "permit" } + +evaluate_policy_combinator("first_applicable", results) := result if { + indices := [i | results[i].decision_extended != "not_applicable"] + count(indices) > 0 + result := results[max(indices)] + result.decision_extended == "deny" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("only_one_applicable", results) := result if { + applicable := [result | result := results[i]; result.decision_extended != "not_applicable"] + count(applicable) == 1 + result := applicable[0] +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_deny_overrides", results) := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate" +} else := { "decision_extended": "not_applicable" } + +evaluate_policy_combinator("ordered_legacy_permit_overrides", results) := { "decision_extended": "permit" } if { + some result in results + result.decision_extended == "permit" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_p" +} else := { "decision_extended": "deny" } if { + some result in results + result.decision_extended == "deny" +} else := { "decision_extended": "indeterminate" } if { + some result in results + result.decision_extended == "indeterminate_d" +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_decision(policyset, child_results) := decision if { + evaluate_target(policyset.target).match_result.value == true + decision := evaluate_policy_combinator(policyset.combinator, child_results) +} else := decision if { + is_indeterminate(evaluate_target(policyset.target)) + decision := lift_decision_indeterminate(evaluate_policy_combinator(policyset.combinator, child_results)) +} else := { "decision_extended": "not_applicable" } + +evaluate_policyset_advices(policyset, child_results, child_advice) := { "advice" : advice } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_advice := [expr | expr := policyset.advice[_]; expr.applies_to == decision ] + advice := array.concat(policyset_advice, child_advice) +} + +evaluate_policyset_obligations(policyset, child_results, child_obligations) := { "obligations" : obligations } if { + decision := evaluate_policyset_decision(policyset, child_results) + policyset_obligations := [expr | expr := policyset.obligations[_]; expr.applies_to == decision ] + obligations := array.concat(policyset_obligations, child_obligations) +} + +IIA1_policy := { + "combinator": "deny_overrides", + "target": [], + "obligations": [], + "advice": [] +} + +IIA1_rule := { + "target": [[[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:subject:subject-id", + "category": "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "Julius Hibbert" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:resource:resource-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#anyURI", + "value": "http://medico.com/record/patient/BartSimpson" + }}]], + [[{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "read" + }}], + [{ "function": "urn:oasis:names:tc:xacml:1.0:function:string-equal", + "designator": { + "identifier": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action", + "type": "http://www.w3.org/2001/XMLSchema#string", + "must_be_present": false + }, + "value": { + "kind": "primitive", + "type": "http://www.w3.org/2001/XMLSchema#string", + "value": "write" + }}]]], + "effect": "permit", + "obligations": [], + "advice": [] +} + +allow := evaluate_policyset_decision(IIA1_policy, [evaluate_rule_decision(IIA1_rule)]) |