Tenant Service

Overview

The Tenant service is the entry point for configuring a tenant into Link Cloud. The service is responsible for maintaining and generating events for the scheduled measure reporting periods that the tenant is configured for. These events contain the initial information needed for Link Cloud to query resources and perform measure evaluations based on a specific reporting period.

The Tenant service uses Quartz with ADO Job Stores to manage jobs across multiple instances of the service, primarily for producing ReportScheduled Kafka events.

flowchart LR
nTenantService_F25B55["Service: Tenant Service"]
  nTenantService_F25B55 -->|produces| nAuditableEventOccurred_2E7ED8D7["Event: AuditableEventOccurred"]
  nTenantService_F25B55 -->|produces| nReportScheduled_BC6D32E["Event: ReportScheduled"]
  nTenantService_F25B55 -->|sends| nGenerateReportRequested_7BC99734["Command: GenerateReportRequested"]
  nTenantService_F25B55 -->|provides| nGetFacilitiesList_5CEDF833["Query: GetFacilitiesList"]
  nTenantService_F25B55 -->|provides| nGetFacilityConfig_32C58A79["Query: GetFacilityConfig"]
  nTenantService_F25B55 -->|provides| nGetServiceInfo_13F02E06["Query: GetServiceInfo"]
  nTenantService_F25B55 -->|requests| nGetFacilitiesList_5CEDF833["Query: GetFacilitiesList"]
  nTenantService_F25B55 -->|requests| nGetFacilityConfig_32C58A79["Query: GetFacilityConfig"]
  nTenantService_F25B55 -->|requests| nGetServiceInfo_13F02E06["Query: GetServiceInfo"]
  subgraph nCompliance_DBAE25D_domain["Domain: Compliance"]
    nAuditableEventOccurred_2E7ED8D7
  end
  subgraph nReport_4D4FBBDA_domain["Domain: Report"]
    nGenerateReportRequested_7BC99734
    nReportScheduled_BC6D32E
  end
  subgraph nTenant_379CD514_domain["Domain: Tenant"]
    nGetFacilitiesList_5CEDF833
    nGetFacilityConfig_32C58A79
    nGetServiceInfo_13F02E06
    nTenantService_F25B55
  end

Common Configurations

Custom Configuration

Name Value Secret?
MeasureConfig__CheckIfMeasureExists true or false No

Soft Delete

The Tenant service supports soft deletion of facilities. Rather than permanently removing a facility record, the soft delete endpoint marks the facility with an isDeleted flag set to true. This preserves the facility's configuration and historical data while effectively removing it from active use.

DELETE /api/Facility/softDelete/{facilityId}

Soft deletes a facility by setting its isDeleted flag to true.

Parameters:

  • facilityId (path, required): The unique identifier of the facility to soft delete.

Response:

  • 200 OK: Facility soft deleted successfully. Returns the updated facility configuration.
  • 400 Bad Request: If the request is invalid.
  • 404 Not Found: If no facility exists for the specified facilityId.
  • 500 Internal Server Error: If an error occurs during processing.

Features and Functionality

Key Management

Keys are managed independently by the tenant service, and then associated with tenants. These keys are used for signing authentication JWTs that are passed to /token endpoints at the EHRs. EHRs check that the JWTs are signed using a key found in the JWKS endpoint exposed by Link.

  • Key Registry: A global repository where all JWT signing keys are stored and managed. Each key includes metadata such as kid, algorithm, creation timestamp, status (active, disabled, expired), and an optional primary flag.
  • Lifecycle Operations:
    • Create: Keys can be generated through the admin API/UI with algorithm selection and optional designation as primary.
    • Disable/Delete: Keys no longer in use can be deactivated or removed without disrupting tenant authentication, unless actively in use. This can occur when needing to rotate a key.
    • Rotating Keys:
      1. Create a new key
      2. Associate the new key with tenants
      3. Delete the old key.
  • Tenant Association (handled separately):
    • Tenants reference keys by kid through the Tenant Service configuration interface.
    • A tenant may use a shared or unique key from the registry.
    • Changing a tenant’s associated key does not impact the underlying key object—it only changes the reference.
  • JWKS documents are managed automatically
    • When keys change the JWKS document is re-generated
    • The JWKS document is stored on the file system
    • The JWKS document on the file system is exposed via proxy to external parties for verification (such as EHRs)

