Architectuur
Componenten
agent (Rust, op elke host) │ HTTPS batches: metrics · heartbeats · inventory · alerts · honeypot events ▼hub-api (Go + Gin) ──► TimescaleDB (Postgres met Timescale extensie) ├── Redis (rate limiting · cache) ├── NATS (interne message bus) └── Ollama (lokale LLM voor "Verklaar dit")hub-api ──► dashboard (Next.js) └── websocket emergency push ──► agentWaarom geen Prometheus
Alle data hoort in één database — joins tussen alerts en metrics zijn dan SQL, niet PromQL plus applicatie-logica. TimescaleDB hypertables geven de tijdreeks-prestaties zonder een tweede operationeel systeem in te brengen.
Trade-off: we verliezen Prometheus’ pull-based service discovery en de exporter-ecosystem. Voor het monitoren van het platform zelf exposen we /metrics op api.monsys.ai in Prometheus exposition formaat.
Waarom Caddy
Auto-TLS via Let’s Encrypt zonder configuratie. De subdomeinen zijn stabiel, dus er is geen reden om de TLS-lifecycle manueel te draaien zoals met nginx.
Waarom Rust voor de agent
De agent draait op elke gemonitorde host: footprint en betrouwbaarheid zijn dominant. Rust geeft een statisch gelinkte binary van ~12 MB zonder runtime-dependencies, voorspelbaar geheugen onder load (geen GC-pauzes die op CPU-pieken lijken), en het type-systeem vangt fouten die een long-running daemon niet mag hebben.
Waarom Ed25519 voor Emergency Action Tokens
We willen de agent geen permanente root-rechten geven. Tokens geven dezelfde operationele macht voor enkele minuten dat een incident duurt en vervallen daarna. Bij compromittering van de hub blokkeren nonces replays; bij compromittering van de agent ligt er geen langlopend sleutelmateriaal op tafel.