summaryrefslogtreecommitdiffstats
path: root/tmp-decisions.md
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-13 03:56:30 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-13 03:56:30 +0200
commitee6573c57f721db8550e34e1c1c79c5922c62a4b (patch)
tree997f251456730487c75641802edfad167b099b67 /tmp-decisions.md
parentf0248975908ad670fa8a820f865bf22ea8d0172d (diff)
downloadmeshbay-0.1.tar.gz
docs: second security review + roadmap rewrite0.1
Second architecture and security review (second-review.md): 6 critical and 7 high findings against the Phase 12 implementation, plus an assessment of whether the system meets its end-to-end confidentiality claim. Roadmap rewritten against those findings (devel-phases-next.md): new blocking Phase 11.5 (security remediation), Phase 12 (hub minimization), Phase 13 (native desktop client). Old phases 12-17 renumbered to 14-19. tmp-decisions.md records two open decisions: whether the hub keeps serving the web UI, and browser extension vs native desktop client vs both. CLAUDE.md and devel-phases-next.md also carry pre-existing Phase 12 edits from the working tree that could not be cleanly separated from the review changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'tmp-decisions.md')
-rw-r--r--tmp-decisions.md145
1 files changed, 145 insertions, 0 deletions
diff --git a/tmp-decisions.md b/tmp-decisions.md
new file mode 100644
index 0000000..97a27ea
--- /dev/null
+++ b/tmp-decisions.md
@@ -0,0 +1,145 @@
+# Open decisions — client architecture
+
+> Working note, not a spec. Created 2026-08-13 after the second security review.
+> Delete or fold into `docs/meshbay-draft-v5.md` once decided.
+
+---
+
+## Status
+
+| # | Decision | State |
+|---|---|---|
+| D1 | Does the hub keep serving the web UI? | **Open** — leaning yes |
+| D2 | Browser extension, native desktop client, or both? | **Open** — needs time |
+| D3 | Transport: aiortc primary, QUIC at parity, TCP+HTTP removed | ✅ Decided 2026-08-13 |
+
+**Neither D1 nor D2 blocks anything right now.** Phase 11.5 (security remediation),
+Phase 12 (hub minimization), Phase 14 (node CLI) and Phase 15 (Sender Keys) are entirely
+client-agnostic — every finding they close is node-side or hub-side. Phase 11.5 is in
+progress on that basis.
+
+---
+
+## Why these are open
+
+The second review recommended a native client and claimed *"T3 disappears — code integrity
+stops depending on the hub."* **That claim was wrong and has been corrected** in
+`second-review.md` §9.
+
+If the hub operator is the adversary, a native client downloaded from `meshbay.org` and
+signed with a key that operator holds does not remove the trust — it relocates it from "the
+JS they serve" to "the binary they serve." What actually changes is **detectability**:
+
+- **Browser:** an attack is one HTTP response, targeted at one user, leaving no artifact.
+ Undetectable in principle.
+- **Native:** an attack requires shipping a build. That build is an artifact — hashable,
+ archivable, comparable between users, reversible. Targeting one user means giving them a
+ different binary, which reproducible builds and published hashes make detectable.
+
+That is a real improvement, but **the value lives in the verification machinery
+(reproducible builds, published hashes, independent rebuilds — Phase 18.7), not in the
+packaging format.** Without it, a native client from meshbay.org is only marginally more
+trustworthy than the SPA from meshbay.org.
+
+Native also has real costs that were under-weighted: loss of the browser sandbox (a Python
+process with full user privileges vs a seccomp-confined renderer), ownership of patch
+velocity for WebKitGTK and every bundled dependency, and new attack surface (loopback media
+server, IPC bridge, update client).
+
+**Conclusion recorded:** the native client is justified on *product* grounds — durable keys,
+no browser tab, background connectivity, better video, hub-less `group://` access over QUIC.
+It should not be justified as the fix for T3 unless 18.7 ships with it.
+
+---
+
+## D1 — Should the hub keep serving the UI?
+
+Keeping it is defensible. It is how anyone tries the platform without installing anything,
+and it stays the fallback when a device has no client installed.
+
+What must be true if it stays (all already scheduled in Phase 12.6):
+
+- strict CSP and Subresource Integrity on the bundle
+- the hub publishes a **signed digest** of the served bundle, so any third party — an
+ extension, a native client, a curious user — can verify it
+- `/app/` carries an explicit, visible "reduced trust: this hub serves this code" notice
+- the docs never claim end-to-end integrity for the hub-served SPA path
+
+The honest framing: hub-served SPA is a **convenience tier**, not the secure tier.
+
+---
+
+## D2 — Extension vs native: what each actually covers
+
+Three shapes, cheapest first:
+
+**Option A — Extension as a verifier (hub still serves the UI)**
+The extension does not ship the UI. It hashes the bundle the hub served and compares it
+against a digest signed by the project. Mismatch → visible alarm, optionally block.
+Converts a silent targeted injection into a loud one. Small effort, keeps today's
+architecture, compatible with D1 = yes.
+
+**Option B — Extension ships the UI (hub serves the API only)**
+The UI lives in the extension, distributed and signed by Mozilla/Chrome — a channel **the
+hub operator does not control**. Manifest V3 forbids remote code, which works in our favour:
+the structure enforces exactly what we want. Keys live in extension storage, isolated from
+page JS. Moderate effort.
+
+**Option C — Native desktop client (pywebview + aiortc)**
+Phase 13. Full control, durable keys in an OS keystore, QUIC, hub-less access, best UX.
+Highest effort, and the security argument depends on 18.7.
+
+### Comparison
+
+| | Hub-served SPA (today) | A: extension verifies | B: extension ships UI | C: native desktop |
+|---|---|---|---|---|
+| Code distribution channel | Hub (the adversary) | Hub, but **verified** | Store (independent) | Hub download + own signing key |
+| Silent targeted injection | Undetectable | **Detected** | Not possible | Detectable *if* 18.7 |
+| Browser sandbox | ✅ Full | ✅ Full | ✅ Full | ❌ None (partial under Flatpak) |
+| Patch velocity | Browser auto-updates | Browser auto-updates | Browser + store review latency | **You own it** (WebKitGTK, Python deps) |
+| Key storage | IndexedDB, page-reachable | unchanged | Extension storage, page-isolated | **OS keystore** |
+| Crypto available | WebCrypto only (no ChaCha20/Argon2id) | unchanged | unchanged | **Full** (ChaCha20, Argon2id 256 MB) |
+| Transport | WebRTC | WebRTC | WebRTC | WebRTC **+ QUIC** |
+| Large file → disk | Chrome only (FS Access API) | unchanged | unchanged | **Native, unlimited** |
+| Hub-less `group://` | ❌ | ❌ | ❌ | ✅ |
+| New attack surface | — | negligible | negligible | loopback server, IPC, updater |
+| Platforms to maintain | 0 | 2 stores | 2 stores | 3 OSes |
+| Effort | 0 | Low | Moderate | High |
+
+### Observations for the decision
+
+- **A and B are not exclusive with C.** A/B protect browser users; C serves users who want a
+ real application. "Both" is coherent — just sequence them.
+- **B gives most of C's security benefit at a fraction of the cost**, because the win was
+ never the packaging format — it was getting the code off the adversary's distribution
+ channel — and the extension keeps the browser sandbox while doing it.
+- **Store review latency is the one place B is worse than C**: a critical fix waits on
+ Mozilla/Google. Mitigate with a version-pinned kill switch.
+- **For node operators specifically, Phase 14 (CLI) beats all three.** The operator is the
+ highest-value target — holds the GEK, is the content authority — and today must use
+ hub-served JS to initialize GEKs and invite members. The CLI removes that dependency at a
+ fraction of any client's cost. If only one thing gets built for T3, it should be the CLI.
+- If **D1 = yes** (hub keeps serving the UI), Option A is the natural companion and is nearly
+ free once 12.6 publishes the signed digest.
+
+### Not yet investigated
+
+- Whether AMO/Chrome Web Store policy accepts an extension whose purpose is P2P file sharing
+- Whether MV3 service-worker lifetimes can hold a long-lived WebRTC DataChannel (may need an
+ offscreen document — worth a spike before committing to B)
+- Safari/iOS: no extension route comparable to AMO; likely out of scope either way
+
+---
+
+## Impact on the roadmap
+
+| Decision | If yes | If no |
+|---|---|---|
+| D1 hub serves UI | Phase 12.6 as written (CSP, SRI, signed digest, reduced-trust notice) | 12.6 shrinks to removing `/app/`; hub becomes API-only |
+| D2 = A | Small new phase; 12.6 is a prerequisite | — |
+| D2 = B | New phase, ~Phase 13-sized; 13.1 platform split is reused directly | — |
+| D2 = C | Phase 13 as written (13.2–13.11), + 18.7 for the security claim to hold | Phase 13 reduces to 13.1 only |
+
+**13.1 (platform adapter split) is worth doing regardless of D2.** It is pure refactoring
+whose acceptance criterion is "the browser SPA behaves identically," and it is the
+prerequisite for A, B and C alike.