Skip to main content

Fire Arrow Server 1.9.0

· 4 min read

Fire Arrow Server 1.9.0 has been released.

  • (security) Remove the 100,000-resource scope limit that could silently restrict authorization for very large practitioner caseloads
  • (feature) Add GeneralPractitioner authorization validator for Patient.generalPractitioner based access control
  • (feature) Route Subscription notifications to per-Subscription Azure Storage Queues via channel.endpoint suffix
  • (security) Dependency upgrades for org.postgresql:postgresql, spring-security-core, spring-security-oauth2-jose, and postcss

Authorization Scaling for Large Caseloads

The LegitimateInterest and CareTeam validators previously computed a caller's accessible scope by materialising the full set of accessible resource IDs up front. That approach worked for typical caseloads but had a hard upper bound of 100,000 resources per scope. Beyond the limit, only a warning was logged and the caller was silently authorized to a non-deterministic subset of their data.

Starting with 1.9.0, both validators evaluate access against the underlying relationships at query time rather than materialising the scope in advance. Authorization no longer scales with the number of accessible patients, the silent truncation is gone, and the SQL the database executes stays compact regardless of caseload size.

This change is internal to the authorization layer — the set of resources a client is allowed to read is unchanged, and no configuration is required to opt in. Deployments that previously came close to the 100,000 ceiling will see correct, complete results.

GeneralPractitioner Validator

A new validator implements access control around the Patient.generalPractitioner link. It supports both client roles relevant to a primary-care relationship:

  • Patient clients can read the Practitioner, Organization, and PractitionerRole resources listed as their general practitioners. PractitionerRole references in the GP list are expanded so that the underlying Practitioner and Organization are reachable as well.
  • Practitioner clients can read, create, update, and delete Patient resources whose generalPractitioner list contains the practitioner directly, one of the practitioner's active PractitionerRoles, or one of the organizations from those roles. The same access extends to patient-compartment resources (Observation, Condition, Encounter, etc.) for those patients.

Compared to LegitimateInterest, GeneralPractitioner resolves a much smaller scope and is intended for deployments where the GP link — rather than organizational membership — is the access-granting relationship.

application.yaml
fire-arrow:
authorization:
validation-rules:
- client-role: Practitioner
resource: Patient
operation: read
validator: GeneralPractitioner
- client-role: Patient
resource: Practitioner
operation: read
validator: GeneralPractitioner

See the GeneralPractitioner validator documentation for the full access matrix, PractitionerRole expansion behaviour, and recommendations for combining it with PatientCompartment for patient-side clinical data.

Per-Subscription Azure Queue Routing

Azure Queue subscription delivery previously sent every notification to the single queue named in fire-arrow.subscription.azure-queue.queue-name. Multi-tenant or multi-domain deployments that wanted to fan notifications out to per-tenant queues had to run a separate Fire Arrow instance per queue.

Starting with 1.9.0, a Subscription can opt into a different destination queue by setting channel.endpoint to the well-known prefix (channel:fire-arrow-azure-queue by default) followed by :<queue-name>:

{
"resourceType": "Subscription",
"status": "requested",
"criteria": "CommunicationRequest?status=active",
"channel": {
"type": "message",
"endpoint": "channel:fire-arrow-azure-queue:identity-resolution-events"
}
}

The endpoint suffix selects a separate Azure Storage Queue resource in the same storage account, not a sub-channel inside one queue. Because the suffix can be set by any Subscription writer, override routing is deny-by-default: the operator must add each acceptable queue name to the new allowed-override-queues allow-list before suffix-based routing takes effect. Names that do not appear in the allow-list, or that are syntactically invalid, fall back to the configured default queue and emit a warning.

Override queues are not auto-created by default. The recommended workflow is to provision per-tenant queues out-of-band (Bicep, Terraform, deploy script) and add their names to allowed-override-queues. Operators who prefer lazy creation can enable auto-create-override-queues.

Subscriptions without the prefix (REST Hook URLs, blank endpoints, malformed strings) and Subscriptions whose endpoint is exactly the prefix without a suffix continue to route to the configured default queue, so existing single-queue deployments are unaffected.

See the Subscriptions documentation for the full destination-resolution table and the new configuration properties.

Security

This release picks up four upstream dependency updates flagged as security-relevant:

  • org.postgresql:postgresql updated to 42.7.11
  • org.springframework.security:spring-security-core updated to 6.5.10
  • org.springframework.security:spring-security-oauth2-jose updated to 6.5.10
  • postcss (administration UI) updated to 8.5.10