routing-engine — Security Model
Status: populated | Last updated: 2026-04-18
1. Authentication & Authorization
gRPC (mTLS)
All gRPC connections to routing-engine use mutual TLS (mTLS):
- Server certificate issued by the cluster-internal CA (
cluster.localCA — managed bycert-manager). - Client certificate required; only
sms-orchestratorholds a valid client cert signed by the same CA. - Certificate rotation is handled automatically by
cert-managerwith a 90-day TTL and 30-day renewal window. - No API key or JWT is required on the gRPC channel — the mTLS client cert serves as the authentication mechanism.
NATS JetStream
- NATS credentials are mounted as Kubernetes
Secretobjects (nats-credentialssecret in thesms-gatewaynamespace). - The service uses NATS NKey authentication; credentials are never hardcoded.
- Consumer is restricted to
SUBSCRIBEonoperator.healthonly (NATS permission policy).
HTTP Management Endpoints (/health, /ready, /metrics)
- Exposed only on the pod's internal network interface (
127.0.0.1or cluster-internal ClusterIP). - Not routed through Kong Gateway.
- No authentication required (standard Kubernetes probe pattern).
/metricsis scraped by Prometheus within the cluster only.
2. Secrets Management
| Secret | Storage | Injection method |
|---|---|---|
| PostgreSQL DSN (read-only user) | Kubernetes Secret (sealed with Sealed Secrets) | Environment variable DATABASE_URL |
| Redis password | Kubernetes Secret | Environment variable REDIS_URL |
| NATS NKey credentials | Kubernetes Secret | Mounted as file /run/secrets/nats/nkey.creds |
| TLS server cert + key | Kubernetes Secret (cert-manager Certificate CR) | Mounted as volume /run/secrets/tls/ |
| mTLS CA bundle | Kubernetes ConfigMap | Mounted as volume /run/secrets/tls/ca.crt |
The service validates at startup that all required secrets are present and readable. It exits with code 1 and a structured log message if any secret is missing.
3. Network Security
routing-engineis deployed with a KubernetesNetworkPolicythat:- Allows inbound TCP on port
50051only from pods with labelapp=sms-orchestrator. - Allows inbound TCP on port
3001from the Prometheus scraper pod only. - Denies all other inbound traffic.
- Allows outbound TCP to PostgreSQL (port
5432) and Redis (port6379) within the namespace. - Allows outbound TCP to the NATS cluster.
- Allows inbound TCP on port
4. Threat Model Summary
| Threat | Mitigation |
|---|---|
Unauthorised caller invokes SelectOperator | mTLS client cert required; only sms-orchestrator cert is trusted |
| Operator credentials leaked via gRPC response | OperatorConfig returns systemId but never password; password is consumed only by smpp-connector via operator-management-service internal API |
| Cache poisoning via Redis | Redis is accessible only within the Kubernetes namespace; NetworkPolicy enforced |
| NATS event injection causing health state manipulation | NATS NKey auth + publish-only permission for operator-management-service; routing-engine can only subscribe |
| PostgreSQL data exposure | Read-only DB user; no credentials stored in code |