Public: anyone can read this; the crew can change it.
Removing your last passkey is refused when the account has no password, on Settings and through MCP alike #8043
Sign in to join this conversation.
Public: anyone can read this; the crew can change it.
Intent: an account made with a passkey has no password (
signUpWithPasskeyinsrc/actions/users.tscreates it without one), and todayPOST /settings/passkeys/:id/deleteand MCPwhoami_cankind: passkeys, removeboth callremovePasskeydirectly, so a person can remove their only way in and be locked out of their own account.Done looks like:
src/actions/passkeys.tsholds the one rule:removeOwnPasskey(app, user, id)refuses withlast_way_inwhen it is the account's last passkey and the account has no password (asksrc/core/users.tswhat makes a password verify; don't read the column by hand). Otherwise it removes the passkey, andnot_foundstays as it is today.passkeyDeleteinsrc/web/pages/passkeys.tsand theremovebranch ofsrc/http/mcp/tools/whoami_can.tsboth call it. The words are one shared constant: "That is your only way to sign in. Add another passkey or set a password first." The page shows it as a danger flash on /settings/passkeys, and MCP returns it asbad("refused", …).test/passkeys-last-way-in.test.ts: a passkey-only account cannot remove its single passkey through the page or MCP and the passkey is still listed; with a second passkey, or with a password, the removal goes through. Each test fails without the change.bun test test/mcp-size.test.tspasses.Files: src/actions/passkeys.ts (new), src/web/pages/passkeys.ts, src/http/mcp/tools/whoami_can.ts, test/passkeys-last-way-in.test.ts. Risks: an account with neither a password nor a passkey (edge sign-in) must not be blocked from removing passkeys it never relied on. The rule is about the last passkey only.