Wednesday, January 21, 2026

Sustaining the Work That Sustains Trust: Why I’m Seeking Support for Some of My Standards Efforts

For many years, I’ve used this blog to explore the intersection of healthcare, privacy, and interoperability. Much of my professional life has been dedicated to helping the industry build systems that respect patient autonomy, protect sensitive information, and communicate clearly across organizational and technical boundaries.

Recently, I launched Moehrke Research, my independent consulting practice. It’s still early in its development, but it reflects the same principles that have guided my work for decades: clarity, transparency, and a commitment to practical, implementable standards. As I grow this business, I’m also continuing to invest deeply in common-goods efforts that advance the broader ecosystem.

Right now, that includes two areas that are both urgent and foundational:
These efforts are essential to the future of trustworthy digital health. They also require a significant investment of time—time that I’ve been donating because I believe deeply in the work and in the communities that will benefit from it.

But the reality is that these projects have grown in scope and complexity. They now demand sustained, focused attention to ensure they mature into practical, implementable guidance that organizations can rely on. And that level of commitment is difficult to maintain without dedicated support.

Why This Work Matters

Healthcare is entering a period where AI‑generated content, automated decision support, and increasingly granular privacy expectations are no longer theoretical. They are here, influencing care, shaping patient experiences, and challenging long‑standing assumptions about data governance.

The AI Transparency IG
aims to give implementers a clear, standards‑based way to document how AI systems contribute to clinical information—what models were used, what data informed them, how confident they were, and what human oversight was involved. This is not just a technical exercise; it’s a trust exercise. 

This IG just completed an HL7 ballot with over 100 comments. Very good and constructive comments. There is so much work yet to be done to make this IG better and more clear.


Sensitive health topics
are improving thru, the SHIFT Task Force and HL7 Sensitivity IG are tackling the nuanced, often fragmented world of privacy‑sensitive data. From reproductive health to behavioral health to social determinants, organizations need consistent, interoperable ways to tag, segment, and protect information that carries heightened risk. 

We are looking for a way to better and more clearly manage valueSets that can inform real-world use of data sensitivity tagging. This was once started by SAMHSA, but that effort has languished for 10+ years. The community need a more sustainable and actionable methodology. 

These are not optional capabilities. They are becoming regulatory expectations, ethical imperatives, and operational necessities.

Why I’m Asking for Support

I’ve always believed in contributing to the standards community. It’s where some of the most important work in healthcare happens. I have benefitted from past employers that allowed me to work on these Privacy and Authenticity topics. But the volume and depth of the current projects have reached a point where continuing entirely as pro bono work is no longer sustainable.

As I work to establish Moehrke Research, I also want to ensure that my contributions to these critical standards efforts remain strong and consistent. Funding would allow me to:
  • Dedicate focused time to advancing the AI Transparency IG
  • Support the SHIFT Task Force with detailed modeling, examples, and implementation guidance
  • Strengthen the HL7 Sensitivity IG with real‑world, policy‑grounded segmentation patterns
  • Produce documentation, diagrams, and educational materials that help implementers adopt these standards correctly
  • Continue writing openly about these topics so the broader community benefits
In short, support would ensure that this work moves forward with the rigor, clarity, and speed it deserves.

How Organizations Can Help

If your organization depends on trustworthy AI, interoperable privacy controls, or clear guidance on handling sensitive health information, I invite you to consider sponsoring this work. Support can take many forms—direct funding, project‑based engagements, or contributions aligned with specific deliverables.

My goal is simple: to keep doing the work that helps the entire ecosystem function more safely and transparently. With your support, I can continue contributing at the level these efforts require.

If you’re interested in discussing sponsorship or collaboration, please reach out through MoehrkeResearch.com.

Wednesday, January 7, 2026

Tracking Patient Data Corrections

When data are corrected, especially when the Patient themselves reported that the data was wrong, there needs to be breadcrumbs left behind. Correction is a form of updating of data, but with the special need to indicate that previous data was in error. Some corrections result in the previous data being removed, while others result in the previous data being replaced with corrected data.

Therefore the needs to be a special indication of a correction Provenance, as distinct from a general update Provenance, with the following goals:

  1. So that future uses understand the past might have seen different data
  2. So that requests for data, especially from outside (e.g. HIE), can see that previous data has been corrected.

