aboutsummaryrefslogtreecommitdiffstats
path: root/docs/meshbay-draft-v5.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/meshbay-draft-v5.md')
-rw-r--r--docs/meshbay-draft-v5.md46
1 files changed, 38 insertions, 8 deletions
diff --git a/docs/meshbay-draft-v5.md b/docs/meshbay-draft-v5.md
index b03328b..e4218ee 100644
--- a/docs/meshbay-draft-v5.md
+++ b/docs/meshbay-draft-v5.md
@@ -1,8 +1,15 @@
# MeshBay — Architecture Draft v5
+> **SUPERSEDED 2026-08-17 by `docs/meshbay-draft-v6.md`.** v6 restates only what
+> changed; everything below that v6 does not touch is still authoritative — the
+> handshake (§4), node authority (§5), the hub's role (§6), cryptography (§7) and
+> the testing posture (§10). Read v6 first, then this.
+>
> Status: **Phase 11.5 (security remediation) complete. Invite redesign complete
> (2026-08-14) — H3 and M3 closed.** See `devel-phases-next.md` and, for the invite
-> and pairing design, `docs/invite-pairing-v1.md`.
+> and pairing design, `docs/invite-pairing-v1.md`. For the desktop client — shell,
+> device linking, account creation, node management — `docs/desktop-client-v1.md`
+> (2026-08-17) is authoritative and supersedes §8.2 here.
> Supersedes `meshbay-draft-v4.md`. Sections not restated here are unchanged from v4.
>
> v5 exists because the second security review (`second-review.md`, 2026-08-13) found
@@ -220,7 +227,7 @@ was 32 opaque random bytes signed blind — an unbound signing oracle.
|---|---|
| `file_delete` | Node operator, or the user who uploaded the file (verified by the key recorded at upload) |
| `invite_create` | **Node operator only** (delegation designed, deferred) |
-| GEK activation | **Local admin UI or CLI only** — no MNP message can activate a GEK |
+| GEK activation | **Local admin UI or CLI only** — no MNP message can activate a GEK. The rule targets *key material arriving from outside* (C5b), not the instruction: a future operator-signed `gek_rotate` where **the node generates the key itself** is a different shape and is allowed (`docs/desktop-client-v1.md` §6.2). The initial `gek-init` stays local — with no GEK there is no completed session to carry a signed op |
| ~~`gek_bundle_store`~~ | **Message deleted.** No member ever hands the node key material |
`gek_bundle_store` previously accepted any member's bundle and auto-activated one
@@ -513,17 +520,40 @@ end-to-end *integrity* for that path.
### 8.2 Native client
-pywebview + aiortc, sharing ~69% of the existing UI unchanged (the SPA contains no direct
-`crypto.subtle` or `RTCPeerConnection` usage; everything goes through three injected
-globals and one fetch helper). Assets ship **inside the package** and load from disk — a
-shell pointing its WebView at the hub's `/app/` would be a browser with a different icon
-and would fix nothing.
+**Electron** (decided 2026-08-17 — see `docs/desktop-client-v1.md`, which is authoritative
+for the desktop client and supersedes this section's earlier pywebview form), with an
+optional Python sidecar reusing `quic_client.py` for hub-less `group://`.
+
+Assets ship **inside the package** and load from disk — a shell pointing its WebView at the
+hub's `/app/` would be a browser with a different icon and would fix nothing. That
+constraint is unchanged and is the whole point.
+
+What changed is the engine. The SPA does not depend on "the web" in general but on
+Chromium-class APIs: `RTCPeerConnection`, WebCrypto X25519/Ed25519, MSE, Service Workers,
+File System Access. Keeping Chromium keeps `transport.js`, `crypto.js`, `keyderive.js`,
+`downloads.js`, `sw.js` and the MSE player **unchanged**; replacing it with a system webview
+meant reimplementing ~2500–3000 lines plus a loopback media server and native dialogs. The
+"~69 % reused" figure quoted here previously was measured in August against an `app.js` of
+~2600 lines; it is 4586 lines as of 2026-08-17, and `app.js` now contains 2 direct
+`crypto.subtle` calls (`_pkFromSk`), so the three-globals seam had already leaked.
Native does **not** remove trust in the hub operator; it converts an undetectable,
per-request, per-user attack into a persistent artifact that can be hashed and compared.
That value is realised by reproducible builds and published hashes, not by the packaging
format.
+Two properties of the desktop client bear on this document directly:
+
+- **Identity keys are generated and kept locally**, never bundled anywhere. C4 closes for a
+ native device unconditionally — but **not for an account that also uses a browser**, which
+ still needs a bundle on each node (§7.1). An account is only as strong as its weakest
+ client, and the docs must say so.
+- **A second device is admitted by device linking**, not by an operator code: the
+ already-pinned key countersigns, bound by a one-time code the new device generates. The
+ hub cannot produce that countersignature — it has stored no user keys since 2026-08-14
+ (§6.1) — so this adds no hub-reachable authority. `identities` gains a device dimension;
+ see `docs/desktop-client-v1.md` §4 before touching the roster.
+
---
## 9. Open items
@@ -546,7 +576,7 @@ format.
| # | Item | Status |
|---|---|---|
-| C4 | Remote keypair bundles | Bounded (4 pre-proof fetches, audited); closes in Phase 13.3 when the native client stops storing them remotely |
+| C4 | Remote keypair bundles | Bounded (4 pre-proof fetches, audited). **Closes for a native device unconditionally** (its keys are never bundled), but **stays open for any account that also uses a browser** — a browser has no durable storage of its own and needs a bundle on each node. Full closure needs the opt-out in `docs/desktop-client-v1.md` §5.1, signed by a pinned key so the hub cannot set it |
| — | Chat encryption (Sender Keys) | Phase 15. Distribution must be **pairwise to identity keys**, never GEK-derived |
| — | Chat attachments | Plaintext on the node; decide in Phase 15.7 |
| — | Delegation | Designed, deferred: a group admin who does not run the node still cannot invite |