Multitenancy

openFHIR Engine supports multitenancy, allowing multiple organizations or tenants to use the same openFHIR instance while maintaining complete data isolation and tenant-specific configurations.

Tenant Isolation

All FhirConnect state and mapping access is completely separated per tenant. This includes:

  • Operational Templates (OPTs): Each tenant maintains their own set of operational templates

  • FhirConnect Context Mappers: Context configurations are isolated per tenant

  • FhirConnect Model Mappers: Mapping definitions are tenant-specific

  • ConceptMaps: Terminology mappings are maintained separately for each tenant

  • Mapping Insights: All mapping execution history and insights are tenant-scoped

When a tenant accesses any openFHIR functionality, they only see and can modify their own data. There is no cross-tenant data visibility or interference.

Tenant-Specific Configuration

Each tenant can be configured with specific settings that control how openFHIR processes their data. These configurations are stored as JSON properties within each tenant entity.

Currently available tenant configuration options:

contained_to_separate_bundle_entry

Type: boolean Default: true

Controls how referenced resources are handled in FHIR Bundle generation:

  • true (default): Referenced resources (like PractitionerRole referenced by Consent) are created as separate entries in the FHIR Bundle. This results in more Bundle entries but follows standard FHIR referencing patterns.

  • false: Referenced resources are embedded as contained resources within the parent resource. This results in fewer Bundle entries but uses FHIR’s contained resource mechanism.

Example:

When contained_to_separate_bundle_entry is false:

{
  "resourceType": "Bundle",
  "entry": [
    {
      "resource": {
        "resourceType": "Consent",
        "contained": [
          {
            "resourceType": "PractitionerRole",
            "id": "contained-practitioner"
          }
        ],
        "provision": {
          "actor": [
            {
              "reference": {
                "reference": "#contained-practitioner"
              }
            }
          ]
        }
      }
    }
  ]
}

When contained_to_separate_bundle_entry is true:

{
  "resourceType": "Bundle",
  "entry": [
    {
      "resource": {
        "resourceType": "Consent",
        "provision": {
          "actor": [
            {
              "reference": {
                "reference": "PractitionerRole/separate-practitioner"
              }
            }
          ]
        }
      }
    },
    {
      "resource": {
        "resourceType": "PractitionerRole",
        "id": "separate-practitioner"
      }
    }
  ]
}

Tenant Management API

Tenants can be managed through RESTful API endpoints:

POST /tenant

Create a new tenant with specific configuration.

Example request:

POST /tenant HTTP/1.1
Content-Type: application/json
Authorization: Bearer <token>

{
  "id": "organization-123",
  "properties": {
    "contained_to_separate_bundle_entry": false
  }
}
PUT /tenant/(id)

Update an existing tenant’s configuration.

Example request:

PUT /tenant/organization-123 HTTP/1.1
Content-Type: application/json
Authorization: Bearer <token>

{
  "properties": {
    "contained_to_separate_bundle_entry": true
  }
}
GET /tenant/(id)

Retrieve a specific tenant’s configuration.

Example request:

GET /tenant/organization-123 HTTP/1.1
Authorization: Bearer <token>
GET /tenant

Retrieve all tenants (administrative operation).

Example request:

GET /tenant HTTP/1.1
Authorization: Bearer <token>
DELETE /tenant/(id)

Delete a tenant and all associated data.

Example request:

DELETE /tenant/organization-123 HTTP/1.1
Authorization: Bearer <token>

Security and Authorization

Tenant operations require specific scopes:

  • tenant.c: Create tenants

  • tenant.r: Read tenant information

  • tenant.u: Update tenant configuration

  • tenant.d: Delete tenants

All other openFHIR operations automatically scope to the authenticated user’s tenant context, ensuring complete data isolation between organizations.