Touch ID / Face ID / Windows Hello / Android fingerprint / YubiKey
(PRF-capable) can now unlock the local seed without typing the
passphrase. Fully client-side — the server has zero visibility into
the credential or the derived key.
How it works (WebAuthn PRF extension):
1. Setup (Dashboard → "Quick unlock" → "Set up biometric unlock"):
• Register a platform credential with prf:{} in extensions.
• If the authenticator returns prf.enabled, immediately
getAssertion() with a random 32-byte salt to retrieve a
deterministic 32-byte secret (the "PRF output").
• AES-GCM(seed) under that secret → store the blob, salt, nonce,
and credentialId in a separate IDB entry from the passphrase
blob.
2. Unlock (Unlock page → big "Unlock with Touch ID" button):
• getAssertion() with the stored credentialId + salt → same
32-byte secret → AES-GCM decrypt → seed.
• unlockWithSeed() (new helper in identity-store) merges the
seed with handle/server/primary metadata to rebuild the
UnlockedIdentity session shape.
Trust properties (intentional):
• Passphrase blob stays in place as the authoritative backup.
Biometric is purely additive — wipe your browser profile or lose
the device, passphrase still works on any device where you
re-import the seed.
• PRF output never leaves the browser. The authenticator is the
only thing that can produce it, and only with the matching salt
+ credentialId we stored.
• Disable → just deletes the IDB entry; the registered credential
on the device still exists but is unused. (User can also clear
it from their OS / passkey manager.)
Browser support gating:
• Dashboard panel renders "no platform authenticator detected" if
isUserVerifyingPlatformAuthenticatorAvailable() returns false.
• Setup fails with a clear error if PRF isn't supported by the
authenticator (older YubiKeys, some password managers).
• Unlock page falls back to passphrase form automatically if
biometric fails (cancelled, sensor error, etc.).
Live at https://kez.lat (asset index-Df_F5lEP.js).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>