Ghasi e-Prescribing Gateway Service — Security Model
Status: populated
Owner: TBD
Last updated: 2026-04-18
Companion: Service Template · 03 platform-services · 02 DDD
Authentication
- Interactive users: Keycloak-issued JWT (
Authorization: Bearer).
- Service-to-service (EHR, Pharmacy backends): OAuth2 client credentials; JWT
persona claim determines write rights.
- B2B external integrators: client credentials + optional mTLS; scoped to gateway-only endpoints.
tenantId extracted exclusively from JWT tenant_id claim.
Persona-Based Write Authorization (RBAC)
| Persona / Role | Write MR | Write MD | Write Task | Register Subscription | Admin operations |
|---|
ehr-backend | ✅ | ❌ | ✅ (owner side) | ✅ | ❌ |
pharmacy-backend | ❌ | ✅ | ✅ (requester side) | ✅ | ❌ |
b2b-external | Depends on tenant IG scope | Depends on tenant IG scope | ❌ | ✅ | ❌ |
platform-admin | ❌ | ❌ | ❌ | ❌ | ✅ (replay, DLQ) |
clinician (interactive) | ❌ (use orders-service) | ❌ | ❌ | ❌ | ❌ |
Key constraint: A pharmacy-backend service account CANNOT write MedicationRequest. An ehr-backend service account CANNOT write MedicationDispense. This is enforced by the gateway even if the client presents a valid JWT (BR-RX-001, BR-RX-002).
Encryption
| Data | At rest | In transit |
|---|
gepgw_* Postgres tables | AES-256 via cloud KMS (tenant-level key) | TLS 1.3 |
| FHIR resource JSONB columns | Encrypted at field level for patient identifiers (KMS) | TLS 1.3 |
| NATS event payloads | TLS 1.3 (NATS mTLS) | — |
| Subscription signing keys | KMS-managed; never stored plaintext | — |
| Idempotency records | AES-256 at rest | TLS 1.3 |
Subscription Security
- Signed HTTPS payloads:
X-Ghasi-Signature: sha256=<hmac> — client verifies before processing.
- Endpoint URL verified (HTTPS mandatory; health-check on registration).
- Replay protection: payload includes
X-Ghasi-Delivery-Id; consumers deduplicate.
- Subscription keys rotate per tenant policy (configurable; default: 90 days).
Audit Events (HIPAA-equivalent)
All events emitted to audit-service with tenantId, actorId, resourceType, resourceId, action, correlationId, prescriptionBusinessId, timestamp.
| Event | Trigger |
|---|
eprescribing.mr.created | MR persisted |
eprescribing.mr.updated | MR status/fields changed |
eprescribing.mr.cancelled | MR cancelled |
eprescribing.md.created | MD created |
eprescribing.md.updated | MD updated |
eprescribing.search.executed | Search query (patient-scoped) |
eprescribing.auth.forbidden | 403 returned (wrong persona or tenant) |
eprescribing.validation.failed | IG validation failure |
eprescribing.subscription.registered | New Subscription |
eprescribing.subscription.delivery_failed | DLQ enqueue |
eprescribing.replay.triggered | Admin replay |
Rate Limiting
- Per-tenant rate limits enforced at Kong + application layer.
- Configurable per tenant: default
POST /fhir/MedicationRequest = 100 req/min.
- Emergency priority queue available only when tenant policy explicitly enables it (BR-RX-004).
429 RATE_LIMIT_EXCEEDED with Retry-After header.
Consent and Sensitive Data
- Patient consent flags from registration-service are honored on patient-scoped searches.
- Break-glass access for emergency prescribing is configurable per tenant policy with full audit.
- Cross-border data transfers: tenant-declared residency enforced; no cross-region query.
GDPR / Data Privacy
| Aspect | Handling |
|---|
| PHI in transit | TLS 1.3 + HMAC-signed Subscription payloads |
| PHI at rest | KMS encryption; gepgw_* tables |
| Data minimization | Searches scoped to authenticated tenant + patient |
| Retention | Clinical records: 10 years; ops events: 90 days; legal hold configurable |
| Erasure | Clinical hold applies; erasure queued post-retention; entered_in_error FHIR pattern |
| DSAR | Patient medication history exportable via authorized export flow |
Security Testing Requirements
- Adversarial cross-tenant queries in CI (
tenant-isolation.integration.spec.ts) — mandatory gate.
- Persona enforcement: test EHR-backend writing MD returns 403; pharmacy-backend writing MR returns 403.
- Subscription signature verification test in CI.
- Quarterly penetration test covering authentication bypass and FHIR injection.