Skip to content

Healthcare architecture

How Tavrik AI-ESB integrates with a hospital’s existing AI-traffic, audit-aggregation, and compliance infrastructure. Two deployment topologies per ADR-0043 Decision 6; both first-class.

Topology A — on-network

Tavrik gateway runs on the hospital network. Direct MLLPS / HTTPS to the hospital integration engine and FHIR audit aggregator.

┌───────────────────────────────────┐
│ Hospital network │
│ │
Clinician │ ┌────────────┐ │
browser ──→ │ │ Tavrik │── /v1/messages ─┼──→ External LLM provider
(extension) │ │ gateway │ (TLS 1.3, │ (Anthropic, OpenAI,
│ └────────────┘ per-tenant) │ etc. — direct from
│ │ │ hospital network)
│ │ audit event │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ HL7 v2.x ARV via MLLPS │ │
│ │ (M5.A.8 hl7mirth) │ │
│ └─────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ Mirth Connect / │ │
│ │ Cloverleaf / │ │
│ │ Rhapsody / Iguana │ │
│ │ (integration engine) │ │
│ └─────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ Hospital SIEM / │ │
│ │ audit-aggregator │ │
│ │ (compliance team's │ │
│ │ source of truth) │ │
│ └─────────────────────────┘ │
│ │
└───────────────────────────────────┘

Alternative (or additional) audit-forwarding path via FHIR:

Tavrik gateway
│ audit event
┌───────────────────────────────┐
│ FHIR R4 AuditEvent via HTTPS │
│ (M5.A.9 fhiraudit) │
└───────────────────────────────┘
┌───────────────────────────────┐
│ FHIR audit aggregator │
│ (FHIR-R4-capable endpoint) │
└───────────────────────────────┘

Pre-requisites for Topology A:

  • Tavrik runs as systemd units on a single Linux VM per ../operations/on-prem-vm-runbook.md (the pilot shape, executed end to end). A Kubernetes Helm chart under deploy/helm/tavrik exists and is install-smoked in CI but is not the pilot shape. There is no single-binary appliance build (ADR-0008 defers it).
  • Network access from the gateway to the integration engine’s MLLPS listener (typically TCP 6661) AND to the FHIR audit endpoint (HTTPS 443).
  • Hospital integration engine configured with a MLLPS listener bound to a hostname Tavrik resolves locally.
  • Operator-supplied CA bundle for the hospital integration engine’s TLS server cert.
  • Optional: operator-supplied client cert + key for mTLS authentication of Tavrik’s outbound MLLPS connections.

Topology B — SaaS via companion (M6)

Tavrik gateway runs in Tavrik-managed cloud infrastructure (per-customer dedicated tenancy or pooled multi-tenant). The Tavrik gateway has NO direct network access to the hospital integration engine. An operator-deployed hospital-side companion connector re-emits Tavrik audit events into the local integration engine.

┌──────────────────────────────────────┐ ┌──────────────────────────┐
│ Tavrik SaaS region │ │ Hospital network │
│ │ │ │
│ ┌────────────┐ │ │ ┌────────────────────┐ │
│ │ Tavrik │── audit event ─ mTLS ─ HTTPS ─┼──→│ Companion connector│ │
│ │ gateway │ │ │ │ (Tavrik-shipped │ │
│ └────────────┘ │ │ │ binary; M6 │ │
│ │ │ │ packaging) │ │
└──────────────────────────────────────┘ │ └────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ HL7 ARV MLLPS / │ │
│ │ FHIR R4 AuditEvent │ │
│ │ HTTPS │ │
│ │ (same M5.A.8/ │ │
│ │ M5.A.9 wire shape │ │
│ │ as Topology A) │ │
│ └────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ Hospital │ │
│ │ integration engine │ │
│ └────────────────────┘ │
│ │
└──────────────────────────┘