The recipient can then find if they have a copy or used the previous data, and take appropriate action.

I have this documented in an IG that has both FHIR R4 and R6 details

- ci-build for FHIR R4 - http://build.fhir.org/ig/JohnMoehrke/correction/branches/main/index.html

- ci-build for FHIR R6 - https://build.fhir.org/ig/JohnMoehrke/correction/branches/R6/index.html

Use-cases

  • A patient contacts their provider to report that there is some data that is incorrect. An investigation is done, and the data are found to be in error. The data is corrected, and a Provenance resource is created to indicate the correction.
  • A Quality Improvement process finds that some data is incorrect. An investigation is done, and the data are found to be in error. The data is corrected, and a Provenance resource is created to indicate the correction.
    • One possibility for this detection is an AI system that reviews data and finds potential errors.

Profiling

Recommended use of a Profile on Provenance to indicate corrections:

  • activity.coding: will be code FIXDATA from v3-ActReason to indicate that this Provenance is for a data correction.
  • reason.coding: can use a set of codes often associated with a correction.
  • recorded: will be the time the correction was made.
  • target: points at the resource(s) that are corrected.
  • agent: indicates who made the correction.
    • the Patient would be indicated here for corrections requested by the patient.
  • entity: indicates the records corrected.
    • entity.role=#removal points at the record being replaced or removed (if applicable).
    • entity.role=#revision points at the record being revised (if applicable).
  • textual reason can be in why in R6, or in activity.text in R4/R5.
  • evidence such as the request for the correction can be in basedOn in R6, or in entity with role=#derivation in R4/R5.

Examples:

  • Provenance removal resource documenting the removal of incorrect food allergy observation. This example does not point at a resource that explains the correction, such as a DocumentReference.
  • Provenance replacement Provenance resource documenting the replacement of an immunization record that was in error. This example includes a reference to a DocumentReference that explains the correction.
  • Provenance AI corrected Provenance resource documenting the detection of an error in FHIR data by an AI system. The original Observation that is error is removed, and a new AllergyIntolerance resource is created to replace it.
  • Provenance AI corrected with replacement Provenance resource documenting the detection of an error in FHIR data by an AI system, where the Observation was used to record a food allergy, but the AI system detected that this should have been an AllergyIntolerance resource instead. Thus the Observation is removed, and the AllergyIntolerance is created.
  • Provenance patient correction Provenance resource documenting a patient requested correction of their birth date.
  • Provenance revision correction Provenance resource documenting the revision of a Condition resource with corrected onset date. In this case the original Condition is revised. Thus the old version history/1 is indicated as revised, and the new version history/2 is indicated as the current version.

changes from R4->R6 Provenance:

  • In R6 basedOn would be used to hold the evidence for the correction. Where in R4 would use entity with role=derivation, and in R5 with role=instantiates.
  • In R6 patient element exists. Same in R6. R4 didn't have patient, so other methods would be needed to find all Provenance pointing at a patient's data.
  • In R6 why exists. This does not exist in R4 or R5. Sometimes the activity.text would be used for this.
  • In R6 and R5 authorization is a codeableReference, where in R5 reason is used to hold the PurposeOfUse

Discovering Corrections

To find all corrections for a specific patient, one can search for Provenance resources with Provenance.activity with the FIXDATA code, and where the Provenance points at resources related to the patient.

FHIR R5 and R6

In FHIR R5 and R6 there is a patient element on Provenance, making it easy to find all Provenance resources related to a specific patient. One needs to simply filter on Provenance.activity with the FIXDATA code.

GET [base]/Provenance?patient=[patient-id]&activity=http://terminology.hl7.org/CodeSystem/v3-ActReason|FIXDATA

FHIR R4

In FHIR R4 one needs to search for Provenance resources that point at resources related to the patient. This can be done by searching for Provenance with Provenance.activity with FIXDATA and where the target or entity.what points at resources related to the patient. Since either target or entity.what may point at resources that contain a patient reference, these cannot be combined in a single standard FHIR search query. Both chained searches must be performed and results combined client-side to find all relevant Provenance resources:

