diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-14 19:15:49 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-14 19:15:49 +0200 |
| commit | cfe49407abb3eb48b996ab6d08d66985f29846f0 (patch) | |
| tree | f49e3ceacd9a49aba818ff549ec8da6b8e7521f7 /CLAUDE.md | |
| parent | f0984e86d9cb596a282ce6feb7cfc2f075b2794b (diff) | |
| download | meshbay-cfe49407abb3eb48b996ab6d08d66985f29846f0.tar.gz | |
docs: user guide and conventions catch up with per-node identity
USERGUIDE said registration submits your public keys "so other members can wrap
GEK bundles for you". Both halves are wrong now: registration creates an account
and nothing else, and nobody wraps anything for a key fetched from the hub. The
API reference and the register body followed the same correction.
CLAUDE.md gains the block a future session needs before touching registration or
anything shaped like a user's public key: keys are born at first contact with a
node and stay there, the hub publishes none, tokens carry no pk_user, and a
scripted signup is now a real account.
Left alone deliberately: first-review.md, docs/poc-v1*.md and poc/spike-results.md
still describe the old JWT and registration. They are records of what was true on
their date, like second-review's verdict table, and draft-v5 is what states the
present.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'CLAUDE.md')
| -rw-r--r-- | CLAUDE.md | 23 |
1 files changed, 22 insertions, 1 deletions
@@ -143,7 +143,8 @@ Scope: `hub`, `node`, `common`, or omitted for cross-cutting - `_bundleKey` persisted in IndexedDB (CryptoKey survives page refresh) - `_sessionKeys` persisted in sessionStorage (survives refresh, cleared on tab close) - `_pkFromSk()`: derive X25519 public key from recovered private key via JWK export (no hub fetch) -- Removed auto-`regenerateKeys()` on login (was silently rotating hub keys, breaking GEK unwrap) +- `regenerateKeys()` is gone entirely (2026-08-14): identity keys are per node, so + rotation is `meshbay-node member unpin <user>` plus a fresh code - Raw answer SDP saved before `setRemoteDescription` (Chrome strips sha-256 from multi-hash SDP) - Upload chunk size: 48KB (fits aiortc SCTP limit after msgpack overhead) @@ -212,6 +213,26 @@ See `docs/invite-pairing-v1.md`. Read it before touching invites, admin authorit - Floor: 12 characters and ~60 estimated bits, enforced client-side only — with the password split (T1) the hub never sees a passphrase +## Identity keys are PER NODE (2026-08-14) + +See `docs/per-node-identity-v1.md`. Read it before touching registration, the +keypair bundle, or anything that looks like a user's public key. + +- A keypair is created at **first contact with a node**, encrypted under the + passphrase, and left on that node. Never reused elsewhere. Cracking one yields + the identity used with that operator and nothing anywhere else +- **The hub stores and publishes no user keys.** `users.pk_ed25519`/`pk_x25519` + are dropped, `PUT /me/keys` is gone, `/pubkeys` returns an account id and the + node linking key. Do not reintroduce a key directory — that was H3 +- **Tokens carry no `pk_user`.** The node recorded it as the uploader's identity + and authorized deletion against it, so whoever issued tokens decided who could + delete a file. Attribution uses the roster pin (`_pinned_pk`) +- Registration generates nothing, so a scripted signup is a real account — + `QE/deploy/demo.py bootstrap` takes a wiped hub and node to a working demo +- The key handed back on a join belongs to the **group of the connection**, not + the group named in the invitation (an operator pairs node-wide while opening a + group) + ## Two lessons that cost four rounds of live testing - **`QE/deploy/e2e.py` cannot test `app.js`.** It is a second implementation of the |