DLR Processor — Security Model
Status: populated Owner: Platform Engineering / Security Last updated: 2026-04-18 Companion: DEPLOYMENT_TOPOLOGY · API_CONTRACTS
1. Threat Surface
The DLR Processor has a minimal external threat surface:
- No public HTTP endpoints. Infrastructure probes (
/health,/ready,/metrics) are cluster-internal only. - NATS consumer only. All inbound data arrives via JetStream — no external HTTP ingress.
2. Authentication & Authorisation
NATS
- TLS mutual authentication (mTLS) using leaf node credentials.
- NATS user:
dlr-processor— scoped tosubscribe sms.dlr.inbound,publish billing.events,publish webhook.dispatch,publish sms.dlr.unmatched. - No
>wildcard; least-privilege subject permissions.
PostgreSQL
- Dedicated service account
dlr_svc. - Grants:
SELECT, INSERTondlr.*;UPDATE(status, dlr_status, dlr_received_at, processed_at)onorch.sms_messagesonly. - Row-Level Security not applied (service processes cross-account data; account isolation enforced at query predicate level).
- TLS enforced (
sslmode=require).
3. Data Handling
| Data Element | Handling |
|---|---|
Phone numbers (destAddr, sourceAddr) | Stored in dlr.delivery_receipts only when present in DLR; not logged |
operatorMessageId | Not PII; safe to log |
rawPayload in orphaned_receipts | May contain PII from carrier; encrypted at rest (PG tablespace encryption) |
| Account IDs | Internal UUIDs; logged for correlation |
PII policy: Phone numbers are never emitted in log lines. They appear only in DB columns protected by tablespace-level encryption and restricted SELECT grants.
4. Secrets Management
| Secret | Storage | Rotation |
|---|---|---|
DATABASE_URL (includes password) | Vault KV v2 → K8s Secret | 90 days |
| NATS TLS cert + key | Vault PKI | 30 days (auto-renewed) |
| OTEL exporter token | Vault KV v2 → K8s Secret | 90 days |
No secrets in environment variables set at build time; all injected at runtime by Vault Agent.
5. Network Security
- Pod Security Policy (PSP) / Pod Security Admission:
restrictedprofile. - NetworkPolicy: ingress from within
sms-gatewaynamespace only (NATS); egress tosms-gatewaynamespace +postgresnamespace only. - No egress to internet.
6. Input Validation
All inbound NATS messages are validated with Zod schemas before processing. Invalid payloads are discarded immediately — they do not reach DB operations. This prevents injection via crafted stat values or oversized strings.
7. Dependency Security
npm auditrun in CI pipeline; CRITICAL/HIGH findings block merge.- Base image:
node:20-alpine(minimal attack surface). - Trivy image scan in CI; critical CVEs block deployment.