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 underdeploy/helm/tavrikexists 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^trcARV|1||TAVRIK_AUTH_TENANT_RESOLVED|SUCCESS|tenant-radiology-ai|key_id^key_xyz~key_prefix^tvk_|op_root_001MSH-10carries the canonical UUIDv7event_idfor SIEM dedupeARV-3carries the Tavrik canonical event-type asTAVRIK_<EVENT_TYPE_UPPERCASE>action codeARV-4carriesSUCCESS/FAILUREoutcome markerARV-5carries Tavrik tenant contextARV-6carries categorical attribute pairs (key^value~key^value) in sorted-key orderARV-7carries 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 durablyconnector.event_failed(failure) — generic Writer errorconnector.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_versionpin (/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