Pre-requisites for Topology B (M6 milestone):

  • Tavrik companion connector running on hospital network (Docker image / appliance image per M6 packaging).
  • mTLS-authenticated HTTPS channel from Tavrik SaaS gateway → companion connector. Operator-issued CA verifying the gateway’s identity certificate.
  • Companion connector has the same network access as Topology A’s gateway (MLLPS + FHIR HTTPS).
  • All per-tenant config (CA bundles, client certs, FHIR bearer tokens) provisioned via the companion connector’s local admin API.

Status: not yet available. No companion-connector binary exists; the packaging is filed for the M6 on-prem milestone. Customers with SaaS deployment needs that include audit-forwarding-to-hospital wait for M6, OR export the audit log file from the Tavrik host and ingest it into their integration engine via their own tooling in the interim (the ClickHouse / S3 ledger backends have not shipped either; the file backend is the only one).

Audit data flow

Tavrik’s canonical audit event is categorical-only per ADR-0013. The translation to either HL7 v2.x ARV or FHIR R4 AuditEvent preserves the categorical-only invariant: NO PHI in either wire format.

HL7 v2.x ARV wire shape (M5.A.8)

Two segments per message:

MSH|^~\&|TAVRIK|TAVRIK_GW|MIRTH|HOSPITAL_AUDIT|20260511132245||ARV^O60^ARV_O60|01HXYZ|P|2.5|||||||req^trc
ARV|1||TAVRIK_AUTH_TENANT_RESOLVED|SUCCESS|tenant-radiology-ai|key_id^key_xyz~key_prefix^tvk_|op_root_001
  • MSH-10 carries the canonical UUIDv7 event_id for SIEM dedupe
  • ARV-3 carries the Tavrik canonical event-type as TAVRIK_<EVENT_TYPE_UPPERCASE> action code
  • ARV-4 carries SUCCESS / FAILURE outcome marker
  • ARV-5 carries Tavrik tenant context
  • ARV-6 carries categorical attribute pairs (key^value~key^value) in sorted-key order
  • ARV-7 carries actor identifier

MLLP framing per HL7 spec: <VT> payload <FS><CR> (0x0B, 0x1C, 0x0D).

FHIR R4 AuditEvent wire shape (M5.A.9)

{
"resourceType": "AuditEvent",
"id": "01HXYZ_fhir_test",
"type": {
"system": "https://tavrik.ai/fhir/audit-event-type",
"code": "auth.tenant_resolved"
},
"subtype": [
{ "system": "https://tavrik.ai/fhir/audit-event-type/domain", "code": "auth" }
],
"action": "R",
"recorded": "2026-05-11T13:22:45Z",
"outcome": "0",
"agent": [
{
"type": { "coding": [{ "system": ".../agent-type", "code": "tenant" }] },
"who": { "identifier": { "value": "tenant-radiology-ai" } },
"requestor": false
},
{
"type": { "coding": [{ "system": ".../agent-type", "code": "actor" }] },
"who": { "identifier": { "value": "op_root_001" } },
"requestor": true
}
],
"source": {
"site": "TAVRIK_GW",
"observer": { "identifier": { "value": "tavrik-prod-au-syd" } }
},
"entity": [
{ "name": "key_id", "what": { "identifier": { "value": "key_xyz" } } },
{ "name": "key_prefix", "what": { "identifier": { "value": "tvk_" } } }
]
}