GET [base]/Provenance?activity=http://terminology.hl7.org/CodeSystem/v3-ActReason|FIXDATA&target.patient=[patient-id]
GET [base]/Provenance?activity=http://terminology.hl7.org/CodeSystem/v3-ActReason|FIXDATA&entity.what.patient=[patient-id]

Proposed FHIR Document section

I could not find an existing FHIR Document section that covers this topic. For example, in an International Patient Summary (IPS) this could be an additional section. In this way as new Cross-Community requests are made corrections would be communicated. This section contains information about corrections made to the patient's data, including details of the original data, the corrected data, and the reason for the correction. This information is provided to ensure data integrity and transparency in the patient's health record. I propose a new section:

  • Section code: http://loinc.org#77472-9 (Information integrity attribute)
  • Section title: Corrections to Data
  • Section text: Text summary of the corrections made.
  • Section entries: Provenance resources documenting corrections made to the patient's data following the correction Profile on Provenance.

Note that loinc code 77472-9 is "Information integrity attribute", which seems appropriate for this section. I am open to other code suggestions.

Conclusion

This is just my view on this use-case. I expect there is experience that might help refine. Please let me know

Sunday, December 28, 2025

FHIR Consent backed by XACML enforcement

Imagine a scenario where my organization uses XACML for all of our policy. This is where HR policies are on what HR relevant data can be accessed by whom, etc. This same XACML system would also be used to protect Patient data, including imaging, EHR, and HIE access. Thus, the XACML system is very broad and deep. Thus, it is the one that we want to use to protect everything.

Along comes FHIR Consent and we feel that there is a need to have some representation of the Patient Consent in FHIR form, but the actual rules that are applied stay in XACML. So, what does the FHIR Consent look like?

Generally speaking, the FHIR Consent would be just a cross-reference between the Patient as known in FHIR with the XACML subject id as known in XACML. The FHIR Consent would not replicate any of the patient specific rules. 

So, lets imagine a Patient has indicated that they agree to permit all the normal clinical activities with Normal sensitivity data, but that they do not allow external access to Restricted sensitivity data. 

In FHIR Consent, this would be a set of Consent.provisions; but in my case I already have this in computable form in XACML.

Further, my organizational overriding policies are written in XACML.


To see what this looks like, I have written a simple Implementation Guide: The Consent points at the overriding policy and the patient specific policy as shown below. This is Profiled:

XACML Policies

For those more familiar with XACML, can you check my work? I don't pass off these two policy sets as perfect, but as small representative examples.

Using XACML leverages an existing standard for defining access control policies. XACML policies are XML documents that specify rules for granting or denying access to resources based on various attributes, such as user roles, resource types, and environmental conditions.

XACML Overriding Policy

The XACML Overriding Policy is a policy set that defines the overarching access control rules for FHIR resources. This policy is intended to be used in conjunction with patient-specific XACML policies referenced in FHIR Consent resources. The overriding policy ensures that certain organizational or regulatory requirements are consistently applied across all patient consents.

<!-- This XACML policy file defines an organizational governance layer that overrides patient consent preferences. Specifically:

Purpose: It demonstrates how an organization's data access rules take precedence over patient consent policies using XACML's "deny-overrides" combining algorithm.

Key Rules:

1. Emergency Access - Permits doctors to access data during life-safety emergencies, regardless of consent restrictions
2. Archived Data Denial - Strictly forbids access to archived records, overriding any patient permits
3. Administrative Staff Restriction - Denies administrative staff access to data tagged as "Restricted" (R), even if patient consent would allow it

Context: This sits within a larger governance framework where patient consent (referenced via PolicySetIdReference) is evaluated, but organizational policies can override patient preferences when necessary for clinical workflows, safety, or compliance reasons. A master container applies default-deny if neither permits nor denies are found.
-->

