On passkeys for crypto
Georgios Konstantopoulos recently published an article making the case for passkeys as the future of crypto wallets. I disagree, and this is my attempt to explain why. I am not arguing against passkeys in general. I am arguing against passkeys as the foundation for crypto wallets. I am also not arguing specifically against Tempo's implementation of passkeys, rather against the general idea of using passkeys for self-custodial wallets. This excludes biometric authentication systems that use secure enclaves but do not rely on FIDO-style passkeys.
Context
Before I start arguing against passkeys as the foundation for crypto wallets, it is worth being clear about where I am coming from, so here is a short timeline of my involvement with passkeys and related systems.
- September 2021: I started designing self-sovereign crypto authentication systems around biometrics and secure enclaves, and dAuth was one of those experiments.
- May 2022: Apple, Google, and Microsoft announced passkeys under the FIDO Alliance.
- June 2023: ERC-7212 proposed a secp256r1 precompile to support WebAuthn-style passkeys onchain.
- August 2023: I built and tested one of the earliest onchain passkey auth systems during ETHIstanbul.
- 2024 and 2025: Participant in Coinbase's embedded wallet private beta (Wallet-as-a-Service), partnering on auth, including passkeys UX and onboarding tradeoffs.
Since 2017, my main work in the crypto space has been centered on improving the user experience while preserving the core properties of self-custody. Most notably Portrait Protocol and Portrait Wallet, but there are many more experiments that involved passkeys and biometrics in some form. I have spent at least a few hundred hours designing, building, and testing passkey-based authentication systems for crypto applications.
Passkeys are like nicotine
The business case for passkeys is obvious. Seed phrases create onboarding friction, friction creates drop-off, and drop-off is bad for growth.
Passkeys are the nicotine patch. They remove the seed phrase from the first-run experience and replace it with a device-native flow that feels familiar to people coming from normal apps.
The problem is that passkeys solve onboarding friction by pushing the real problems into a worse place. They fit apps with account recovery behind them. They fit self-custodial wallets much less well.
The problems
- The biggest problem is portability. A passkey created on a Mac sits in Keychain and does not naturally move to Android.
- A third-party password manager like 1Password can sync across platforms, but that is another setup burden. For many users it is not simpler than a seed phrase.
- The native passkey UI is designed for signing in to an app. For wallets it can miss the context that actually matters.
- Passkeys are bound to a domain through the RP ID. If the domain path breaks, access can break too, even if you technically still hold the keys.
- Access keys are an extra abstraction layer added to compensate for passkey weaknesses. If apps can already store a seed phrase inside passkey fields like
largeBloborPRF, the obvious question is why not build the abstraction on top of the seed phrase instead. [4] - And to get syncing at all, you usually need cloud services enabled like iCloud. Otherwise you are left with local transfers like AirDrop, which only work when the devices are near each other.

There is a nuance for self-custody and legal opportunities
The value of passkeys is not just convenience. Self-custody can unlock legal and financial opportunities that custodial accounts cannot. If that upside matters enough, a company might accept the UX downsides. But that is a different argument from saying passkeys are the best onboarding UX.
Base App shows the distinction. A self-custodial wallet can experiment more freely than Coinbase.com, which operates under tighter custodial and compliance constraints. If passkey-based wallets enable products custodial accounts cannot, that may justify them despite the tradeoffs.
Conclusion
I think biometrics are good. They are one of the best ways to make crypto feel native to the devices people already use.
But a self-custodial system should always let the user back up the seed phrase directly. That should remain the bedrock recovery path, even if the first-run experience is wrapped in Face ID, Touch ID, or some other device-native approval flow.
On top of that, I would rather build optional recovery layers than make passkeys the foundation itself. That could mean Tempo-like access keys, or even using a passkey to help protect or unlock the passphrase itself. The important thing is the ordering: biometrics for convenience, seed phrase for sovereignty, and extra recovery options as optional layers above that base.
Experiments
Portrait Wallet
In Portrait Wallet, we used biometrics plus SIWE-style sign-in logic to authenticate a device and complete login over WebSockets. The transport does not have to be WebSockets though. You can apply the same pattern over decentralized messaging protocols like Waku if you want the handshake to move through a peer-to-peer channel instead of a centralized socket server.
That is the point I care about more than passkeys as a brand. The important part is a biometric, device-native sign-in flow that still gives you control over how intent is transported and verified.


dAuth
Back in 2021, before passkeys became the fashionable answer to wallet UX, I built a desktop auth flow around the secure enclave and biometrics. The app could respond to a custom dauth:// protocol, unlock a wallet locally, and sign SIWE-style (ERC-4361) parameters like nonce and domain.
That matters because it shows the point was never to cling to seed phrases. I wanted the biometric, device-native experience early. The real question was what kind of system could deliver that experience without quietly breaking autonomy.
This later inspired the architecture for Portrait Hosting for MacOS and Windows, but instead of communicating over localhost, it used the dauth:// protocol handler with a callback to the application domain, which is arguably a more secure model. It avoids a browser-facing localhost bridge, depends less on browser-specific rules like Brave blocking local requests, and narrows the attack surface.
Even if a site tried to fake the origin by passing it into dauth://, the important parts still stayed bound to the real relying party. The user would be prompted to sign in to a specific origin like example.com, and the callback would also return to example.com. So even if a malicious site triggered the protocol handler, the result would not be sent back to that malicious site.