Skip to main content

Webhook Dispatcher — Deployment Topology

Status: populated Owner: Platform Engineering Last updated: 2026-04-18 Companion: LOCAL_DEV_SETUP · OBSERVABILITY

1. Kubernetes Workload

apiVersion: apps/v1
kind: Deployment
metadata:
name: webhook-dispatcher
namespace: sms-gateway
spec:
replicas: 3
selector:
matchLabels:
app: webhook-dispatcher
template:
spec:
containers:
- name: webhook-dispatcher
image: ghasi/webhook-dispatcher:latest
ports:
- containerPort: 3000
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"
livenessProbe:
httpGet: { path: /health, port: 3000 }
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet: { path: /ready, port: 3000 }
initialDelaySeconds: 5
periodSeconds: 10
envFrom:
- secretRef: { name: webhook-dispatcher-secrets }
- configMapRef: { name: webhook-dispatcher-config }

2. Kong Gateway Routes

# Kong route for REST API
services:
- name: webhook-dispatcher
url: http://webhook-dispatcher.sms-gateway.svc.cluster.local:3000
routes:
- name: webhooks-api
paths: ["/v1/webhooks"]
methods: ["GET", "POST", "PUT", "DELETE"]
plugins:
- name: jwt # Validates customer JWT; injects X-Account-Id
- name: rate-limiting
config:
minute: 60 # 60 REST requests/min per account
- name: request-size-limiting
config:
allowed_payload_size: 1 # 1 KB max request body

3. Horizontal Pod Autoscaler

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webhook-dispatcher-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webhook-dispatcher
minReplicas: 3
maxReplicas: 15
metrics:
- type: External
external:
metric:
name: nats_consumer_pending_messages
selector:
matchLabels:
consumer: webhook-dispatcher
target:
type: AverageValue
averageValue: "200"
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70

4. Network Topology

Internet (customer endpoints) ◄── webhook-dispatcher pods ◄── NATS webhook.dispatch
Kong (REST API, internal) ──► webhook-dispatcher pods ──► PostgreSQL hook schema
──► NATS webhook.dispatch.deadletter

Egress to customer URLs: pods have unrestricted HTTPS egress (port 443) via NAT gateway. All other egress restricted by NetworkPolicy.

5. Environment Variables

VariableDescriptionExample
NATS_URLNATS server URL(s)nats://nats:4222
DATABASE_URLPostgreSQL connection stringpostgresql://hook_svc:***@pg:5432/ghasi
DB_POOL_MINMin pool size5
DB_POOL_MAXMax pool size20
KMS_KEY_IDKMS key for webhook secret encryptionarn:aws:kms:eu-west-1:...
HTTP_DELIVERY_TIMEOUT_MSHTTP delivery timeout5000
RETRY_WORKER_INTERVAL_MSRetry poller interval10000
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collectorhttp://otel-collector:4318
LOG_LEVELPino log levelinfo
PORTHTTP port3000

6. Secrets Management

SecretStorageRotation
DATABASE_URLVault KV v2 → K8s Secret90 days
KMS_KEY_ID + access credentialsVault KV v2 / IAM roleManaged by cloud provider
NATS TLS cert + keyVault PKI30 days