Skip to main content

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.
Choose the simplest validator

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 roleAccess model
PatientPatient compartment + managing organization's resources
PractitionerAll 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:

  1. Their own Patient resource — the patient can always read and update their own record.
  2. Patient compartment resources — all resources in the standard FHIR Patient compartment (observations, conditions, encounters, etc.).
  3. Managing organization — the Organization resource referenced in Patient.managingOrganization.
  4. Practitioners and roles in the managing organization — all Practitioner and PractitionerRole resources linked to the managing organization. This lets patients see their care providers.
  5. Organization compartment resources — resources that belong to the managing organization through specific reference fields (see table below).
  6. TasksTask resources 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:

  1. Their own Practitioner resource — always accessible, regardless of organizational membership.
  2. Organizations — every organization where the practitioner has an active PractitionerRole.
  3. Fellow practitioners and roles — all Practitioner and PractitionerRole resources in those organizations.
  4. Patients — all patients where Patient.managingOrganization points to one of the accessible organizations.
  5. Patient compartment resources — clinical data (observations, conditions, encounters, etc.) for those patients.
  6. Organization compartment resources — resources linked to the accessible organizations through specific reference fields (see table below).
  7. TasksTask resources 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:

  • PractitionerRole with organization = Organization/city-general and code doctor
  • PractitionerRole with organization = Organization/downtown-clinic and code doctor

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.

ResourceReference fieldHow it links to the organization
DeviceownerThe organization that owns or is responsible for the device
DeviceDefinitionownerThe organization that owns the device definition
HealthcareServiceprovidedByThe organization providing the healthcare service
InsurancePlanownedByThe organization that administers the insurance plan
LocationmanagingOrganizationThe organization responsible for the location
OrganizationAffiliationorganizationThe primary organization in the affiliation
PaymentNoticeproviderThe organization that is the payment provider
PaymentReconciliationrequestorThe organization that requested the reconciliation
PersonmanagingOrganizationThe organization responsible for the person record
RegulatedAuthorizationholderThe organization holding the authorization
ResearchStudysponsorThe organization sponsoring the study
Person resource: dual compartment

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 by practitioner-role-system and practitioner-role-code)
  • ManagingOrg = The patient's Patient.managingOrganization

Practitioner clients

ResourceAccess rule
PractitionerOwn resource + all practitioners in ActiveOrganizations
OrganizationAll ActiveOrganizations
PractitionerRoleAll roles in ActiveOrganizations
PatientAll patients where managingOrganization is in ActiveOrganizations
TaskTasks where Task.for is a patient in ActiveOrganizations
Organization compartment resourcesResources where the organization reference field points to an ActiveOrganization (see table above)
All other resourcesPatient compartment: accessible if the resource's subject/patient is a patient in ActiveOrganizations

Patient clients

ResourceAccess rule
PatientOwn resource only
OrganizationManagingOrg only
PractitionerAll practitioners with active roles in ManagingOrg
PractitionerRoleAll roles in ManagingOrg
TaskTasks where Task.for is the patient
PersonPatient compartment (via Person.patient) + organization compartment (via Person.managingOrganization = ManagingOrg)
Organization compartment resourcesResources where the organization reference field points to ManagingOrg (see table above)
All other resourcesPatient 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
application.yaml
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:

application.yaml
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:

application.yaml
fire-arrow:
validators:
legitimate-interest:
role-inheritance-levels: 2
SettingDescription
role-inheritance-levels: 0Default. No inheritance. A practitioner only accesses data in organizations where they have a direct PractitionerRole.
role-inheritance-levels: 1The practitioner also accesses data in child organizations one level deep.
role-inheritance-levels: 2Two levels deep: direct organization + children + grandchildren.
role-inheritance-levels: NUp 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/regional can only see data in Organization/regional.
  • A practitioner at Organization/cardiology can only see cardiology data.

With role-inheritance-levels: 2:

  • A practitioner with a role at Organization/regional can see data in all four organizations (regional + city-general + cardiology + radiology).
  • A practitioner at Organization/city-general can see data in city-general + cardiology + radiology.
  • A practitioner at Organization/cardiology can 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).
Performance impact

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:

  1. Resolving the practitioner's organization memberships (one query)
  2. If role inheritance is enabled, walking the organization hierarchy (one query per inheritance level)
  3. 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 typeCostExplanation
Read/search own compartment resourcesConstantUses FHIR compartment rules directly
Read managing organizationConstantSingle reference lookup, cached after first access
Search practitioners in managing orgScales with practitioners per orgEnumerates practitioners in one organization, not all
Access organization compartment resourcesScales with resources per orgEnumerates resources linked to one organization

Practitioner client requests are more expensive and scale with organizational scope:

Operation typeCostExplanation
Read own Practitioner resourceConstantDirect instance access
Search patientsScales with patients across all accessible orgsMust enumerate all patients in all organizations where the practitioner has a role
Search patient compartment resourcesScales with patients across all accessible orgsThe set of accessible patients must be resolved before the search can be narrowed
Search organization compartment resourcesScales with resources across all accessible orgsEnumerates 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, PatientCompartment is orders of magnitude faster than LegitimateInterest.
  • Role inheritance adds latency — each inheritance level requires an additional database query to walk the organization hierarchy. Use the minimum number of levels necessary.