Files

82 lines
3.9 KiB
Markdown

# 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.