Files
thePR0M3TH3ANandClaude Fable 5 30b4f34300 Recovery phrase is mandatory for passkey accounts
Owner decision: keep the architecture (static, independently hostable, no
BitLogin-operated OAuth service, shared signer, or central login domain)
and strengthen recovery instead.

Passkey registration now runs the phrase ceremony BEFORE granting a
session -- phrase shown, three words verified, then dashboard -- exactly
as password signup does. The deferred 'Secure your account' card is gone,
along with the securePhrasePending state behind it: that design was
inherited from the OAuth on-ramps, where a service still held a copy of
the credential. Nothing holds a copy for a passkey account, so deferring
the only recovery path was strictly worse than the design it came from.

Note the recovery EXPORT is not an alternative here: by design it carries
no phrase-derived key and cannot recover an account alone (§19.5), so the
phrase ceremony is the only thing that closes the trap.

Also documents the loss mode that surprises people: a passkey is bound to
the site's WebAuthn RP id, so a deployment changing domain leaves its
users' passkeys unable to unlock anything there -- account untouched on
relays, phrase still works.

The e2e now drives the real ceremony (reads the 12 words from the DOM,
answers the three-word quiz) and asserts activeMethod() is null until it
completes, so 'no session before recovery' is enforced against a real
browser. New policy pin: runPasskeyRegistration must hand off to the
phrase screens and must not dispatch a session itself.

269 tests green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-04 15:41:24 -04:00
..