Files

6.9 KiB

Architecture · Overview

This is the high-level technical view. For specific subsystems see the sibling files in this folder.

The four tiers

            ┌──────────────────────────────────────┐
            │   Hub  (EU sovereign bare-metal)     │
            │   - multi-site control plane         │
            │   - cross-site forensic search       │
            │   - operator auth (Keycloak)         │
            │   - long-term embeddings index       │
            └────────────────┬─────────────────────┘
                             │ MQTT bridge over TLS
                             │ + HTTPS for blob storage
                             │
              ╔══════════════╪══════════════╗
              ║              │              ║   per-site
              ║    ┌─────────▼─────────┐    ║   boundary
              ║    │ Router (OpenWrt)  │    ║
              ║    │ - mosquitto       │    ║
              ║    │ - tailscale       │    ║
              ║    │ - GitOps recon.   │    ║
              ║    │ - SPA host        │    ║
              ║    │ - reverse proxy   │    ║
              ║    └────┬─────────┬────┘    ║
              ║         │         │          ║
              ║   VLAN-10        VLAN-20    ║
              ║   cameras       compute     ║
              ║   ┌──┐ ┌──┐    ┌────────┐   ║
              ║   │c1│ │c2│    │  Cell  │   ║
              ║   └──┘ └──┘    │RK3588  │   ║
              ║         ...    │        │   ║
              ║                │frigate │   ║
              ║                │enricher│   ║
              ║                │re-id   │   ║
              ║                │healthd │   ║
              ║                └────────┘   ║
              ║                    ▲        ║
              ║                    │        ║
              ║                    ▼        ║
              ║          (optional Core)    ║
              ║          ┌─────────────┐    ║
              ║          │ Jetson Orin │    ║
              ║          │ federates   │    ║
              ║          │ N Cells     │    ║
              ║          └─────────────┘    ║
              ╚══════════════════════════════╝

Data flow

Capture: cameras (RTSP) and microphones publish to the Cell.

Inference: Frigate runs detection on streams, generates events. Enricher consumes events and produces embeddings, hashes, re-ID vectors.

Bus: everything flows over MQTT topics on the local broker. The contract is documented in mqtt-contract.md.

Storage:

  • Raw video clips → Cell's encrypted disk (NVMe hot + HDD cold). Never bridged.
  • Embeddings + metadata → Cell's local index, optionally bridged to hub.
  • Snapshots → local only.
  • Aggregated health/state → bridged to hub.

Console: SPA hosted by the router. Talks to the router via /api/router/* (ubus) and to the Cell via /api/cell/* (reverse-proxied by the router).

Configuration: GitOps repos cloned by the router. Reconciled every 5 minutes. See ADR-0004.

Egress sovereignty: only what the bridge policy explicitly allows leaves the site. See data-sovereignty.md.

Key technologies

Layer Choice
Router OS OpenWrt 23.05+
Router hardware GL.iNet GL-MT6000 (default), Banana Pi BPi-R4 (alternative)
Cell OS Balena OS on RK3588
Cell hardware Banana Pi BPI-W3, Radxa Rock 5B+
Edge AI engine Frigate v0.14+ with RKNN
Models YOLOv8n (detection), CLIP (embeddings), reid models, Whisper-v3 (audio)
Broker Mosquitto with bridge
Time sync chrony with NTS
VPN Tailscale
GitOps Git + cron-driven reconcile (custom ucode script)
Hub OS Debian on Hetzner bare-metal
Hub services Mosquitto, MinIO, Qdrant, TimescaleDB, Keycloak, Caddy

Provisioning lifecycle

  1. Image build: OpenWrt Image Builder produces a router firmware with luci-app-blocao-console and dependencies.
  2. First boot: router shows the wizard at http://blocao-router.local/. Installer goes through 6 steps.
  3. Cell enrollment: Cell devices on the local network are auto-discovered (mDNS + MQTT announce). Balena handles their provisioning over the air.
  4. GitOps repos: created by the wizard at hub side. Site repo is initialized with applied UCI config.
  5. Hub registration: router exchanges enrollment token for mTLS cert. Bridge starts. Sites Overview at hub now shows the new site.
  6. Camera onboarding: scan VLAN-10, identify, authenticate, test, configure. GitOps commit + Frigate reload.
  7. Operator login: console at the router via Tailscale or local network.

Failure modes considered

Failure Mitigation
WAN down Site continues operating; events queue locally; bridge resumes when WAN returns
Hub down Router operates standalone; queue grows; reconnects automatically
Cell crash Frigate auto-restarts via Balena; events buffered; selftest alerts in <30s
Camera offline Detected by selftest; alert in SYNOPSIS and CAMS; doesn't block other cameras
Bridge cert expires Selftest warns 90 days before; auto-renewal planned (currently manual)
GitOps push conflict Reconcile fails, alerts via _bridge/status, last-known-good remains applied
Cell disk full Retention rotates oldest first; soft alert at 75%, hard at 85%, evidence locker has separate quota
Operator forgets password Router has local recovery via console port; hub has Keycloak admin recovery

Out of scope (for design phase)

  • Mobile operator app — explicitly post-MVP.
  • Real-time video streaming to operator over WAN — bandwidth-prohibitive, only on-demand clips.
  • Automated camera positioning / PTZ control — vendor-specific, deferred.
  • Cross-site real-time correlation (e.g., follow a vehicle across sites in real time) — analytics-grade feature, post-MVP.

See also