Audit Service — Deployment Topology
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template
1. Runtime
| Attribute | Value |
|---|---|
| Runtime | NestJS 11 / Node 22 LTS / TypeScript 5.x |
| Container image | ghasi/audit-service:latest |
| Base image | node:22-alpine |
| Port | 3006 (internal) |
| Health endpoint | GET /health |
| Readiness probe | DB connectivity + NATS subscription alive |
2. Kubernetes deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: audit-service
namespace: ghasi-ehealth
spec:
replicas: 2 # minimum; HPA scales to 6
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: audit-service
image: ghasi/audit-service
resources:
requests: { cpu: 200m, memory: 256Mi }
limits: { cpu: 500m, memory: 512Mi }
3. Scaling
| Metric | Target | Min | Max |
|---|---|---|---|
| CPU | 70 % | 2 | 6 |
| NATS consumer lag | > 1 000 pending msgs | Triggers alert | — |
The audit service is write-heavy (high event ingestion) and read-light (compliance queries are infrequent). Scaling is driven primarily by NATS consumer lag.
4. Regions and data residency
| Deployment | Region | Notes |
|---|---|---|
| Primary | Afghanistan (AF) | MoPH data-residency; Postgres and NATS co-located in-country |
| DR passive | Secondary on-prem or cloud region | Async replica; DNS failover |
| Dev/staging | Shared cloud | Synthetic events only; no real PHI |
5. Database topology
| Component | Technology | Notes |
|---|---|---|
| Primary DB | PostgreSQL 16 | audit schema; INSERT-only role; monthly range partitions on recorded_at |
audit_app DB role | INSERT on audit_entries, SELECT on audit_entries + audit_exports, INSERT + UPDATE on audit_exports | UPDATE and DELETE on audit_entries explicitly revoked |
| Backup | Daily pg_dump + WAL archiving | 7-year minimum retention (MoPH BR-AUD-003) |
| Migrations | Drizzle Kit, CI-applied | Never auto-run on startup |
6. Object storage (export files)
| Component | Technology | Notes |
|---|---|---|
| Export bucket | S3-compatible (MinIO on-prem / AWS S3) | NDJSON and CSV files; signed URLs with 1-hour TTL |
| Retention | 90 days for export files | Underlying audit_entries persist 7 years |
7. NATS JetStream
| Stream | Subjects consumed | Notes |
|---|---|---|
| All platform streams (wildcard) | com.ghasi-ehr.>, patient_chart.>, ai_gateway.>, etc. | Wildcard consumer subscribes to all event streams |
AUDIT_DLQ | audit.dlq | Dead-letter queue; max-deliver exhausted messages |
The audit service does not publish to streams (except audit.export.requested.v1, audit.export.completed.v1, audit.dlq.alert.v1).
8. Network and security
| Control | Value |
|---|---|
| Ingress | Kong edge gateway; query + export APIs only |
| mTLS | Enabled in-cluster |
| NATS TLS | Required for all consumer connections |
| Secrets | Kubernetes Secrets via Vault Agent |
| Network policy | Deny-all; allow list: NATS ingress, Postgres, Kong, object storage |
9. Canary and rollout
| Stage | Traffic % | Duration | Validation |
|---|---|---|---|
| Canary | 5 % | 30 min | NATS consumer lag stable; no chain-hash errors; no DLQ growth |
| Progressive | 50 % → 100 % | 15 min each | Same gates |
| Rollback trigger | Chain-hash integrity test fails or DLQ growing | Automated via Argo Rollouts |