FHIR Consent Resource in Practice: Building Patient-Controlled Data Sharing for TEFCA
CTO & Co-Founder
CTO & Co-Founder at Nirmitee.io. Architects healthcare integrations across FHIR, SMART on FHIR, ABDM and NHCX, writing from production experience taking hospital software from sandbox to go-live.

Part of our complete guide to a primer on FHIR.
Why Consent Is the Hardest Problem in Health Data Exchange
Every health data exchange framework—TEFCA, CMS-0057-F, state HIEs—eventually hits the same wall: who controls what data gets shared, with whom, and for what purpose? The answer is consent management, and the FHIR Consent resource is the standard mechanism for recording these decisions. Enforcement needs a separate policy decision point and enforcement point.
If you are designing consent capture and enforcement, our patient identity and consent team can review your model. If you are planning TEFCA exchange for production, our TEFCA integration team can build it with you.
Yet most implementations treat consent as a checkbox. A patient signs a paper form, someone scans it into the EHR, and the system either shares everything or nothing. This approach fails when regulations require granular control—when a patient wants to share lab results but not mental health records, or permit data access for treatment but deny it for research.
This guide covers the FHIR Consent resource structure in depth, shows how to build three real-world consent scenarios with working JSON examples, explains how consent integrates with SMART on FHIR authorization, and walks through the IHE Privacy Consent on FHIR (PCF) profile that brings it all together for TEFCA-scale exchange.
FHIR Consent Resource: Structure and Semantics
The FHIR R4 Consent resource captures a patient's choices about how their health data may be used or disclosed. Understanding each element is critical before building consent workflows.
Core Elements
| Element | Purpose | Required |
|---|---|---|
status | draft, proposed, active, rejected, inactive, entered-in-error | Yes |
scope | What the consent covers: patient-privacy, research, treatment, adr | Yes |
category | Classification using LOINC codes (e.g., 64292-6 for release of info) | Yes |
patient | Reference to the Patient resource | No in R4 (0..1), but set it for any patient privacy consent |
dateTime | When consent was recorded | No |
performer | Who gave consent (patient, guardian, legal representative) | No |
organization | Organization that received the consent | No |
policy | Reference to the applicable regulation or policy | No |
provision | The actual rules: permit or deny, with filters | No |
The provision element is where consent gets powerful. It supports nested rules with filters by data type, actor, purpose, time period, and security label. A single Consent resource can express complex policies like "permit all data sharing for treatment, but deny substance use disorder records for any purpose except emergency treatment."
FHIR R4 (4.0.1). In R5, scope was removed, patient became subject, and provision.type moved to decision. Check which version your server runs. The three scenario examples below are R4 and pass the HL7 validator for 4.0.1.
Consent Scenario 1: Permit All Data Sharing
The simplest case—a patient consents to share all their health data with any authorized recipient for any permitted purpose. This is the baseline consent for healthcare interoperability exchanges.
{
"resourceType": "Consent",
"id": "consent-permit-all",
"status": "active",
"scope": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/consentscope",
"code": "patient-privacy",
"display": "Privacy Consent"
}]
},
"category": [{
"coding": [{
"system": "http://loinc.org",
"code": "64292-6",
"display": "Release of information consent"
}]
}],
"patient": {
"reference": "Patient/patient-jane-doe"
},
"dateTime": "2026-03-01T09:00:00Z",
"performer": [{
"reference": "Patient/patient-jane-doe"
}],
"organization": [{
"reference": "Organization/metro-health-system"
}],
"policyRule": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "OPTIN"
}]
},
"provision": {
"type": "permit",
"period": {
"start": "2026-03-01",
"end": "2027-03-01"
}
}
}Key points: the policyRule of OPTIN signals this is an affirmative consent. The provision.type of permit without additional filters means all data types are included. The period sets a one-year validity window—consent should always have an expiration.
Consent Scenario 2: Deny Mental Health Records
A patient shares all data except mental health records. This is common in states with heightened mental health privacy protections and is a critical use case for TEFCA exchanges where data crosses jurisdictional boundaries.
{
"resourceType": "Consent",
"id": "consent-deny-mental-health",
"status": "active",
"scope": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/consentscope",
"code": "patient-privacy"
}]
},
"category": [{
"coding": [{
"system": "http://loinc.org",
"code": "64292-6",
"display": "Release of information consent"
}]
}],
"patient": {
"reference": "Patient/patient-jane-doe"
},
"dateTime": "2026-03-01T09:00:00Z",
"policyRule": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "OPTIN"
}]
},
"provision": {
"type": "permit",
"period": {
"start": "2026-03-01",
"end": "2027-03-01"
},
"provision": [{
"type": "deny",
"class": [{
"system": "http://hl7.org/fhir/resource-types",
"code": "Condition"
},
{
"system": "http://hl7.org/fhir/resource-types",
"code": "Observation"
}],
"securityLabel": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "MH",
"display": "mental health information sensitivity"
}]
}]
}
}The nested provision structure is key. The outer provision permits all data. The inner provision denies specific resource types (Condition, Observation) when they carry the mental health (MH) security label. The example uses provision.securityLabel, not provision.code: code matches the codes inside a resource (for example a diagnosis code), while securityLabel matches the labels in the resource's meta.security. Use the label your labeling service applies. This requires your FHIR server to tag resources with security labels during ingestion—a prerequisite many organizations overlook.
Consent Scenario 3: Permit for Treatment, Deny for Research
A patient permits data sharing when the purpose is treatment but denies it when the purpose is research. This scenario directly maps to the TEFCA Permitted Purposes framework.
{
"resourceType": "Consent",
"id": "consent-treatment-only",
"status": "active",
"scope": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/consentscope",
"code": "patient-privacy"
}]
},
"category": [{
"coding": [{
"system": "http://loinc.org",
"code": "64292-6"
}]
}],
"patient": {
"reference": "Patient/patient-jane-doe"
},
"dateTime": "2026-03-01T09:00:00Z",
"policyRule": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "OPTIN"
}]
},
"provision": {
"type": "deny",
"provision": [
{
"type": "permit",
"purpose": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
"code": "TREAT",
"display": "Treatment"
}]
},
{
"type": "permit",
"purpose": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
"code": "ETREAT",
"display": "Emergency Treatment"
}]
}
]
}
}Notice the structure inversion: the outer provision is deny (default deny everything), and the inner provisions explicitly permit specific purposes. This deny-by-default pattern is more secure than permit-with-exceptions because any new purpose of use is automatically blocked until explicitly allowed.
Integrating Consent with SMART on FHIR OAuth
Consent capture should be part of the authorization flow, not a separate process. When a patient authorizes a third-party app through SMART on FHIR, the consent decision can be captured simultaneously.
Consent-Aware Authorization Flow
- App redirects to authorization server: Standard SMART launch with requested scopes (e.g.,
patient/Condition.read,patient/Observation.read). - Patient authenticates: Login through the organization's identity provider.
- Consent screen presented: Instead of a generic "authorize this app" screen, show granular consent options—which data categories to share, for what purposes, for how long.
- Consent resource created: The authorization server creates a FHIR Consent resource capturing the patient's choices.
- Token issued with consent-scoped claims: The access token includes claims that reference the Consent resource, allowing downstream services to enforce the consent.
- FHIR server enforces consent: On each data request, the server checks the referenced Consent resource and filters responses accordingly.
A Consent resource is a record. It does not by itself authorize or block access, and storing one is not legal authorization. The decision comes from a policy decision point that reads the consent, and the block comes from an enforcement point in front of the data.
# Access token JWT payload with consent reference
{
"iss": "https://auth.example.com",
"sub": "patient-jane-doe",
"aud": "https://fhir.example.com",
"scope": "patient/Condition.read patient/Observation.read",
"consent_reference": "Consent/consent-deny-mental-health",
"exp": 1773652800
}IHE Privacy Consent on FHIR (PCF) Profile
The IHE Privacy Consent on FHIR (PCF) profile standardizes how consent is captured, stored, and enforced across health information exchanges. It defines three levels of consent sophistication, and is directly relevant to TEFCA implementations.
PCF Consent Levels
| Level | Capability | Use Case |
|---|---|---|
| Basic | Opt-in or opt-out for all data sharing | Simple consent for HIE participation |
| Intermediate | Filters by data sensitivity category (mental health, substance use, HIV) | State law compliance, sensitive data protection |
| Advanced | Filters by data type, actor, purpose, time period | Granular patient preferences, research consent |
PCF defines specific actors in the consent enforcement chain:
- Consent Recorder: Captures the patient's consent decision and creates the FHIR Consent resource.
- Consent Registry: Stores Consent resources and makes them available for lookup.
- Consent Authorization Server: Evaluates data access requests against stored consent policies and issues authorization decisions.
- Consent Enforcement Point: Filters data responses based on authorization decisions.
TEFCA and Consent: What Changes
TEFCA introduces a national consent framework through its Qualified Health Information Networks (QHINs). TEFCA FHIR requirements depend on the exchange purpose, the participant role and the Standard Operating Procedure (SOP). The RCE FAQ currently lists some Individual Access Services FHIR requirements for July 2027. Check the current SOPs for your role.
Dates below come only from RCE documents (checked 15 October 2026). None of them is a consent-management requirement; they set the FHIR and identity ground that consent decisions run on.
| TEFCA requirement | Role | SOP / version | Date | Source |
|---|---|---|---|---|
| Updated IAS policies take effect | IAS Providers, QHINs, Participants, Subparticipants | IAS Exchange Purpose Implementation SOP v3.0 | 3 August 2026 | RCE FAQ |
| Distinct issuer URLs for production and non-production IAS exchange (section 4.3) | CSPs via IAS Providers | IAS XP Implementation SOP v3.0 | 1 October 2026 | RCE FAQ |
| Demographics double-check (section 4.7) | IAS Providers | IAS XP Implementation SOP v3.0 | 1 January 2027 | RCE FAQ |
| IAS FHIR endpoints support the HL7 SSRAA FHIR IG, Modes 1.2 and 2.3 (section 4.6) | QHINs, Participants, Subparticipants | IAS XP Implementation SOP v3.0 with the Facilitated FHIR Implementation SOP | 1 July 2027 | RCE FAQ |
| FHIR exchange may use US Core 3.1.1 or higher | All FHIR exchange | FHIR Implementation SOP | No date given | RCE FAQ |
TEFCA Permitted Purposes
TEFCA defines specific Permitted Purposes for data exchange—treatment, payment, health care operations, public health, benefits determination, and individual access. Each purpose maps to consent provisions that patients can control. For example, a patient who participates in TEFCA can permit data sharing for treatment while denying it for payment purposes.
Sensitive Data Under TEFCA
Certain data categories require explicit consent under federal and state law, regardless of TEFCA participation:
- Substance Use Disorder (42 CFR Part 2): Requires specific patient consent for any disclosure, with strict re-disclosure restrictions.
- Mental Health: Many states impose additional consent requirements beyond HIPAA.
- HIV/AIDS: State-specific consent requirements for disclosure.
- Reproductive Health: Post-Dobbs privacy concerns have led to new state-level protections.
- Genetic Information (GINA): Restrictions on use for insurance and employment decisions.
Your consent enforcement engine must understand these sensitivity categories and apply the correct consent rules. This is where security labels on FHIR resources become essential—each resource must be tagged with its sensitivity level so the consent engine can filter appropriately.
Consent Enforcement Architecture
Building a working consent enforcement system requires four components working together. Here is a practical architecture for organizations building healthcare integration platforms.
# Consent Enforcement Service (Python pseudocode)
def evaluate_consent(patient_id, requested_resources, purpose_of_use, requesting_actor):
"""Evaluate whether access is permitted based on active consent."""
# 1. Retrieve active consent for patient
consents = fhir_client.search('Consent', {
'patient': patient_id,
'status': 'active',
'scope': 'patient-privacy'
})
if not consents:
return apply_default_policy(patient_id) # Opt-in vs opt-out jurisdiction
# Most recent active consent by dateTime. Search result order is not
# guaranteed, so do not take consents[0].
consent = max(consents, key=lambda c: c['dateTime'])
# 2. Evaluate provision rules
filtered_resources = []
for resource in requested_resources:
decision = evaluate_provision(
consent['provision'],
resource=resource,
purpose=purpose_of_use,
actor=requesting_actor
)
if decision == 'permit':
filtered_resources.append(resource)
# 3. Log the access decision (required for audit)
create_audit_event(patient_id, purpose_of_use, requesting_actor,
total=len(requested_resources),
permitted=len(filtered_resources))
return filtered_resourcesTest the decision before you trust it
The service above calls evaluate_provision. Here is a small version of it for R4 Consent resources. A nested provision is an exception to the base rule, and it applies only when every filter it states matches the resource.
# Provision evaluation (Python, R4 Consent as dict)
from datetime import datetime, timezone
def in_period(provision, now):
period = provision.get("period")
if not period:
return True
start, end = period.get("start"), period.get("end")
today = now.date().isoformat()
return (not start or start <= today) and (not end or today < end)
def matches(rule, resource, purpose):
"""A nested rule applies only if every filter it states matches."""
if "class" in rule and resource["resourceType"] not in [c["code"] for c in rule["class"]]:
return False
if "securityLabel" in rule:
labels = {(s.get("system"), s["code"]) for s in resource.get("meta", {}).get("security", [])}
if not any((l.get("system"), l["code"]) in labels for l in rule["securityLabel"]):
return False
if "purpose" in rule and purpose not in [p["code"] for p in rule["purpose"]]:
return False
return True
def evaluate_provision(provision, resource, purpose, actor=None, now=None):
now = now or datetime.now(timezone.utc)
if not in_period(provision, now):
return "deny" # expired consent shares nothing
decision = provision["type"] # base rule
for rule in provision.get("provision", []):
if matches(rule, resource, purpose):
decision = rule["type"] # nested rule is an exception to the base
return decision # actor filters are not handled in this sketchRun these six cases against evaluate_consent as one parametrised pytest before go-live:
| Case | Consent on file | Expected result |
|---|---|---|
| Treatment request with an active permit | Scenario 1 | Resource returned |
| Research request (purpose HRESCH) | Scenario 3, deny by default | Nothing returned |
| Observation labelled MH | Scenario 2 | Labelled Observation withheld, unlabelled Condition returned |
| Consent revoked a minute ago | Scenario 1 set to inactive | Default policy applies, not the old permit |
| Consent period has ended | Permit with an end date in the past | Nothing returned |
| Two active consents that conflict | Scenario 1 and a newer Scenario 3 | The newer consent (by dateTime) decides |
Pick the most recent active consent by dateTime, not consents[0]: a FHIR search does not promise any order unless you ask for one. Better still, make the consent registry allow only one active privacy consent per patient.
Security Labels: The Missing Prerequisite
Consent enforcement only works if resources are tagged with security labels. Without labels, the consent engine cannot distinguish a mental health Condition from a diabetes Condition. You need a labeling pipeline that tags resources at ingestion time based on diagnosis codes, encounter types, and ordering context.
| Security Label | Category | ICD-10 Range | Regulation |
|---|---|---|---|
MH | Mental Health | F01-F99 | State mental health laws |
ETH | Substance Use Disorder | F10-F19 | 42 CFR Part 2 |
HIV | HIV/AIDS | B20-B24, Z21 | State HIV disclosure laws |
PSY | Psychiatry | F20-F29 (psychotic) | State-specific |
SDV | Sexual/Domestic Violence | T74-T76 | State-specific |
SEX | Reproductive/Sexual Health | O00-O99, Z30-Z39 | Post-Dobbs state laws |
Each resource ingested into the FHIR server should pass through a labeling service that evaluates its clinical content against this mapping table and applies the appropriate meta.security labels. Resources may carry multiple labels—a Condition for opioid use disorder would receive both MH and ETH labels, requiring consent evaluation against both categories.
Consent Versioning and Lifecycle Management
Consent is not a one-time event—it is a living document that changes over time. A robust consent management system must handle the full lifecycle: creation, activation, modification, revocation, and expiration. When a patient updates their consent preferences, you should not modify the existing Consent resource. Instead, create a new Consent resource with status: active and set the previous one to status: inactive. This preserves an audit trail showing what consent was in effect at any point in time—critical for compliance investigations and litigation.
Consent expiration is equally important. The provision.period element should always have an end date. When consent expires, your system must either block data sharing until the patient re-consents (in opt-in jurisdictions) or fall back to a default policy (in opt-out jurisdictions). Build automated re-consent workflows that notify patients 30 days before expiration and provide a simple digital mechanism to renew.
For organizations participating in TEFCA, consent versioning becomes even more complex because consent decisions may need to be communicated to multiple QHINs. Consider implementing a consent event bus that publishes consent changes to all downstream consumers—ensuring that revocation takes effect across the entire network, not just at the originating organization. This pattern aligns well with event-driven healthcare architectures that use message queues for cross-system coordination.
Common Pitfalls in Consent Implementation
- Paper consent without digital enforcement: Scanning a consent form into the EHR provides documentation but no automated enforcement. You need computable consent—FHIR Consent resources that the system can evaluate programmatically.
- All-or-nothing consent: Many systems only support opt-in or opt-out for all data. Patients increasingly want granular control, and regulations like 42 CFR Part 2 require it for specific data categories.
- Missing security labels: Without sensitivity labels on FHIR resources, granular consent enforcement is impossible. Build the labeling pipeline before building the consent engine.
- Consent drift: Consent decisions expire or change. Your system must handle consent revocation, expiration, and updates. An expired consent should trigger a re-consent workflow, not silently fail to share data.
- Ignoring state law variations: Each US state has different consent requirements for sensitive data. A national exchange like TEFCA must apply the most restrictive applicable law—which may be the patient's home state, the provider's state, or both.
Frequently Asked Questions
What is the FHIR Consent resource used for?
The FHIR Consent resource captures a patient's decisions about how their health data can be used or disclosed. It supports granular controls—patients can permit or deny access by data type, purpose of use, recipient, and time period. The resource is used for privacy consent, research consent, treatment consent, and advance directive documentation.
How does TEFCA handle patient consent?
TEFCA requires participants to comply with applicable federal and state consent laws. For most treatment purposes, HIPAA's minimum necessary standard applies without explicit patient consent. For sensitive data categories (substance use disorder, mental health), explicit patient consent is required before disclosure. TEFCA FHIR requirements depend on the exchange purpose, the participant role and the Standard Operating Procedure (SOP). The RCE FAQ currently lists some Individual Access Services FHIR requirements for July 2027. Check the current SOPs for your role.
What is the IHE PCF profile?
The IHE Privacy Consent on FHIR (PCF) profile standardizes consent capture, storage, and enforcement using FHIR resources. It defines three levels (Basic, Intermediate, Advanced) for different granularity needs, and specifies actors like Consent Recorder, Consent Registry, and Consent Authorization Server.
Can patients revoke consent?
Yes. Setting the Consent resource status to inactive or creating a new Consent with status: active that supersedes the previous one. Your system should immediately stop sharing data when consent is revoked and log the revocation for audit purposes.
How do security labels work with consent?
Security labels are metadata tags on FHIR resources that classify their sensitivity level (e.g., MH for mental health, ETH for substance use disorder). The consent enforcement engine checks these labels against the consent provisions to determine whether each resource should be included in a response. Without security labels, granular consent enforcement is not possible.
Ready to scale?
Talk to our healthcare engineering team about building, integrating, and shipping faster.
Frequently Asked Questions
What is the FHIR Consent resource?
How do you model a consent that denies mental health records in FHIR?
How does FHIR consent integrate with SMART on FHIR authorization?
What is the IHE Privacy Consent on FHIR (PCF) profile?
What does TEFCA require for consent management?
How does Nirmitee.io approach healthcare software development?