diff --git a/docs/01-architecture/data-sovereignty.md b/docs/01-architecture/data-sovereignty.md new file mode 100644 index 0000000..ad8bc22 --- /dev/null +++ b/docs/01-architecture/data-sovereignty.md @@ -0,0 +1,81 @@ +# Data sovereignty + +The sovereignty model is enforced at three layers, each visible in the operator console. + +## Layer 1 — Storage tier separation + +| Tier | Data | Where it lives | Encryption | +|---|---|---|---| +| 1 | Raw video clips | Cell's local disk (NVMe + HDD) | LUKS at rest | +| 1 | Audio recordings | Cell's local disk | LUKS at rest | +| 2 | Embeddings (CLIP, voiceprints) | Cell's vector index, optionally bridged to hub | TLS in transit, AES at rest on hub | +| 2 | Detection metadata (events, hashes) | Cell's TimescaleDB, bridged to hub | same | +| 3 | Evidence packs (when exported) | Customer-provided destination | BYOK encryption | + +**Tier 1 never leaves the site by default.** No accidental upload, no "telemetry" exemption, no "diagnostics improvement" loophole. + +## Layer 2 — MQTT bridge policy + +Defined in [`mqtt-contract.md`](mqtt-contract.md). Summary: + +| Direction | Allowed | Not allowed | +|---|---|---| +| Up (site→hub) | events, state, registry, health, bridge status, evidence manifests | snapshots, raw telemetry, $SYS | +| Down (hub→site) | commands, config | nothing else | + +The policy is in `/etc/mosquitto/conf.d/bridge.conf`, version-controlled in the site-config repo. The MQTT panel renders it. + +## Layer 3 — Network egress at the firewall + +The cameras VLAN (VLAN-10 by default) has **zero internet egress**. Firewall rules: + +- DROP from VLAN-10 to WAN. +- DROP from VLAN-10 to any non-RTSP port on VLAN-20. +- DROP from VLAN-10 to anywhere except: local DNS sinkhole, RTSP from VLAN-20, NTP from local router. + +DNS is sinkholed: cameras think they have DNS but the router resolves all queries locally. Phone-home attempts are visible in the security checklist during onboarding. + +The Cell (VLAN-20) **does** have internet egress, but only to bridge endpoint and Balena. The router enforces this with named iptables/nftables sets. + +## Layer 4 — GitOps audit trail + +Every configuration change is a Git commit, signed by an operator's GPG or SSH key. The repo is auditable by anyone with read access. Drift between live config and Git state is detected within 5 minutes and surfaced in the GitOps panel. + +This is **the audit trail** for compliance: "show me what was running on this site on date X" → check Git history for commits before date X. + +## What customers see + +In the operator console: + +- **MQTT panel** → bridge policy section: explicit `↑hub`, `↓hub`, `✗ stays local`, `✗ never bridged` tags on every topic. +- **CAMS panel** → "DNS BLK 847 calls today" stat showing how many phone-home attempts were blocked. +- **GITOPS panel** → who changed what, when, with the SHA. +- **HEALTH panel** → "VLAN segregation · DENIED ✓" test confirming the policy is alive. +- **SYNOPSIS** → bottom right corner shows `◆ DATA · SOVEREIGN ◆` as a permanent banner. + +## Customer-facing claims (what we can say) + +We can claim: + +- "Raw video stays on-site; cryptographically demonstrable." +- "Hub data centers are EU-jurisdiction; no US presence in the critical path." +- "Customer holds encryption keys for evidence packs (BYOK)." +- "Audit trail in Git, signed by operators, retained indefinitely." +- "Zero unauthorized egress from cameras VLAN; verifiable in the live MQTT bus." + +We do **not** claim (yet): + +- "Compliant with [specific regulation]" — that's per-jurisdiction legal review. +- "Tamper-evident clips" — that's the evidence chain workstream, post-MVP. +- "Air-gapped possible" — partially true, but with caveats; document case-by-case. + +## Sovereignty incidents (planned response) + +If a customer reports concern that data leaked: + +1. **MQTT panel** → check bridge log for unexpected publishes. +2. **GITOPS panel** → check recent commits to bridge.conf. +3. **HEALTH panel** → check VLAN segregation test history. +4. **Pcap** → router can capture WAN egress for last 24h on demand (if enabled in config). + +The platform is designed so that demonstrating sovereignty is **a search**, not an investigation.