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>