Things I learnt about passkeys when building passkeybot
16 comments
·December 22, 2025BoppreH
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.
ChrisMarshallNY
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/
xg15
> 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.
ajross
Yes, where practical. Though recognize that by their very nature web apps aren't part of the trust network. The browser and security stack can make a key for them to use, but it's not possible to be sure that the user of that key is not subject to attack at the backend (or even front end, really the best you can do there is XSS protection, which is hardly at the standard of "crytographically secure").
And likewise you as the app vendor can know the key was generated, and that it works, but you can't[1] know that it's actually locked to a device or that it's non-exportable. You could be running in a virtualized environment that logged everything.
Basically it's not really that useful. Which is sort of true for security hardware in general. It's great for the stuff the device vendors have wired up (which amounts to "secured boot", "identifying specific known devices" and "validating human user biometrics on a secured device"), but not really extensible in the way you'd want it to be.
[1] Within the bounds of this particular API, anyway. There may be some form of vendor signing you can use to e.g. verify that it was done on iOS or ChromeOS or some other fully-secured platform. I honestly don't know.
loloquwowndueo
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.
gear54rus
It's absolutely hilarious that someone would think that this passes for API docs nowdays. Still it's good to know what to avoid on the very first glance.
the_mitsuhiko
I think it's good. Quite frankly, it's the better experience to be given the right prompts to onboard into something than having to guess that the inputs are the right for the LLM.
jiggawatts
It's also a bit of a "bootstrapping" issue. How does anyone expect the AIs to learn to do things correctly if the instructions are not published for them to pick up during training?
This is like those "contact your system admin" error messages. I am the system admin!
tptacek
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.
boombapoom
i wish passkeys could replace passwords, not suppliment them
spockz
Why? Passwords can be remembered and entered on other devices for recovery. The plethora of passkeys out there cannot.
A bit the same why although I love the keychain in macOS, it also makes me uncomfortable. Lose your phone and laptop in a theft or fire and you are locked out from your Apple account. Goodbye online presence.
AlotOfReading
The "standard" answer is that you should either use synced passkeys, or enroll multiple passkeys with the provider. The problem is that some providers (e.g. Paypal, some banks) only support one passkey, and synced passkeys aren't supposed to be trusted for attestation (unless they're synced by Apple/Google/Microsoft).
wkat4242
That's exactly the issue I have with passkeys. All that lockin to big tech. I tried bit warden but most sites with passkeys didn't work with it (like Amazon and PayPal). And on android it only wants to use the Google version (I don't use a Google account on my phone so that's not possible).
AlotOfReading
And I wish passkeys could cover all the use cases of passwords, yet here we are. Passwords are simple and well understood. Passkeys have all sorts of sharp edges that you won't discover until you're hurt by them.
null
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?