Architecture Overview
The RedactedWorld platform follows a microservice architecture with subdomain-based routing, event-driven communication, and Kubernetes-native job execution.
Subdomain Routing
All external traffic enters the cluster through Traefik, which terminates TLS and routes requests based on the subdomain.
Full Service Architecture
The API Gateway is the single entry point for all client API calls. It delegates to downstream services over gRPC, publishes events to NATS, and manages WebSocket connections for real-time scan output.
Communication Patterns
| Pattern | Technology | Use Case |
|---|---|---|
| Synchronous RPC | gRPC (Protocol Buffers) | API Gateway to downstream services for request/response calls (e.g., create user, verify domain, start scan) |
| Asynchronous Messaging | NATS JetStream | Event-driven communication between services (e.g., scan progress updates, notification triggers, domain verification results) |
| Real-Time Streaming | WebSocket | Live scan output streamed from workers through NATS to the API Gateway and finally to the client browser |
| Batch Job Execution | Kubernetes Jobs | Scan tools (nmap, ZAP, sslyze, subfinder) run as short-lived K8s Jobs spawned by the scan-service |
| Data Replication | Change Data Capture | PostgreSQL changes streamed to ClickHouse for analytics and Elasticsearch for full-text search |
Design Rationale
- gRPC over REST for inter-service calls: Provides strongly-typed contracts via
.protofiles, efficient binary serialization, and native streaming support. The API Gateway still exposes a REST/GraphQL interface to external clients. - NATS JetStream over Kafka: Simpler operational model, lower resource footprint, built-in persistence with JetStream, and first-class support in the NestJS microservices module.
- K8s Jobs over long-running workers: Each scan tool runs in an isolated container with its own resource limits. Jobs are ephemeral -- they start, execute the scan, publish results, and terminate. This prevents resource leaks and provides natural horizontal scaling.