aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xacml-translation/xacml.rego726
1 files changed, 726 insertions, 0 deletions
diff --git a/xacml-translation/xacml.rego b/xacml-translation/xacml.rego
new file mode 100644
index 0000000..b5ba0ff
--- /dev/null
+++ b/xacml-translation/xacml.rego
@@ -0,0 +1,726 @@
+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
+########################################################################
+
+## TODO
+apply_xacml_function("urn:oasis:names:tc:xacml:1.0:function:string-equal", [("http://www.w3.org/2001/XMLSchema#string", a), ("http://www.w3.org/2001/XMLSchema#string", 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
+ attribute.attr.issuer == null
+}
+
+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) := result if {
+ xs := [y.value | y := input.request[_]; designator_matches(designator, y)]
+ count(xs) > 0
+ result := { "kind": "bag", "values": xs }
+}
+
+evaluate_designator(designator) := result if {
+ xs := [y.value | y := input.request[_]; designator_matches(designator, y)]
+ count(xs) == 0
+ not designator.must_be_present
+ result := { "kind": "bag", "values": xs }
+}
+
+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.
+ is_array(designator_result)
+
+ some x in designator_result
+ apply_xacml_function(match.fn, x).value == true
+} else := { "match_result": indeterminate_value } if {
+ designator_result := evaluate_designator(match.designator)
+
+ # Designator evaluates without error.
+ is_array(designator_result)
+
+ some x in designator_result
+ is_indeterminate(apply_xacml_function(match.fn, x))
+} else := { "match_result": false_value } if {
+ designator_result := evaluate_designator(match.designator)
+
+ # Designator evaluates without error.
+ is_array(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) == 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)
+}

© 2015 - 2026 Jakob L. Kreuze