Repository navigation
feat(share): end-to-end encrypt invite-link terminal sessions - #561
Merged
Merged
Conversation
The host no longer uploads the raw session key for an invite-link session. The link and short code only admit; the server asks the host's socket to wrap the key for each admitted guest (VoltiusApp/server#96). - Host: createInviteLinkSession goes through prepareWrappedSessionKey, so it publishes the host's public key and keeps sessionKeyBytes. A key_request frame wraps for that guest through the same path as a People invite (inviteUserToSession now takes a user id; it only ever used that). - Guest: my-key answering 202 publishes the guest's public key before the socket opens, so the host wraps to the current key. joinSession no longer blocks on the key: the tab opens, the bar reads "Waiting for the host…", and frames that arrive first wait on the pending key in order. key_ready fetches and unwraps it; after 30 s the session ends with "Host didn't share the key". - raw_key from an older host is still imported, for one release. - joinSession reuses makeCallbacks instead of a copy of it, keeping the guest's no-op onInput. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #521. Server side: VoltiusApp/server#98, already deployed (
sha-9208738).Invite-link sessions uploaded the raw session key, and the server gave it to anyone holding the link or a short code. Now the link and the code only let a guest in. The host's client wraps the key for each guest the server admits, the same way People invites already work.
Host
createInviteLinkSessionstops sendingsession_key_bytes. It now callsprepareWrappedSessionKey([]), which also publishes the host's public key: guests unwrap against that key. It keepssessionKeyByteson the connection.key_request {user_id}on the socket wraps the key throughinviteUserToSession, the same path a People invite takes, with a fresh public-key read.inviteUserToSessionnow takes a user id, since that's all it ever used, and the store's invite andkey_requestshare onewrapKeyForUserhelper.Guest
getMySessionKeyreturns"pending"on 202. Before returning it publishes the guest's own public key, because the socket admission that triggerskey_requestmust not race that publish.joinSessionno longer waits for the key. The tab opens right away andMultiplayerBarshows "Waiting for the host…".openWebSocketaccepts a key promise, and output that arrives early (the history replay) waits on it, in order.key_readytriggers a newmy-keyfetch and an unwrap. After 30 s without it, the socket closes and the bar reads "Host didn't share the key".raw_keyfrom an older host still imports, for one release.The socket frames are
key_requestandkey_ready, with underscores like the other frames, not the hyphenated names in the issue.Also
joinSessionnow reusesmakeCallbacksinstead of carrying its own copy (repo DRY rule). The guest keeps its no-oponInput: the host's relay must never write into a guest's local session. A regression test covers that; I confirmed it fails without the override.Compatibility
Tests
session_key_bytesis sent and the host key is published; 202 gives"pending"and publishes first; the wait succeeds onkey_ready, times out with no fetch, and fails if still pending afterkey_ready.key_requestandkey_readydispatch to their handlers; early output is held and delivered in order.key_requestwith exactly one wrap and POST; a pending guest goes waiting, thenkey_ready, then the key; a failed wait ends the session and closes the socket; a guest never relays input.tsc --noEmitis clean. All 53 multiplayer, terminal and members test files pass (428 tests, plus the new ones). One full-suite run hit a 5 s timeout in an unrelated test (TriStateToggle) under load; it passes when run alone.Still to do
landing/content/blog/shared-terminals.mdxin VoltiusApp/web, which still says link sessions aren't E2EE.🤖 Generated with Claude Code