LegitimateInterest
The LegitimateInterest validator implements organization-based access control. It grants access to FHIR resources based on the organizational relationships between the authenticated client and the data. This is the most powerful validator in Fire Arrow Server and is designed for real-world healthcare scenarios where access depends on organizational affiliation rather than direct resource ownership.
When to use
Use LegitimateInterest when:
- Practitioners need access to all patients and clinical data within their organization, not just resources they personally authored.
- Patients need access to organizational resources such as practitioner directories, locations, healthcare services, or devices belonging to their healthcare provider.
- You need to support multi-tenant deployments where multiple organizations share a single FHIR server and each organization's data must remain isolated.
- You need role-based differentiation within an organization, such as allowing doctors to access patient data but restricting IT administrators to organizational resources only.
- Organization hierarchies exist (e.g., hospital → department → ward) and parent organizations need visibility into child organization data.
If a compartment validator (PatientCompartment, PractitionerCompartment) achieves the same result, prefer it. LegitimateInterest is more powerful but also more resource-intensive because it resolves organizational memberships and patient sets on every request.
Supported client roles
LegitimateInterest supports two client roles:
| Client role | Access model |
|---|---|
| Patient | Patient compartment + managing organization's resources |
| Practitioner | All resources within the organizations where the practitioner has active roles |
Using LegitimateInterest with any other client role (RelatedPerson, Device) will result in an error. For those roles, consider using the CareTeam validator or the corresponding compartment validators.
How it works: Patient clients
For patient clients, LegitimateInterest extends the standard PatientCompartment behavior with access to organizational resources. The key link is Patient.managingOrganization — the organization responsible for the patient's care.
A patient client gets access to:
- Their own Patient resource — the patient can always read and update their own record.
- Patient compartment resources — all resources in the standard FHIR Patient compartment (observations, conditions, encounters, etc.).
- Managing organization — the
Organizationresource referenced inPatient.managingOrganization. - Practitioners and roles in the managing organization — all
PractitionerandPractitionerRoleresources linked to the managing organization. This lets patients see their care providers. - Organization compartment resources — resources that belong to the managing organization through specific reference fields (see table below).
- Tasks —
Taskresources where the patient is the subject (Task.for).
Real-world example: Patient portal
A patient registered at "City General Hospital" (their managing organization) opens their patient portal app. Through LegitimateInterest, they can:
- View their lab results, medications, and appointments (patient compartment)
- Browse the hospital's practitioner directory to find a specialist (practitioners in managing organization)
- See the hospital's locations and available healthcare services (organization compartment)
- View their insurance plans offered by the hospital (organization compartment)
- Access their care tasks and action items (tasks)
They cannot see patients, practitioners, or data belonging to a different hospital.
How it works: Practitioner clients
For practitioner clients, LegitimateInterest builds what is effectively an "organization compartment" — access to all resources that belong to the practitioner's organizations.
A practitioner's accessible organizations are determined by their active PractitionerRole resources. If a practitioner has an active PractitionerRole with PractitionerRole.organization = Organization/hospital-a, they gain access to all data within Organization hospital-a.
A practitioner client gets access to:
- Their own Practitioner resource — always accessible, regardless of organizational membership.
- Organizations — every organization where the practitioner has an active
PractitionerRole. - Fellow practitioners and roles — all
PractitionerandPractitionerRoleresources in those organizations. - Patients — all patients where
Patient.managingOrganizationpoints to one of the accessible organizations. - Patient compartment resources — clinical data (observations, conditions, encounters, etc.) for those patients.
- Organization compartment resources — resources linked to the accessible organizations through specific reference fields (see table below).
- Tasks —
Taskresources where the subject (Task.for) is a patient in the accessible organizations.
Real-world example: Hospital practitioner
Dr. Smith is a cardiologist at "City General Hospital" and also has a consulting role at "Downtown Clinic". She has two active PractitionerRole resources:
PractitionerRolewithorganization = Organization/city-generaland codedoctorPractitionerRolewithorganization = Organization/downtown-clinicand codedoctor
Through LegitimateInterest, Dr. Smith can:
- Access all patients registered at either hospital
- View clinical data (observations, conditions, medications) for those patients
- See other practitioners and their roles at both organizations
- Access organizational resources (devices, locations, healthcare services) at both organizations
- Manage care tasks for patients at either organization
She cannot see data belonging to "Uptown Medical Center" where she has no role.
Organization compartment resources
The following resource types are linked to organizations through specific reference fields. Both patient and practitioner clients can access these resources when they have a legitimate interest in the corresponding organization.
| Resource | Reference field | How it links to the organization |
|---|---|---|
Device | owner | The organization that owns or is responsible for the device |
DeviceDefinition | owner | The organization that owns the device definition |
HealthcareService | providedBy | The organization providing the healthcare service |
InsurancePlan | ownedBy | The organization that administers the insurance plan |
Location | managingOrganization | The organization responsible for the location |
OrganizationAffiliation | organization | The primary organization in the affiliation |
PaymentNotice | provider | The organization that is the payment provider |
PaymentReconciliation | requestor | The organization that requested the reconciliation |
Person | managingOrganization | The organization responsible for the person record |
RegulatedAuthorization | holder | The organization holding the authorization |
ResearchStudy | sponsor | The organization sponsoring the study |
The Person resource is a special case. For patient clients, it can be accessed through both the patient compartment (via Person.patient) and the organization compartment (via Person.managingOrganization). Access through either path is sufficient.
Validation strategy by resource type
The table below shows how access is validated for each resource type, broken down by client role. Understanding this table helps you predict exactly what data a client will see.
Definitions:
- ActiveOrganizations = Organizations where the practitioner has an active
PractitionerRole(optionally filtered bypractitioner-role-systemandpractitioner-role-code) - ManagingOrg = The patient's
Patient.managingOrganization
Practitioner clients
| Resource | Access rule |
|---|---|
Practitioner | Own resource + all practitioners in ActiveOrganizations |
Organization | All ActiveOrganizations |
PractitionerRole | All roles in ActiveOrganizations |
Patient | All patients where managingOrganization is in ActiveOrganizations |
Task | Tasks where Task.for is a patient in ActiveOrganizations |
| Organization compartment resources | Resources where the organization reference field points to an ActiveOrganization (see table above) |
| All other resources | Patient compartment: accessible if the resource's subject/patient is a patient in ActiveOrganizations |
Patient clients
| Resource | Access rule |
|---|---|
Patient | Own resource only |
Organization | ManagingOrg only |
Practitioner | All practitioners with active roles in ManagingOrg |
PractitionerRole | All roles in ManagingOrg |
Task | Tasks where Task.for is the patient |
Person | Patient compartment (via Person.patient) + organization compartment (via Person.managingOrganization = ManagingOrg) |
| Organization compartment resources | Resources where the organization reference field points to ManagingOrg (see table above) |
| All other resources | Patient compartment (standard FHIR Patient compartment check) |
Practitioner role filtering
Authorization rules can optionally require that the practitioner holds a specific role in the organization. This is configured through the practitioner-role-system and practitioner-role-code fields on the validation rule. Both fields must be specified together.
When role filtering is active, the practitioner's accessible organizations are narrowed to only those where they have a PractitionerRole with a matching code entry (both system and code must match).
Real-world example: Role-based access tiers
A hospital wants to implement different access levels for different staff roles:
- Doctors can read and update patient data
- IT administrators can manage organizational resources (practitioners, devices, locations) but cannot access patient clinical data
- Nurses can read patient data but not modify it
fire-arrow:
authorization:
default-validator: Forbidden
validation-rules:
# Doctors: full access to patient data
- client-role: Practitioner
resource: Patient
operation: read
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: doctor
- client-role: Practitioner
resource: Patient
operation: update
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: doctor
- client-role: Practitioner
resource: Observation
operation: search
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: doctor
# Nurses: read-only patient data
- client-role: Practitioner
resource: Patient
operation: read
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: nurse
- client-role: Practitioner
resource: Observation
operation: search
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: nurse
# IT administrators: manage organizational resources only
- client-role: Practitioner
resource: Practitioner
operation: search
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: ict
- client-role: Practitioner
resource: Device
operation: read
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: ict
- client-role: Practitioner
resource: Location
operation: search
validator: LegitimateInterest
practitioner-role-system: http://hl7.org/fhir/ValueSet/practitioner-role
practitioner-role-code: ict
With this configuration, Dr. Smith (role: doctor) can read patient data but cannot manage devices. The IT administrator (role: ict) can manage devices and practitioner records but cannot access any patient clinical data.
Configuration
Validation rules
LegitimateInterest is specified as a simple string value in the validator field of a validation rule:
fire-arrow:
authorization:
validation-rules:
- client-role: Practitioner
resource: Patient
operation: read
validator: LegitimateInterest
Role inheritance
The LegitimateInterest validator supports role inheritance through the organization hierarchy. FHIR organizations can form a hierarchy using the Organization.partOf reference. When role inheritance is enabled, a practitioner with a role at a parent organization gains access to data in child organizations.
Role inheritance is configured separately from the validation rules, under the fire-arrow.validators.legitimate-interest section:
fire-arrow:
validators:
legitimate-interest:
role-inheritance-levels: 2
| Setting | Description |
|---|---|
role-inheritance-levels: 0 | Default. No inheritance. A practitioner only accesses data in organizations where they have a direct PractitionerRole. |
role-inheritance-levels: 1 | The practitioner also accesses data in child organizations one level deep. |
role-inheritance-levels: 2 | Two levels deep: direct organization + children + grandchildren. |
role-inheritance-levels: N | Up to N levels deep. Maximum value is 10. |
Real-world example: Hospital hierarchy
Consider a hospital with the following organizational structure:
Regional Health Authority (Organization/regional)
└── City General Hospital (Organization/city-general, partOf: Organization/regional)
├── Cardiology Department (Organization/cardiology, partOf: Organization/city-general)
└── Radiology Department (Organization/radiology, partOf: Organization/city-general)
With role-inheritance-levels: 0 (default):
- A practitioner with a role at
Organization/regionalcan only see data inOrganization/regional. - A practitioner at
Organization/cardiologycan only see cardiology data.
With role-inheritance-levels: 2:
- A practitioner with a role at
Organization/regionalcan see data in all four organizations (regional + city-general + cardiology + radiology). - A practitioner at
Organization/city-generalcan see data in city-general + cardiology + radiology. - A practitioner at
Organization/cardiologycan still only see cardiology data (inheritance goes downward, not upward).
This supports scenarios where:
- Hospital administrators at the parent organization need visibility across all departments.
- Department staff should only see data within their department.
- SaaS vendors can create a virtual root organization and gain access to customer data when customers link their organization as a child (for support purposes).
Each level of role inheritance requires additional database queries to resolve the organization hierarchy. Use the minimum number of levels necessary for your use case. For deeply nested hierarchies, consider whether the performance trade-off is acceptable.
Resource creation
For practitioner clients, the LegitimateInterest validator permits creating resources that are linked to the practitioner's accessible organizations. The validator checks that the new resource's organization reference field points to one of the practitioner's organizations. Practitioners cannot create new Practitioner resources — this must be handled through a different rule (e.g., Allowed with appropriate role filtering).
For patient clients, resource creation is restricted to the patient compartment and organization compartment resources linked to the patient's managing organization. Patients cannot create Patient, Organization, Practitioner, or PractitionerRole resources.
Performance
The LegitimateInterest validator is significantly more resource-intensive than compartment validators because it must resolve organizational memberships and enumerate accessible resources on every request. Understanding its performance characteristics helps you plan capacity and design your authorization rules effectively.
Cache behavior
Fire Arrow Server uses a multi-layer Caffeine cache to minimize database queries:
- Layer 1 (Identity): Caches identity resolution mappings (which FHIR resource corresponds to an authentication token). This layer has a longer TTL (default: 10 minutes) since identities rarely change.
- Layer 2 (Structural): Caches practitioner organization memberships, organization hierarchy (for role inheritance), and patient managing organization lookups. Default TTL: 60 seconds.
- Layer 3 (Enumeration): Caches per-organization lists of patients, practitioners, and practitioner roles. Default TTL: 60 seconds.
Cache entries are automatically invalidated when relevant resources are modified. For example, creating a new PractitionerRole invalidates the practitioner's cached organization membership and the organization's cached practitioner list. Invalidation is deferred until after the database transaction commits to prevent stale reads from concurrent requests.
Cache warm-up
The first request from a given client after server startup (or after a cache miss) will be noticeably slower because it triggers database lookups to populate the cache layers. For a practitioner client, this involves:
- Resolving the practitioner's organization memberships (one query)
- If role inheritance is enabled, walking the organization hierarchy (one query per inheritance level)
- Enumerating patients in the accessible organizations (one query per organization)
Subsequent requests from the same client (or from other clients accessing the same organizations) benefit from cached results and are significantly faster.
Scaling characteristics
Patient client requests scale well regardless of total system size:
| Operation type | Cost | Explanation |
|---|---|---|
| Read/search own compartment resources | Constant | Uses FHIR compartment rules directly |
| Read managing organization | Constant | Single reference lookup, cached after first access |
| Search practitioners in managing org | Scales with practitioners per org | Enumerates practitioners in one organization, not all |
| Access organization compartment resources | Scales with resources per org | Enumerates resources linked to one organization |
Practitioner client requests are more expensive and scale with organizational scope:
| Operation type | Cost | Explanation |
|---|---|---|
| Read own Practitioner resource | Constant | Direct instance access |
| Search patients | Scales with patients across all accessible orgs | Must enumerate all patients in all organizations where the practitioner has a role |
| Search patient compartment resources | Scales with patients across all accessible orgs | The set of accessible patients must be resolved before the search can be narrowed |
| Search organization compartment resources | Scales with resources across all accessible orgs | Enumerates resources linked to all accessible organizations |
Multi-organization practitioners (practitioners with roles in many organizations) experience the highest latency because lookups are multiplied across all accessible organizations. The performance impact grows linearly with the number of organizations.
Recommendations
- Use the cache — it is enabled by default and provides substantial speedups for repeated requests. Only disable it for debugging purposes.
- Minimize organization count per practitioner — practitioners with roles in many organizations will have slower requests. Consider whether role inheritance can replace explicit multi-org membership.
- Prefer compartment validators where possible — for patient-facing rules where only the patient's own data needs to be accessible,
PatientCompartmentis orders of magnitude faster thanLegitimateInterest. - Role inheritance adds latency — each inheritance level requires an additional database query to walk the organization hierarchy. Use the minimum number of levels necessary.