logoalt Hacker News

Things I learnt about passkeys when building passkeybot

62 pointsby emaddatoday at 6:58 PM18 commentsview on HN

Comments

BoppreHtoday at 8:27 PM

Love these "lessons learned" posts, keep the coming!

My only feedback is about the Quickstart of passkeybot, "feed this example into a good LLM with these instructions". I undeerstand the idea, but I was a bit shocked that the first time I see these sort of instructions is for an auth framework.

ChrisMarshallNYtoday at 8:30 PM

Thanks for that!

I am in the middle of writing a passkey-driven server dashboard app (native SwiftUI app, with a small server component).

In the future, I would like to use passkeys as much as possible, but they do present a bit more friction to users than Sign in with Apple. When I was initially learning them I wrote this up: https://littlegreenviper.com/series/passkeys/

smallnixtoday at 9:49 PM

In oauth2: when I /1 associate a random uuidv4 for each new flow with my user (server side), /2 stick that uuid into the state parameter, and then /3 look up my user with this on callback-endpoint execution. Isn't PKCE in that case redundant?

show 2 replies
xg15today at 9:28 PM

> generateKey is a JS API that allows you to create new key pairs, where the private key cannot be extracted similar to passkeys.

Is that "cannot be extracted" from JS only, or is this an actual device-locked, TPM/SEP-bound key like passkeys?

If it is, it seems kind of like the buried lede to me that there is a browser API that lets any website built its own completely unstandardized quasi-passkey system and lock the key to the current device.

show 1 reply
loloquwowndueotoday at 8:28 PM

How to add passkeybot support to your site, according to their official guide:

start

(1) Copy / paste example_http_server into your LLM of choice (use a paid/good model). (2) Prompt: Implement the HTTP handlers here for my project,..

Um, no? How about you give me real instructions on how to do it? I’m not going to delegate a security-critical task to an LLM. And since I need to review it carefully myself anyway, I might as well write it all by hand, right? Like, the whole premise is I just need to implement a couple of webhooks.

show 1 reply
tptacektoday at 8:45 PM

Regarding PKCE, the way I remember it is that OAuth2 was deliberately designed to eliminate as much actual cryptography as possible, relying instead on same-origin and TLS security; PKCE is one of the few things that introduces an actual cryptography primitive.

boombapoomtoday at 8:55 PM

i wish passkeys could replace passwords, not suppliment them

show 3 replies
EGregtoday at 11:02 PM

The authenticator GUI only shows “sign in to your_domain.com”. It never allows a more general “sign this content for your_domain.com”. E.g. “sign this transaction request to move £50 to Bob's account”.

That is why you should ship a pristine HTML+CSS+JS environment that can use subtle web crypto. YOU show what is being signed. And then the device can sign its hash using the secure enclave.

And you CAN do attestation even on consumer devices, by using the Device or AppAttest framework (I think that’s what it’s called). I did it myself in our app. It does show up 100% of the time but when it does it’s useful.

PS: being the web3 / blockchain geek that I am, I will tell you stuff that triggers anticryptobros on HN.

The Web3 ecosystem already has a standard called EIP712 for signing structured data. If you want to stick to standards, use that!

The secure enclaves all use P-256 (sometimes called R-256) while Bitcoin / Web3 uses K-256 (the Koeblitz curve, they distrust the NIST curve or whatever).

So that means you’re going to have to use Abstract Accounts and the new precompiled smart contracts to verify P256 signatures, which only Binance Smart Chain and a handful of other chains have deployed. Luckily BSC is the most widely used chain by volume and has plenty of money sloshing around so you can build your trustless programs there. If you want to be totally trustless — LET THE SMART CONTRACTS GENERATE THE CHALLENGE TO BE SIGNED BY THE AUTHENTICATOR. Then have it sign the temporary k256 public key (from the keypair) to use, as long as your session is open you can then add use your private key to sign transactions. As usual, do this for small amounts per day, transactions that move larger amounts should still require use of multisig keys etc.)