The Tavrik-issued CodeSystem URN (https://tavrik.ai/fhir/audit-event-type) is documented in compliance/healthcare/fhir-audit-codes.md.

POSTed as Content-Type: application/fhir+json over TLS 1.3 HTTPS.

TLS posture

Both connectors enforce TLS 1.3 minimum at the transport layer per ADR-0043 Decision 3. Plaintext MLLP is structurally rejected at the per-tenant config-validation seam — there is no operator escape hatch.

  • Server cert validation: against operator-supplied CA bundle ONLY. NO system-root fallback (hospital integration engines typically use internal/private CAs).
  • No certificate pinning: per ADR-0040 Decision 3 precedent. Enterprise MDM environments commonly run TLS-inspecting proxies; pinning breaks them.
  • Optional mTLS: operator-supplied client cert + key for MLLPS; selectable bearer-or-mTLS for FHIR HTTPS.
  • Envelope-encrypted credentials: per ADR-0035. Client certs, keys, bearer tokens encrypted at rest with per-tenant DEK wrapped by tenant KEK. Plaintext only in process memory at construction; never logged.

Failure handling

Both connectors emit categorical audit events on failure paths:

  • connector.event_forwarded (success) — Writer accepted a batch durably
  • connector.event_failed (failure) — generic Writer error
  • connector.client_cert_expiring (failure) — within 14 days of client cert expiry, by either writer when an mTLS client cert is configured (days_until_expiry, not_after; one emission per 24 h per writer instance)
  • connector.mllps_handshake_failed (failure) — TLS handshake fail (failure_class: cert_expired / unknown_authority / connection_refused / timeout / unknown)
  • connector.fhir_endpoint_unreachable (failure) — HTTPS failure (failure_class: dns_failure / connection_refused / cert_invalid / cert_expired / unknown_authority / auth_rejected / server_error / client_error / timeout / tls_handshake / unknown)

connector.event_dlq is declared in the closed event enum but is not emitted: when an event exhausts its retries the dispatcher writes a dispatch: event moved to DLQ line to the admin journal and a row to connector_dlq, and nothing lands in the audit stream.

Tavrik’s dispatcher per ADR-0046 provides at-least-once delivery with stable event_id dedupe: the audit file is the outbox, failed events park in connector_retry with exponential backoff (1 s doubling, capped at 5 min), and move to connector_dlq after 10 attempts — roughly ten minutes of sustained failure. There is no admin surface yet for retry depth, DLQ depth or DLQ replay (B5 in pilot-blockers.md); operators read the two tables by SQL per the operations runbook.

Per-tenant configuration

tenant_connector_configs rows per ADR-0036 §5 (envelope-encrypted per ADR-0035). Two connector kinds for the healthcare vertical, as accepted by the admin API path /v1/tenants/{id}/connectors/{kind} and the console (internal/admin/handlers/connectors.go, migration 0015 CHECK constraint):

  • hl7_mirth_mllps — HL7 v2.x ARV over MLLPS (M5.A.8)
  • fhir_audit_https — FHIR R4 AuditEvent over HTTPS (M5.A.9)

(ADR-0043 and the connector packages’ ConfigKind constants use the older names hl7_mllps / fhir_auditevent; those names are not accepted on the wire.)

Configs are per-(tenant, connector). One Tavrik gateway serves multiple hospitals as separate tenants; each tenant gets its own per-connector config naturally isolated by ADR-0036 §5 RLS + ADR-0004 tenant-scoped predicates.

Operator console (M5.B)

The operator console (M5.B, shipped) surfaces today:

  • Per-tenant vertical-pack enablement and pack_version pin (/tenants/[id]/vertical-packs)
  • Per-tenant connector configuration for the two healthcare kinds (/tenants/[id]/connectors; config-save wires through the ConfigValidator from ADR-0043 §3). SIEM and Purview kinds are configured through the admin API.
  • Audit-event review with event-type filters and a per-event hash check (/audit)

Not yet available in the console: per-recognizer-category overrides (B7), retry / DLQ depth and DLQ replay (B5), provider-directory enrichment in the audit viewer (post-pilot), and a per-tenant “AI tools in use” view (B4). Everything the console does not surface is done via the admin API directly (docs/operations/admin-api.md).

References

  • ADR-0043 — EHR-adjacent connector architecture
  • ADR-0036 — Connector framework (outbox/DLQ; per-tenant configs)
  • ADR-0035 — BYOK key resolution (envelope-encryption)
  • ADR-0013 — Audit event types closed enum (categorical-only)
  • ADR-0040 — Browser extension architecture
  • ADR-0008 — Hardware appliance strategy (deferred; no appliance build exists)
  • ADR-0046 — Connector dispatcher (audit file as outbox; retry + DLQ tables)
  • ../operations/on-prem-vm-runbook.md — the pilot deployment shape