Real-Time Analytics & Security Platform - CADSA
CADSA is an open-source, self-hosted monitoring platform purpose-built for Caddy web server operators. It parses structured access logs in real time, enriches every request with geographic and device context, scores security threats per IP, and surfaces findings through an interactive web dashboard - with no external cloud dependencies.
The Problem
Caddy has grown as a preferred web server for self-hosters and small infrastructure teams because of its automatic HTTPS and clean configuration model. But its logging story is minimal by design: it writes structured JSON to disk and stops there. Operators who want to understand traffic patterns, detect brute-force attempts, or respond to anomalies are left assembling their own tooling. Existing general-purpose solutions - Grafana + Loki, GoAccess, Datadog - all impose real costs: operational complexity, cloud egress fees, or loss of data sovereignty. None understand Caddy's specific log schema or its Admin API natively.
Architecture
CADSA follows a clean two-tier architecture: a Python backend and a TypeScript frontend, co-deployed as a single systemd service.
Backend
FastAPI drives both a REST API and WebSocket connections, with Uvicorn as the ASGI server. Two databases handle different workloads: DuckDB stores raw request records and materialized aggregations - its columnar format makes time-range queries fast without a separate OLAP pipeline. SQLite handles operational state: user accounts, active sessions, alert configurations, and blocklists. Log discovery uses a three-tier fallback - Caddy's Admin API, Caddyfile parsing, then filesystem scanning - so CADSA works out of the box without manual path configuration.
Frontend
The frontend communicates with the backend over WebSockets for the live request stream and REST calls for historical queries. Vite handles the build, with a dev-mode proxy forwarding /api and /ws to the backend - keeping local development frictionless with hot module replacement.
Deployment Model
CADSA runs as an unprivileged systemd service with strict sandboxing: NoNewPrivileges, ProtectSystem=strict, and a private temp filesystem. It binds exclusively to 127.0.0.1:3131 and relies on Caddy itself as the TLS-terminating reverse proxy - eliminating certificate management from CADSA's scope and reusing the operator's existing Caddy configuration.
Key Features
Real-Time Traffic Dashboard
The live view streams request data as it arrives, displaying requests per second, error rate, and unique IP count with no polling lag. Traffic is broken down by HTTP status class (2xx/3xx/4xx/5xx) with response time percentiles (P50, P75, P95, P99), hourly heatmaps, and per-host and per-IP drill-downs.
Geographic Intelligence
Each request is enriched with MaxMind GeoLite2 city-level data. The dashboard renders an interactive choropleth world map togglable between request count and error rate, with country and city tables. Clicking any region filters the full dashboard inline - no separate query required.
Threat Detection Engine
CADSA scores each IP continuously across eight threat categories: rate-limit triggers, SQL injection and XSS pattern matching, path traversal attempts, port scanning activity, known vulnerability scanner fingerprints, bot detection, authentication failure patterns, and HTTP method abuse. Scores accumulate per IP and feed a blocklist operators can manage from the dashboard. Optional AbuseIPDB integration adds external reputation data with a configurable cache TTL.
Security-First Authentication
Mandatory TOTP 2FA - compatible with Google Authenticator - cannot be bypassed post-setup. JWT tokens use RS256 asymmetric signing with a 4096-bit RSA keypair generated at install time; the private key never leaves the host. Sessions are revocable server-side, and accounts lock after 10 failed attempts with backup codes provided at enrollment.
Technical Decisions
- DuckDB over PostgreSQL - columnar engine outperforms a general-purpose RDBMS for time-series analytics without requiring a separate server process or connection management.
- uv for Python dependency management - uv sync --frozen ensures reproducible installs across machines and across time, eliminating resolver surprises on updates.
- JSON-only log requirement - Caddy's structured JSON format enables reliable field extraction; supporting multiple log formats would introduce parser complexity without benefit.
- Localhost-only binding - restricting to 127.0.0.1 means CADSA is never directly internet-exposed, even if a firewall is misconfigured.
- Mandatory 2FA - enforced unconditionally rather than made optional; a security monitoring tool vulnerable to credential stuffing is a contradiction.
Data Retention & Maintenance
Raw request records are retained for 90 days by default; hourly aggregations are kept for 365 days. Both are configurable. Old data is purged automatically. The GeoLite2 database refreshes weekly to maintain geolocation accuracy. The update script preserves the configuration file and both databases across upgrades. The test suite covers 136 unit tests across the parser, database layer, auth system, and security engine - providing a regression baseline for contributors.
Project Details
Services Provided
Technologies Used
Let's Talk About What Technology Can Do For Your Organisation
Whether you have a defined project or an open challenge, our enterprise technology advisors will help you build the right approach. No obligation, no sales pitch - just expert guidance.