The following sequence diagram illustrates how the keys are used during the authentication requests to EHRs:

sequenceDiagram
    participant L as Link
    participant J as JWKS Endpoint
    participant E as EHR Vendor

    L->>L: Create JWT
    L->>L: Sign JWT (with kid)
    L->>J: Publish key to JWKS
    L->>E: POST /token (with JWT)
    E->>J: GET /.well-known/jwks.json
    J-->>E: Return JWKS document
    E->>E: Verify signature using kid
    E-->>L: Return access token

Database Schema

NameTypeRequired?Length
MigrationIdstringYes150
ProductVersionstringYes32
NameTypeRequired?Length
IdstringYes
FacilityIdstringYes
FacilityNamestringNo
CreateDatestring (date-time)Yes
ModifyDatestring (date-time)No
ScheduledReportsstringYes
TimeZonestringYes
IsDeletedbooleanYes
VendorstringNo50

OpenAPI Operations

Get facilities

Route Parameters

None

Query Parameters
NameTypeRequired?Description
facilityIdNo
facilityNameNo
timeZoneNo
vendorNo
sortByNo
sortOrderNo
pageSizeNo
pageNumberNo
includeDeletedNo

Creates a facility configuration.

Route Parameters

None

Query Parameters

None

Get a list of all facilities

Route Parameters

None

Query Parameters
NameTypeRequired?Description
searchNo
includeDeletedNo

Gets a facility configuration by facilityId.

Route Parameters
NameTypeRequired?Description
facilityIdYes
Query Parameters

None

Updates a facility configuration.

Route Parameters
NameTypeRequired?Description
facilityIdYes
Query Parameters

None

Deletes a facility configuration.

Route Parameters
NameTypeRequired?Description
facilityIdYes
Query Parameters

None

Route Parameters
NameTypeRequired?Description
facilityIdYes
Query Parameters

None

Restores a soft-deleted facility configuration.

Route Parameters
NameTypeRequired?Description
facilityIdYes
Query Parameters

None

Generate

Route Parameters
NameTypeRequired?Description
facilityIdYes
Query Parameters

None

Route Parameters
NameTypeRequired?Description
facilityIdYes
Query Parameters

None

Route Parameters

None

Query Parameters

None

Health check endpoint

Route Parameters

None

Query Parameters

None

Relationships

flowchart LR
nTenantService_F25B55["Service: Tenant Service"]
  nTenantService_F25B55 -->|produces| nAuditableEventOccurred_2E7ED8D7["Event: AuditableEventOccurred"]
  nTenantService_F25B55 -->|produces| nReportScheduled_BC6D32E["Event: ReportScheduled"]
  nTenantService_F25B55 -->|sends| nGenerateReportRequested_7BC99734["Command: GenerateReportRequested"]
  nTenantService_F25B55 -->|provides| nGetFacilitiesList_5CEDF833["Query: GetFacilitiesList"]
  nTenantService_F25B55 -->|provides| nGetFacilityConfig_32C58A79["Query: GetFacilityConfig"]
  nTenantService_F25B55 -->|provides| nGetServiceInfo_13F02E06["Query: GetServiceInfo"]
  nTenantService_F25B55 -->|requests| nGetFacilitiesList_5CEDF833["Query: GetFacilitiesList"]
  nTenantService_F25B55 -->|requests| nGetFacilityConfig_32C58A79["Query: GetFacilityConfig"]
  nTenantService_F25B55 -->|requests| nGetServiceInfo_13F02E06["Query: GetServiceInfo"]
  subgraph nCompliance_DBAE25D_domain["Domain: Compliance"]
    nAuditableEventOccurred_2E7ED8D7
  end
  subgraph nReport_4D4FBBDA_domain["Domain: Report"]
    nGenerateReportRequested_7BC99734
    nReportScheduled_BC6D32E
  end
  subgraph nTenant_379CD514_domain["Domain: Tenant"]
    nGetFacilitiesList_5CEDF833
    nGetFacilityConfig_32C58A79
    nGetServiceInfo_13F02E06
    nTenantService_F25B55
  end