legitimate-interest
legitimate_interest Validator Documentation
Advanced Policy-Driven Access Control for FHIR Resources
Intent
The legitimate_interest validator enforces granular, context-aware access rules to comply with regulatory frameworks (e.g., GDPR) or organizational policies. Unlike static compartment validators, it dynamically evaluates relationships between users, resources, and organizations to determine if a "legitimate interest" exists for accessing data.
Why Use This Validator?
- Multi-Tenant Systems: Manage access across organizations sharing a single FHIR repository.
- Regulatory Compliance: Enforce GDPR-like rules where access requires explicit justification.
- Hierarchical Access: Support nested organizations (e.g., hospitals with parent/child units).
Core Concepts
1. ActiveOrganizations
A practitioner’s ActiveOrganizations are derived from their active PractitionerRole resources:
ActiveOrganizations = PractitionerRole.where(
practitioner == Practitioner.id &&
active == true
).organization
Example: A doctor with roles at General Hospital and Cardiology Unit can access both compartments.
2. Organization Compartment
For practitioners, this includes:
- All patients where
Patient.managingOrganizationmatches an active organization. - All resources in those patients’ compartments (e.g., Observations, Appointments).
3. Role Inheritance
Configure legitimate_interest.role_inheritance_levels to allow roles to cascade down organizational hierarchies.
- Level 0: No inheritance (default).
- Level 2: Inherit roles from two parent levels (e.g., hospital → department → ward).
Detailed Workflow
For Patient Clients
- Role Check: Confirm the client has the
Patientrole. - Resource Validation:
- If the resource is in the
patient_compartment, allow access. - If the resource is an
Organization, allow access if it matchesPatient.managingOrganization. - If the resource is a
PractitionerorPractitionerRole, allow access if linked to the patient’s managing organization.
- If the resource is in the
Example:
A patient can view their managing organization (Organization/123) and practitioners affiliated with it, but not other organizations.
For Practitioner Clients
- Role Check: Confirm the client has the
Practitionerrole. - Fetch ActiveOrganizations: Query active
PractitionerRoleentries for the practitioner. - Resource Validation:
- Direct Access: Resource references an
ActiveOrganization(e.g.,Organization/123). - Indirect Access: Resource belongs to a patient in the practitioner’s organization compartment.
- Direct Access: Resource references an
Example:
A practitioner with ActiveOrganizations = [Organization/123] can:
- Read
Patientresources wherePatient.managingOrganization = Organization/123. - Read
Observationresources for those patients.
Advanced Configuration
1. Role-Specific Access
Require specific practitioner roles using required_role_system and required_role_code:
{
"client_role": "Practitioner",
"entity_name": "Patient",
"operation": "write",
"validator": "legitimate_interest",
"params": {
"required_role_system": "http://hospital.org/roles",
"required_role_code": "admin"
}
}
Explanation: Only practitioners with an active PractitionerRole containing role.code = "admin" can modify patient records.
2. Caching Behavior
- Cache Scope: Stores
PractitionerRole,Organization, andPatientdata. - Timeout: 2 minutes (configurable via
cache_ttl). - Limitation: Updates to roles/organizations may take up to 2 minutes to reflect.
Mitigation Strategies:
- Pair read/write rules for the same resource to trigger cache invalidation.
- Use webhooks to manually clear the cache on critical updates.
Validation Strategy Table
Entity-Specific Rules (Simplified)
| Resource Type | Practitioner Validation | Patient Validation |
|---|---|---|
| Patient | managingOrganization ∈ ActiveOrganizations | organization_compartment |
| Observation | subject.managingOrganization ∈ ActiveOrganizations | patient_compartment |
| Organization | ID ∈ ActiveOrganizations | Must match Patient.managingOrganization |
| PractitionerRole | organization ∈ ActiveOrganizations | Must be in Patient.general_practitioner |
| Appointment | actor.managingOrganization ∈ ActiveOrganizations | patient_compartment |
Role Inheritance Deep Dive
Configuration
# config.yaml
legitimate_interest.role_inheritance_levels: 2
Use Case: Hospital Hierarchy
- Structure:
- Root:
Organization/hospital - Children:
Organization/cardiology,Organization/orthopedics
- Root:
- Behavior:
- A practitioner with roles at
Organization/hospitalcan access data in child departments. - A practitioner at
Organization/cardiologycannot accessOrganization/orthopedicsunless explicitly granted.
- A practitioner with roles at
Performance Impact
- Network Requests: Each inheritance level adds 1 request to resolve parent-child relationships.
- Recommendation: Limit inheritance to 2–3 levels for latency-sensitive systems.
Best Practices
1. Avoid Overcomplication
- Use
patient_compartmentfor simple patient-owned data. - Reserve
legitimate_interestfor multi-organization or regulatory scenarios.
2. Error Handling
- Cache Misses: Log warnings when cached data is stale.
- Role Conflicts: Prioritize
required_role_codeover inherited roles.
3. Testing
- Unit Tests: Validate rules against mock FHIR resources.
- Edge Cases: Test access denials for:
- Practitioners with expired roles.
- Patients accessing disassociated organizations.
FHIR Resource Links
- PractitionerRole: FHIR R4 Specification
- Compartments: FHIR Compartment Guide
- GDPR & Legitimate Interest: GDPR Article 6(1)(f)
Example: GDPR-Compliant Access
Scenario: A patient requests access to all data shared with their managing organization.
Validator Workflow:
- Patient requests
Bundleof resources. legitimate_interestallows:- Resources in their
patient_compartment. OrganizationandPractitionerRolelinked to their managing organization.
- Resources in their
- Blocks access to unrelated resources (e.g., another patient’s
DiagnosticReport).