Laboratory Service — Security Model
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 02 DDD
1. Authentication
| Layer | Mechanism |
|---|---|
| External (Kong) | JWT validated against Keycloak JWKS |
| Service-to-service | JWT with service account; zero-trust internal validation |
| FHIR gateway | Inherits Kong JWT; adds FHIR SMART scopes |
2. RBAC Matrix
| Role | Scopes | Capabilities |
|---|---|---|
lab:read | svc:laboratory:read | View worklist, accession detail, results, catalog |
lab:technologist | svc:laboratory:write, svc:laboratory:verify | Enter results, verify results, record specimens |
lab:pathologist | All technologist + svc:laboratory:release | Sign off and release results |
lab:admin | All above + svc:laboratory:admin | Manage catalog, critical value policies, PACS endpoints |
lab:clinician | svc:laboratory:read, svc:laboratory:ack | View and acknowledge results |
platform:admin | All scopes | Platform-wide administration |
3. ABAC Rules
| Rule | Enforcement |
|---|---|
| Tenant isolation | Every query filtered by tenant_id from JWT; RLS enforced at DB layer |
| Patient access | Patient-linked result reads check ABAC policy via access-policy-service |
| Module entitlement | ModuleEntitlementGuard validates diag.laboratory license per tenant |
| Correction audit | Corrections require lab:pathologist role minimum; all corrections logged with actor |
4. Encryption Classes
| Data category | Encryption | Notes |
|---|---|---|
| PII / PHI (results, specimens) | AES-256 at rest (PostgreSQL tablespace encryption) | Column-level encryption for value_* on sensitive tests |
| Event payloads | TLS in transit (NATS TLS) | No PHI in event metadata fields |
| Audit logs | Immutable append-only; AES-256 at rest | Stored in audit-service |
| Analyzer raw messages | Encrypted at rest; retention per data classification policy |
5. Audit Events
| Event | When | Captured fields |
|---|---|---|
lab.accession.created | Accession opened | actorId, patientId, accessionId, tenantId, ip |
lab.result.verified | Verification action | actorId, resultId, testCode, tenantId |
lab.result.released | Release action | actorId, resultId, patientId, tenantId |
lab.result.corrected | Correction submitted | actorId, resultId, priorResultId, reason, tenantId |
lab.result.viewed | Clinician views result | actorId, resultId, patientId, tenantId |
lab.result.acknowledged | Clinician ack | actorId, ackType, resultId, tenantId |
lab.critical.triggered | Critical value detected | resultId, patientId, testCode, tenantId |
6. GDPR / Data Privacy Participation
| Requirement | Implementation |
|---|---|
| Data minimization | Result payloads include only clinically necessary fields |
| Right to access | Patient data exportable via FHIR $everything through interop-service |
| Right to erasure | Lab results flagged phi_erasure_pending; erasure workflow triggers soft-delete per retention policy |
| Data residency | tenantId + nodeId used to enforce Afghanistan MoPH data residency constraints |
| Sensitive categories | Certain test codes (HIV, substance abuse) subject to enhanced consent checks |
7. Data Residency
Results data for Afghanistan tenants remains within the AFG node cluster. Cross-border replication is disabled unless explicitly configured by the tenant with MoPH approval.