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)])