<Policy PolicyId="Org_Policy_7890_Workflow_Governance" 
        RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" 
        xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
    
    <Description>
        Organizational Governance: Enforces workflow roles and clinical status.
        This policy overrides subject-level permits.
    </Description>

    <Target/> 
    
    <Rule RuleId="Emergency_Access_Permit" Effect="Permit">
        <Description>Allows doctors to access data regardless of tags during a life-safety event.</Description>
        <Condition>
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Emergency</AttributeValue>
                <AttributeDesignator 
                    AttributeId="urn:example:names:clinical:access-context" 
                    Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" 
                    DataType="http://www.w3.org/2001/XMLSchema#string" 
                    MustBePresent="true"/>
            </Apply>
        </Condition>
    </Rule>

    <Rule RuleId="Deny_Archived_Data_Access" Effect="Deny">
        <Description>Strictly forbids access if the record is in 'Archived' status, overriding user permits.</Description>
        <Target>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Archived</AttributeValue>
                        <AttributeDesignator 
                            AttributeId="urn:example:names:resource:status" 
                            Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" 
                            DataType="http://www.w3.org/2001/XMLSchema#string" 
                            MustBePresent="true"/>
                    </Match>
                </AllOf>
            </AnyOf>
        </Target>
    </Rule>

    <Rule RuleId="Deny_Non_Clinical_Staff_Restricted" Effect="Deny">
        <Description>Forbids administrative staff from seeing any data tagged as 'Restricted' (R).</Description>
        <Condition>
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Administrative</AttributeValue>
                    <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
                </Apply>
                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">R</AttributeValue>
                    <AttributeDesignator AttributeId="urn:example:med:names:resource:data-tag" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
                </Apply>
            </Apply>
        </Condition>
    </Rule>
</Policy>

XACML Patient Consent Policy


The XACML Patient Consent Policy is a policy document that defines the specific access control rules for an individual patient. This policy is referenced in the FHIR Consent resource and works in conjunction with the XACML Overriding Policy to determine access permissions for FHIR resources.

<!-- This XACML policy file encodes a patient consent for Patient ID 12345. Specifically:

Purpose: Defines the patient's preferences for data sharing based on sensitivity tags using Attribute-Based Access Control (ABAC).

Consent Rules:

1. Permits Normal Data - Allows sharing of data tagged as "Normal" (N) sensitivity
2. Denies Restricted Data - Blocks sharing of data tagged as "Restricted" (R) sensitivity

How it Works:

- Targets requests where the subject-id matches patient 12345
- Uses "deny-overrides" at the PolicySet level to ensure denials take precedence
- Contains two sub-policies: one for Normal data (permit-overrides) and one for Restricted data (deny-overrides)
- Evaluates the data-sensitivity attribute on resources to determine access
- This represents the patient's preferences layer in the consent framework, which works in conjunction with organizational policies (like xacml-overriding.xml) to make final access decisions.
-->

<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
           PolicySetId="consent-policy-set-12345"
           Version="1.0"
           PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:deny-overrides">

    <Description>Consent Policy Set for Patient ID 12345</Description>
    <Target>
        <AnyOf>
            <AllOf>
                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">12345</AttributeValue>
                    <AttributeDesignator 
                        AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" 
                        Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" 
                        DataType="http://www.w3.org/2001/XMLSchema#string" 
                        MustBePresent="true"/>
                </Match>
            </AllOf>
        </AnyOf>
    </Target>

    <Policy PolicyId="consent-policy-12345-normal-data"
            RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides">

        <Description>Policy to permit sharing of Normal (N) data</Description>

        <Target>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Normal</AttributeValue>
                        <AttributeDesignator AttributeId="data-sensitivity"
                                             Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
                                             DataType="http://www.w3.org/2001/XMLSchema#string"
                                             MustBePresent="true"/>
                    </Match>
                </AllOf>
            </AnyOf>
        </Target>

        <Rule RuleId="permit-normal-data" Effect="Permit">
            <Description>Permit access to Normal data</Description>
        </Rule>

    </Policy>

    <Policy PolicyId="consent-policy-12345-restricted-data"
            RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides">

        <Description>Policy to deny sharing of Restricted (R) data</Description>

        <Target>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Restricted</AttributeValue>
                        <AttributeDesignator AttributeId="data-sensitivity"
                                             Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
                                             DataType="http://www.w3.org/2001/XMLSchema#string"
                                             MustBePresent="true"/>
                    </Match>
                </AllOf>    
            </AnyOf>
        </Target>
        <Rule RuleId="deny-restricted-data" Effect="Deny">
            <Description>Deny access to Restricted data</Description>
        </Rule>
    </Policy>
</PolicySet>