Skip to content

Multi-tenancy

Multi-tenancy allows each FHIR resource on the Kodjin FHIR server to be stored in a single database while remaining isolated by different ownership. Multi-tenancy is designed for flexibility and can achieve various outcomes.

This feature is desired when each resource pool belongs to a distinct user group, organization, customer, etc. (referred to as a "tenant"), and these tenants should not access or modify data belonging to other tenants.

Kodjin FHIR Server assigns resources to specific tenants by extracting tenant information from an access token provided with a request in the Authorization header.

The RBAC option is mandatory for implementations where multi-tenancy is configured to operate with external requests (which is the case in most instances).

There's also a list of common resources accessible to all tenants. These are defined in an exclude-resources object in the multi-tenancy configuration.

Please refer to the Kodjin FHIR Server configuration page to learn about how to configure the multi-tenancy option.

If you plan to use the Smart on FHIR demo scenario with an embedded patient-picker to set up a patient-context launch/patient, you do not need to enable multi-tenancy. Kodjin does not support the use of an embedded patient-picker with multi-tenancy. This is because using Smart on FHIR requires defining a business context, which typically occurs at a level in front of the FHIR server.

Token and tenant information

With the help of the RBAC module, Kodjin retrieves data from the token and saves tenant data to metadata during POST operations, or filters resources with data from the token during read and search interactions.

Each token claim containing defined tenant information may consist of a list of values.

A token claim is a JSON array with strings, requiring at least one value. Example: organisation_id: ["abc"] or organisation_id: ["abc","123"]

A token claim may contain a wildcard "*" value, signifying "all" and granting access to all tenants. Example: organisation_id: ["abc","123","*""] or organisation_id: ["*"]

The multi-tenancy option can only be enabled during the initial configuration of the Kodjin FHIR Server cluster, before any data is stored in the databases.

Enabling the multi-tenancy option after data has been stored in Kodjin FHIR Server will render that data inaccessible to everyone.

Implementers or cluster administrators cannot enable multi-tenancy after the cluster has been deployed. This configuration cannot be changed post-deployment due to Kodjin's infrastructure being supplied as a codebase.

Export operations and subscriptions

For bulk-export operations: system-level, group-level, patient-level or $everything operations and for subscriptions data is exported or associated with a tenant's ownership based on information extracted from an access token or request headers.

Tenant validation

Different logic has been implemented for read and write operations.

For any GET request, Kodjin only returns records where the resource metadata value matches at least one claim in the provided token or header. It also allows clients to issue tokens or make internal API calls with read access to multiple tenants simultaneously (e.g., for administrative purposes) if needed.

Write (CREATE, PUT, PATCH, DELETE):

Kodjin does not allow write (only CREATE) requests with tokens containing more than one value for tenant claim.

Wildcards are ignored (excluded) from the token-claim.

PUT, PATCH, DELETE is allowed only if the values in the token claims are matched to resource metadata.

POST is allowed if all headers/token-claims are defined and contain only one value or on value+ wildcard for each header/token-claim.

After a resource has been created, the tenant's metadata will never change, even if the resource is updated.

Examples

Below are examples of how tenant validation works in Kodjin FHIR Server for both Write (CREATE, UPDATE, DELETE) and Read (GET, SEARCH, VERSION READ, HISTORY) interactions for each provided combination. In these examples, practice_id is an access token claim configured as a tenant.

Example

practice_id: ["tenant-123"]
WRITE: The client can create a new resource or modify an existing only for tenant-123.
READ: The client can read resources only from tenant-123.

Example

practice_id: ["*"]
WRITE: The client can't create a new or modify any existing resource.
READ: The client can read resources for all tenants.

Planned to be changed in next release to: WRITE: The client can't create a new resource, but can modify existing resources for any tenant.

Example

practice_id: ["tenant-123","*"]
WRITE: The client can create or modify resources only for tenant-123, as the multi-tenancy option ignores the wildcard for write interactions.
READ: The client can read resources for all tenants.

Example

practice_id: ["tenant-123","tenant-222"]
WRITE: The client cannot create new resources due to multiple tenants, but can modify existing resources for tenant-123 and tenant-222.
READ: The client can read resources for all tenants: tenant-123, tenant-222