aboutsummaryrefslogtreecommitdiffstats
path: root/docs/meshbay-draft-v5.md
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-18 02:14:39 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-18 02:14:39 +0200
commit50ebb4f2e620dad8e1fbca8307b97c5e10e7e6c0 (patch)
tree0dd0d2f63ec70a4d459d12aff8f68d2f04881c70 /docs/meshbay-draft-v5.md
parentf23e8e51e4b8bc03d6109081fe048af1782e1f4e (diff)
downloadmeshbay-50ebb4f2e620dad8e1fbca8307b97c5e10e7e6c0.tar.gz
docs: settle the desktop client, and draft v6
A design discussion on 2026-08-17 settled Phase 13 and, in doing so, changed four things the spec states. v6 restates only those; v5 stays authoritative for everything it does not touch, per the convention v5 itself used with v4. What changed: * The native shell is **Electron**, not pywebview — structural decision 18 reversed. The SPA depends on Chromium-class APIs (WebRTC, WebCrypto X25519/Ed25519, MSE, Service Workers), so keeping Chromium keeps transport.js, crypto.js, keyderive.js, downloads.js and sw.js *as the client*. A system webview meant reimplementing ~2500-3000 lines. The old "69 % reused" figure was measured against an app.js of ~2600 lines; it is 4586. * A group's content is **several named roots**, not one directory, because the planned video and audio libraries will not live in one folder on one disk. * **Device linking**: one person may hold several devices on a node, admitted by a key the node already pinned and bound by a one-time code the new device generates. Without it a native client is refused where a browser is not, and an account created natively could never be opened in a browser. * **Authorship is authenticated, not asserted** — chat senders sign, uploads have a provable owner, and delete authorization moves from the uploading key to the account. And one rule v5 assumed without writing down: **group-related server state lives on the node.** Verified for multi-root — SwarmSource carries hashes and endpoints, no paths. Also here: the Caddy configuration, which was a snippet in the roadmap that would have broken the SPA (it predates /a/<hash>/ asset versioning and would have 404ed /sw.js, silently killing streamed downloads on Firefox and Safari); and downloads.html, which becomes a security page once a release key exists. Phase 15 was re-read against device linking and is wrong as written: a sender key must be per **device**, never per person, or two devices sharing a chain produce key and nonce reuse — C1 again, one level down. senderkeys.py already fails this silently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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 |