John Moehrke XACML Consent Example
0.1.0 - ci-build
John Moehrke XACML Consent Example, published by John Moehrke (Moehrke Research LLC). This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/JohnMoehrke/xacml-consent/ and changes regularly. See the Directory of published versions
let’s treat AB 352 as an organizational policy encoded as a top-level XACML PolicySet that:
graph TD
Start((Medical Record Action)) --> Destination{Destination?}
%% IN-STATE FLOW
Destination -->|CA Data Exchange| InState[<b>IN-STATE</b>]
InState --> DxFGate{Specific Consent on File?}
DxFGate -->|No| AutoFilter[<b>AUTO-FILTER: ENABLED</b>]
AutoFilter -->|Action| Scrub[Scrub Sensitive Codes]
Scrub --> SharePartial[Share General Data Only]
DxFGate -->|Yes| FilterOff[<b>Follow Consent #40;AUTO-FILTER:disabled#41;</b>]
FilterOff --> ShareFull[Share Consent Permitted Record via DxF]
%% OUT-OF-STATE FLOW
Destination -->|Cross Border| OutState[<b>OUT-OF-STATE</b>]
OutState --> ShieldGate{Specific Consent on File?}
ShieldGate -->|No| Block[<b>AB 352 SHIELD: BLOCKED</b>]
Block --> Partial[Release Non-Sensitive Data Only]
ShieldGate -->|Yes| Consented[<b>Follow Consent</b>]
Consented --> Full[Release Consent Permitted Record]
%% Formatting
style AutoFilter fill:#fff4dd,stroke:#d4a017,stroke-width:2px
style FilterOff fill:#9f9,stroke:#333
style Block fill:#f99,stroke:#333
Generated by co-pilot with specific direction to use recommendations from HealthNet California AB 352 documentation.
A FHIR Consent instance that is an explicit consent for AB 352 protected data, with provisions that reflect the statutory requirements, with auto-filter bypassed for in-state recipients.
policyRule → AB 352 statutory anchor ==> urn:law:us:ca:statute:AB352policy – see note belowpatient → the patient giving consentorganization → the California hospital organizationdateTime → when the consent was createdcategory → Release of Information Consent LOINC codescope → Privacy Consentprovision[0] → overall provision agreement for AB 352 data segmentation for TREATMENT purpose.
type → permitpurpose → TREATMENT, PAYMENT, OPERATIONSprovision[0] out-of-state recipients deny
type → denysecurityLabel → three sensitivity tags from AB352 Segmentation Tags ValueSetpurpose → TREATMENT, PAYMENT, OPERATIONSprovision[0] → Indicates that for in-state recipients, data tagged with specific sensitivity codes can be accessed for treatment purpose. (Auto-Filter is bypassed)
type → permitlocation → organization in CaliforniaNote that the policy element is not indicated here, as the policyRule code is sufficient to express to the recipient the statutory basis for the consent. If the Recipient does not understand the rules of AB352, then the encoded XACML PolicySet can be shared out-of-band or referenced via a URI. It is not clear what use the Recipient has for the actual XACML policy in the context of FHIR Consent, but it is included here for discussion sake. Many are arguing that the FHIR Consent must include the foundational rules in a computable form.
If the patient wants non-CA recipients to have access than provision[1] would be modified to permit instead of deny. If they want to enable only SOME out-of-state access, then multiple provisions would be needed for each authorized out-of-state organization.
flowchart TD
A["Request to access/disclose data"] --> B["PEP collects attributes"]
B --> C["Attributes: action, sensitivity, recipient jurisdiction, purpose"]
C --> D["PDP evaluates PolicySet urn:org:hospital:policyset:AB352"]
D --> E1{"Action = disclose?"}
E1 -- Yes --> F1{"Sensitivity in AB352 set?"}
F1 -- Yes --> G1{"Recipient jurisdiction != CA?"}
G1 -- Yes --> H1["Deny<br/>Obligation: log-denial"]
G1 -- No --> I1["Continue evaluation<br/>(local org policies)"]
F1 -- No --> I1
E1 -- No --> E2{"Action = access/use?"}
E2 -- Yes --> F2{"Recipient jurisdiction = CA<br/>AND purpose = TREATMENT?"}
F2 -- Yes --> H2["Permit<br/>Obligation: segment-sensitive-data"]
F2 -- No --> I2["NotApplicable or other org policies"]
E2 -- No --> I2
H2 --> J["PEP enforces segmentation<br/>(EHR/HIE data segregation)"]
H1 --> K["PEP denies disclosure<br/>and records AuditEvent"]
This XACML treats AB 352 as an organizational policy implemented by a California hospital, expressed as a top‑level PolicySet with subordinate policies for:
graph TD
PS["<b>PolicySet:</b> AB352 Compliance<br/>Target: CA-HOSPITAL<br/>Combining Alg: Deny-Overrides"]
PS --> P1_T
PS --> P2_T
PS --> P3_T
%% Policy 1
subgraph P1 ["Policy 1: Data Disclosure Control"]
P1_T["Target: Action = DISCLOSE"]
P1_R1["Rule: Deny Out-of-State"]
P1_C{"Condition:<br/>Is Sensitive Health Data?<br/>AND Recipient != CA?"}
P1_O["Obligation: Log Denial Reason"]
P1_T --> P1_R1
P1_R1 --> P1_C
P1_R1 --> P1_O
end
%% Policy 2
subgraph P2 ["Policy 2: In-State Clinical Use"]
P2_T["Target: Action = ACCESS/USE"]
P2_R1["Rule: Permit Treatment"]
P2_C{"Condition:<br/>Recipient = CA?<br/>AND Purpose = TREATMENT?"}
P2_T --> P2_R1
P2_R1 --> P2_C
end
%% Policy 3
subgraph P3 ["Policy 3: Mandatory Segmentation"]
P3_T["Target: Any"]
P3_R1["Rule: Permit"]
P3_O["Obligation: Trigger Segmentation Engine<br/>for Abortion/Gender Care/Contraception"]
P3_T --> P3_R1
P3_R1 --> P3_O
end
%% Styling
style PS fill:#f9f,stroke:#333,stroke-width:4px
style P1_R1 fill:#ff9999,stroke:#c00
style P2_R1 fill:#99ff99,stroke:#0c0
style P3_O fill:#bbdaff,stroke:#00f
Everything is self‑contained and ready for use in an IG or PDP example. Here is the XACML PolicySet for AB 352:
<PolicySet
xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicySetId="urn:org:hospital:policyset:AB352"
Version="1.0"
PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:deny-overrides">
<!-- Applies to this California hospital as data controller -->
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
CA-HOSPITAL
</AttributeValue>
<AttributeDesignator
AttributeId="urn:org:hospital:attribute:organization-type"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<!-- ========================================================= -->
<!-- POLICY 1: AB352 Denial of Out-of-State Disclosure -->
<!-- ========================================================= -->
<Policy
PolicyId="urn:org:hospital:policy:AB352:deny-out-of-state-disclosure"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides">
<Target>
<AnyOf>
<AllOf>
<!-- Applies to disclosure/transmission actions -->
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
disclose
</AttributeValue>
<AttributeDesignator
AttributeId="urn:org:hospital:attribute:action:verb"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<Rule
RuleId="urn:org:hospital:rule:AB352:deny-out-of-state"
Effect="Deny">
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<!-- Resource is AB352-sensitive -->
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
<AttributeDesignator
AttributeId="urn:org:hospital:attribute:health:sensitivity"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ABORTION</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">GENDER_AFFIRMING_CARE</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">CONTRACEPTION</AttributeValue>
</Apply>
<!-- Recipient jurisdiction is not California -->
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-not-equal">
<AttributeDesignator
AttributeId="urn:org:hospital:attribute:recipient:jurisdiction"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">CA</AttributeValue>
</Apply>
</Apply>
</Condition>
<!-- Obligation: log denied AB352 disclosure attempt -->
<ObligationExpressions>
<ObligationExpression
ObligationId="urn:org:hospital:obligation:log-denial"
FulfillOn="Deny">
<AttributeAssignmentExpression AttributeId="urn:org:hospital:log:reason">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
AB352 prohibited disclosure to out-of-state entity
</AttributeValue>
</AttributeAssignmentExpression>
</ObligationExpression>
</ObligationExpressions>
</Rule>
</Policy>
<!-- ========================================================= -->
<!-- POLICY 2: Allow In-State Treatment Access -->
<!-- ========================================================= -->
<Policy
PolicyId="urn:org:hospital:policy:AB352:allow-in-state-treatment"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides">
<Target>
<AnyOf>
<AllOf>
<!-- Access/use actions -->
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">access</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">use</AttributeValue>
<AttributeDesignator
AttributeId="urn:org:hospital:attribute:action:verb"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<Rule
RuleId="urn:org:hospital:rule:AB352:permit-in-state-treatment"
Effect="Permit">
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<!-- Recipient jurisdiction is California -->
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeDesignator
AttributeId="urn:org:hospital:attribute:recipient:jurisdiction"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">CA</AttributeValue>
</Apply>
<!-- Purpose is treatment -->
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeDesignator
AttributeId="urn:org:hospital:attribute:purpose-of-use"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">TREATMENT</AttributeValue>
</Apply>
</Apply>
</Condition>
</Rule>
</Policy>
<!-- ========================================================= -->
<!-- POLICY 3: Segmentation Requirement (Obligation) -->
<!-- ========================================================= -->
<Policy
PolicyId="urn:org:hospital:policy:AB352:segmentation"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides">
<Rule
RuleId="urn:org:hospital:rule:AB352:segmentation-required"
Effect="Permit">
<!-- Always applies; obligation enforces segmentation -->
<ObligationExpressions>
<ObligationExpression
ObligationId="urn:org:hospital:obligation:segment-sensitive-data"
FulfillOn="Permit">
<AttributeAssignmentExpression AttributeId="urn:org:hospital:segmentation:categories">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
ABORTION,GENDER_AFFIRMING_CARE,CONTRACEPTION
</AttributeValue>
</AttributeAssignmentExpression>
</ObligationExpression>
</ObligationExpressions>
</Rule>
</Policy>
</PolicySet>
urn:oasis:names:tc:xspa:1.0:subject:locality (or a custom attribute)urn:org:hospital:attribute:recipient:jurisdictionurn:oasis:names:tc:xspa:1.0:subject:purposeofuse (e.g., TREAT)urn:org:hospital:attribute:purpose-of-useurn:org:hospital:policyset:AB352.Consent instance Consent/consent-ab352-exampleConsent.policy.uri → APPC policy identifier → XACML PolicySetId.Consent.provision.class → sensitivity tags on FHIR resources (e.g., meta.security) → XACML health:sensitivity.