From 6cf21a019963468cb853e5c763ef0097115efa46 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 10 Sep 2026 17:30:22 +0200 Subject: refactor(common): delete the sender-key implementation nothing uses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `senderkeys.py` and its 13 tests implemented Signal-style sender keys, and production has never called them: chat is a key per group, per epoch, per device, derived by name. The reasoning that ruled the ratchet out stays where it belongs — in `chatbox.py`, at the top of the module that replaced it — because the argument is the useful part, and it now stands on its own instead of pointing at a file to compare against. Kept code that nothing calls is worse than absent code: it reads as an alternative somebody may reach for, and it has to be maintained past every refactor to stay compiling, which is maintenance spent on a decision already made. The three comments naming `GroupSenderKeyStore` are rewritten to say the thing they were illustrating. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3 --- packages/meshbay-node/src/meshbay_node/chat/__init__.py | 8 +++----- .../meshbay-node/src/meshbay_node/transport/webrtc_server.py | 10 ++++------ packages/meshbay-node/tests/test_chat_encryption.py | 7 +++---- 3 files changed, 10 insertions(+), 15 deletions(-) (limited to 'packages/meshbay-node') diff --git a/packages/meshbay-node/src/meshbay_node/chat/__init__.py b/packages/meshbay-node/src/meshbay_node/chat/__init__.py index cb2c868..400cb1a 100644 --- a/packages/meshbay-node/src/meshbay_node/chat/__init__.py +++ b/packages/meshbay-node/src/meshbay_node/chat/__init__.py @@ -1,10 +1,8 @@ """MeshBay Node — chat storage and relay. -Encryption is the client's: the node holds an epoch key it delivers to members -and never a plaintext message once a group has the switch on. See -`docs/chat-sender-keys.md`. It is not the Sender Keys ratchet this module's -docstring used to name — `senderkeys.py` is unused by production and is kept for -a possible future 1:1 DM, alongside `ratchet.py`. +Encryption is the client's: the node holds an epoch key it delivers to members, +and never a plaintext message. Not a ratchet — a key per group, per epoch, per +device, for the reasons `meshbay_common/chatbox.py` sets out. """ from .store import ( FORMAT_PLAIN, diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py index ec7ef5d..2a90bb4 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py @@ -383,12 +383,10 @@ class WebRTCPeerSession: self._username: str = "" # This connection's key in the group's peer registry. **Per connection, # never per account**: one person may hold several devices here, and - # keying the registry by user_id made the second evict the first — the - # same "keyed by account where it should be keyed by device" mistake as - # `pin_identity`'s old INSERT OR REPLACE and as GroupSenderKeyStore's - # silent overwrite. Symptom was invisible: two devices of one account - # could not both be connected, and whichever disconnected took the - # other's chat delivery with it. See docs/chat-sender-keys.md F7. + # keying the registry by user_id makes the second evict the first, and + # the symptom is invisible: two devices of one account cannot both be + # connected, and whichever disconnects takes the other's chat delivery + # with it. self._registry_key: str = uuid.uuid4().hex # Set from the roster: the key this node pinned for this account. Never # from the JWT — the hub picks what goes in there. diff --git a/packages/meshbay-node/tests/test_chat_encryption.py b/packages/meshbay-node/tests/test_chat_encryption.py index ea4de2f..0401d27 100644 --- a/packages/meshbay-node/tests/test_chat_encryption.py +++ b/packages/meshbay-node/tests/test_chat_encryption.py @@ -269,10 +269,9 @@ async def test_a_member_cannot_send_as_another_members_device(node): The hole that would have made encrypted chat *worse* than plaintext chat. Receivers verify a signature against the `device` field, so a member free - to name somebody else's key could be that member to everyone — which is - exactly what `GroupSenderKeyStore.add_sender` allowed, one design earlier - (`docs/chat-sender-keys.md` F1). The connection has proved which device it - is, and the claim must match it. + to name somebody else's key could be that member to everyone — and the + signature would check out. The connection has proved which device it is, + and the claim must match it. """ await ops.ensure_chat_epoch(node["state"], GROUP) _sk_alice, raw_alice, b64_alice = _device() -- cgit v1.2.3