Repository navigation
List and remove Hosted Relay passkeys from the account page - #1244
Merged
Merged
Conversation
A passkey on the Hosted Relay now records the computer whose setup code registered it, and every Relay session records the passkey that signed it in. The account page lists the account's passkeys, each with its label, when it was added, and the enrolled computer that added it, and removes one: its row goes, and every session it signed in (and their presence nonces) with it. Removing a computer keeps the passkeys it added, no longer attributed, since one passkey signs a phone in to every computer of the account and each computer's pairings pin it. A full account's 409 now names the account page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
c4839fa
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://a7cebc9a.mouseterm.pages.dev |
| Branch Preview URL: | https://hosted-passkey-burrow-scope.mouseterm.pages.dev |
nedtwigg
requested a deployment
to
hosted-preview
October 20, 2026 15:32 — with
GitHub Actions
Waiting
dormouse-bot
left a comment
Collaborator
There was a problem hiding this comment.
No findings on the diff. Approval is withheld only because Workflow Lint is red at this head: zizmor flags ci.yml:403 ("action's hash pin has mismatched or missing version comment"). This PR doesn't touch ci.yml, and the same job fails on main at ed40d010de8018e77df99a160658e0d052c33e59 (run), so the fix belongs on main. All other checks are green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dormouse-bot
approved these changes
Oct 20, 2026
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.
Hardening for Hosted Relay passkeys: an account can now see and remove them.
Until now a passkey on the Hosted Relay could only go away with its whole account. Any computer enrolled on the account can mint setup codes, so a passkey registered through one (whoever ran that computer, or redeemed a code it showed) stayed on the account even after the computer was removed, counted toward
MAX_PASSKEYS_PER_ACCOUNT, and could keep signing in.009_relay_passkey_removal.sql.dormouse_relay_passkeys."burrowId"names the Burrow whose setup token registered the passkey (ON DELETE SET NULL).dormouse_relay_sessions."credentialId"names the passkey that signed the session in (ON DELETE CASCADE). Existing passkeys have no Burrow, and existing sessions name no passkey, so they live out their 12 hours.hosted/server/relay-api.ts).setup/finishrecords the minting Burrow.setup/finishandsignin/finishrecord the session's passkey. A full account's 409 now names the account page.hosted/server/relay-account.ts).GET /api/relay/passkeyslists the account's passkeys: label,createdAt, and the enrolled Burrow that added each one.DELETE /api/relay/passkeys/:credentialIddeletes the row, and every session it signed in (and their presence nonces) goes with it. Both use the same cookie gate as the Burrow routes: exactOriginfor the delete, scoped to the login's account, 404 for another account's passkey.hosted/src/App.tsx). A Passkeys section under Computers, with Remove, says which computer added each passkey.Removing a computer deliberately keeps the passkeys it added; they just lose the attribution. Pocket signs in to every computer on the account with one passkey (a signed-in phone retires a later computer's setup code instead of registering again), and each computer's pairings pin that passkey. Cascading would sign the phone out of the other computers and force it to pair with each one again whenever an old laptop is retired. The rationale entry says why.
The self-host Relay is unchanged: its passkeys belong to the operator's single account, in the operator's own state files.
Tests
hosted/server/tests/relay.test.ts, "a passkey names the computer whose code registered it and outlives it; removing the passkey ends its sessions". Setup and sign-in sessions name their passkey. Removing the computer leaves the passkey unattributed and still signed in. Deleting the passkey ends its sessions and nonces, and its sign-in then 404s; another passkey's session stands. The test goes red if the session'scredentialIdis dropped.hosted/server/tests/workers.test.ts, "the account lists its passkeys with the computer that added each, and removing one ends its sessions". Checks the list and attribution, that an unentitled account gets 403, the origin gate, the 404 for another account's passkey, and the session cascade.boundary.test.tslists the two new account routes.migrations.test.tspins009. The cap test expects the new 409 message.Specs
docs/specs/hosted.md. In "Burrow enrollment": rows for the two routes; Never remove a passkey with its Burrow; Must remove a passkey by deleting its row. In "Relay": the setup row records the Burrow. Word budget ratcheted.docs/specs/hosted.rationale.md. The passkey and session cap entries no longer say that only the account grows those rows. A new entry explains why a passkey outlives its Burrow.docs/specs/security-hosted.md.S100is widened: a removed passkey's sessions must not survive, and removal must not reach another account's passkey.009is added to the files to inspect.docs/specs/security.md. The enrollment-approval bullet now says what approving someone else's code lets their computer do, and how to undo it. The setup-QR bullet points at the account page. Word budget ratcheted..github/audit/canaries/passkey-removal-keeps-sessions.patch(Rule: S100).This PR touches
.github/, so the owner merges it.🤖 Generated with Claude Code