Things I Learnt About Passkeys When Building Passkeybot
Key topics
The world of passkeys just got a whole lot more interesting, thanks to the "lessons learned" from building passkeybot, a tool that's got everyone talking about the pros and cons of relying on large language models (LLMs) for authentication code. While some commenters praised the innovative approach, others were left scratching their heads at the "API docs" – essentially, a prompt to feed example code into an LLM. As the debate raged on, it became clear that there's a bootstrapping issue at play: can we trust LLMs to get authentication right if the instructions are lacking, and are humans diligently checking the generated code? The author clarified that LLMs were only meant to translate example code into different languages and frameworks, but the discussion highlighted the risks of over-reliance on AI-generated code, with some warning that it could lead to sloppy authentication practices.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
1h
Peak period
80
0-12h
Avg / period
20.3
Based on 142 loaded comments
Key moments
- 01Story posted
Dec 22, 2025 at 1:58 PM EST
12 days ago
Step 01 - 02First comment
Dec 22, 2025 at 3:27 PM EST
1h after posting
Step 02 - 03Peak activity
80 comments in 0-12h
Hottest window of the conversation
Step 03 - 04Latest activity
Dec 27, 2025 at 4:24 PM EST
6d ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
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.
"Hey chat bot friendo, where's the nearest hand-written 'help wanted' sign in the door of a coffee shop? I need a new career path"
This is like those "contact your system admin" error messages. I am the system admin!
The LLM is only for converting the JS based example code into your language X and HTTP framework Y (instead of giving example code for every combination of X and Y).
The standard implementation is in a single file `http_server.ts`, which is around 200 lines of well commented code, with important logic commented. The repo also contains a sequence diagram [1] and a live demo [2] where you can see the request/responses.
- [1] https://github.com/emadda/passkeybot/tree/master?tab=readme-...
- [2] https://demo.enzom.dev/
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.
Amazon, PayPal work just fine on my 3rd party 1Password extension. And it works just fine on Android as a default passkey provider as well.
I use Bitwarden, I use Android, I use Firefox on Linux. Passkeys work just perfectly fine on all of the sites listed here thus far.
I do believe you need Android 14 for that, though, so if your phone has been abandoned by its manufacturer/your ROM of choice, it'll break.
If Bitwarden is bugged out on your computer/phone for whatever reason, there are also alternatives like 1Password.
Is it possible now to export the passkey private key though? That was another thing at the time, apparently the fido consortium didn't want keys to be exportable.
But I'll try it again, good point. I think with paypal the issue was also that they refuse passkeys in firefox and I don't use chrome so I was stuck there too. With Amazon it tried to enroll me but I got a bunch of errors.
So then the follow-up suggestion is to use credential exchange. That's not actually a solution, but by the time you explain that to the passkey proponents they've usually stopped listening.
Session cookies can't be phished either, so why aren't those sufficient?
[1] https://passkeys.dev/docs/reference/known-issues/
Still, I've never seen a website try to block Bitwarden's passkey management (though I've had plenty of issues because of its partial implementation of the API, especially in early versions) despite its spec violations.
For some of the implementations, user verification is a massive pain (as browser extensions often only have long and complicated passwords to authenticate) but for KeepassXC a quick and simple fingerprint/facial scan is an option, as it already offers integration into the native OS biometrics anyway.
Ideally it shouldn't be possible, or at least it should clearly be an ugly hack for a website to be doing something like this. Instead the spec authors explicitly endorse blocking clients that they feel are non-compliant. I'm not going to use a login spec that encourages websites to ban me because of the software I choose to use.
> for KeepassXC a quick and simple fingerprint/facial scan is an option, as it already offers integration into the native OS biometrics anyway.
Man don't get me started on the passkey environment's bizarre obsession with biometrics. My desktop computer doesn't have a fingerprint reader or a camera, and if my OS (Arch Linux) supports that junk I've certainly got no interest in doing the work to set it up just so I can log in to a website.
Passwords don't have any of these problems.
Is that "cannot be extracted" from JavaScript 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 it to the current device.
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.
the capability is there, but it would he massively inconvenient, since it requires a lot of lockdown
might be the next generation of anti-cheats though
There's no direct remote attestation implementation for passkeys yet, but remote attestation for web browsers has been around for a few years now.
May it always remain niche.
A world in which open source browsers are unusable for most people and new entries to the browser market are all but impossible sounds terrible.
GrapheneOS supports attestation. GrapheneOS even provides the sort of security guarantees that would make risk management types at banks happy, but it isn't popular enough for them to be motivated to support it as an attestation target.
Now imagine it was practical for websites to require attestation from browsers. How likely do you think it that all the major services would accept anything other than Chrome, Safari, and Edge?
The code_challenge == sha256(code_verifier). You will share the code_challenge at the start of the flow.
The code
I run an authentication server and requiring PKCE allows me to make sure that XSS protection is handled for all clients.
Of course if you trust the client (no bad browser extensions, updated browser) and have good TLS settings and no MITM risk and make sure the your IDs are single-use then it seems like that should be fine.
[1] https://www.smokingonabike.com/2025/01/04/passkey-marketing-...
[2] https://fy.blackhats.net.au/blog/2024-04-26-passkeys-a-shatt...
But the existence of attestation means Apple could at any time in the future make attestation on by default and suddenly our devices control our secrets more than we do.
I personally think the ability to export+import passkeys is a good thing from a backup point of view, but he's not wrong in suggesting that companies actually using the high security features of passkeys will eventually block software implementations like these.
This isn't about vendor lock-in. Nobody is asking for KeepassXC to remove passkey support. This is about security software implementing an API and not fulfilling the expectations that come with such an implementation. To quote the comment you linked:
> That's fine. Let determined people do that, but don't make it easy for a user to be tricked into handing over all of their credentials in clear text.
> personally think the ability to export+import passkeys is a good thing from a backup point of view
It's not a "good thing," it's absolutely critical. If I can't back up my credentials in a location that I trust, then it's not an acceptable login method. What happens if my PC goes down and I couldn't export my data? I just can't log in anywhere? KeePassXC lets me do that, but the spec authors think it's appropriate to ban me for using it because it lets me manage my own data. That's bonkers.
> What happens if my PC goes down and I couldn't export my data? I just can't log in anywhere?
Then you follow the procedure you would follow for when you'd forget your password. Probably a password reset through email, maybe calling customer support. Or if you have it set up, you could use the passkey set up on your phone or Yubikey or whatever to log in and create a new password on your new PC.
Passkeys aren't passwords, that's the whole point. It's modelled after the "something you have" factor, not "something you know". If you're finding workarounds to violate the security design, you're not gaining any advantage by using passkeys. Just use a password if you want to use a password.
The trouble is, if websites are allowed/encouraged to ban clients, then the advantages you're talking about come with the downside of hard-tying yourself to one of 3 US-based Big Tech companies, because those will be the only ones who will ship clients declared "secure." That's not a trade-off I'm willing to make for something as critical as my service logins. You can already see this happening, almost every article talking about passkeys assumes you're logging in with an Apple, Google, or Microsoft device.
> Then you follow the procedure you would follow for when you'd forget your password. Probably a password reset through email, maybe calling customer support.
This is a downgrade from passwords (and exportable passkeys), where I can just restore it from a backup.
> Just use a password if you want to use a password.
Yeah, that's what I plan to keep doing, unfortunately. What I'm worried about is a password-less future where that's no longer an option and we all have to submit to using one of Android, iOS, or Windows to log in to everything because those are the only clients that can be trusted(TM) to handle the user's data as the big tech companies and governments desire it to be handled.
Remote attestation is evil.
The threat he relayed was more serious than the threat he made. But it is a threat when a person with influence suggests they may support a punishment.
> If you promise to store a key in a non-exportable format
There was no such promise. The people who wish Passkeys to replace passwords did not demand it yet even.
The specification states otherwise: https://www.w3.org/TR/webauthn-2/
MFA is more secure: you combine multiple factors of authentication. You could do password + passkey, password + TOTP token (assuming such tokens are not exportable either), password + biometrics, passkey + biometrics, even TOTP + biometrics would be MFA.
I don't think anyone proposes replacing MFA with passkeys, most proponents are proposing replacing passwords with passkeys.
A second question is "is MFA still necessary when using passkeys", as passkeys are generally more secure than the Welcome1234! type passwords most people use. I'd argue that for quite a few non-critical services, it wouldn't be. More and more services have started requiring 2FA because the damage of accepting passwords alone was too great, and with passkeys I don't believe the same damage would occur.
It'd still be a good to offer the option. In fact, I think passwords should be offered as a second option; combining passkeys with something like TOTP would be close to useless as the same thing you use to validate the passkey probably also generates the TOTP codes.
Amazon actually does MFA with passkeys: you can log in with a passkey but it'll still ask you for a TOTP code. I'd rather combine password and passkey, but at least they're not completely turning off the additional layer of security.
1) that they're enforcing these specs for technical reasons, not because they want vendor lock-in
2) a result of these decisions in the long term is vendor lock-in
No, that is absolutely not the point. The points of using pub/priv keys for asymmetric auth instead of passwords (symmetric, manually generated auth) are:
- Server-side (ie, central point) hacks no longer matter an iota from a user auth pov. No more having to worry about reuse anywhere else, about going around changing passwords, nada, because the server simply doesn't have anything that can be used for auth anymore at all. No more concerns about whether they're storing it with the right hash functions or whatever, they could publish all the public keys in plain text and it'd be irrelevant. This fantastically changes the economics of attacks, since now instead of hacking one place and getting thousands/millions/hundreds of millions of credentials you'd have to hack every single separate client.
- As a practical matter, the process means eliminating the whole ancient hodgepodge of password requirements (often outright anti-security) and bad practices and manual generation work. Everything gets standardized on something that will always be random, unique, and secure.
And that should be it. That's the point and the value, always was. The only goal should be to put a nice UX and universal standard around. But of course, modern enshittified tech being enshittified, they had to shove in a bunch of stupid fucking bullshit garbage like what you're talking about.
My apologies to GP if it came across as too personally aggro, I did mention the corps and their walled gardens to try to be clear on the focus, but the situation does really make me absolutely furious and also truly sad. This should have been such a simple, universal win/win/win that made everything better for everyone. But as you say:
>and so strongly supported by the spec authors and the passkey community, that it's hard to see it as unintentional. It completely poisons the technology, and that sucks because I really do want to use it.
Yeah, 110%. I'm one of the very few who actually tried to use certificates for web authentication back in the 00s, and it did work pretty darn well surprisingly! There were even a few commercial web services that tried it out like the now defunct StartSSL. It was just the whole flow around it was too clunky for regular people and needed some additional standardization and polish. If only the right catalyst had happened to make it a priority in the 2000s it might well have been done in a lasting good way that'd then be too sticky and entrenched to fuck with now. It's depressing to see it being hijacked and poisoned like it has been :(.
I think we're verrry slowly inching toward shedding all the security nerd self-indulgences and getting to what I think is the eventual endgame which PassKeys are just keys and ultimately a fairly user friendly way of getting people to use a password manager without it feeling like one. All the other features seem like noise.
As stated by the spec authors on KeePassXC's bug tracker, open source software may be modified by the user, so cannot be trusted. The passkey proposal is for all of your keys to be managed by proprietary software validated by your phone or your computer's TPM module. That means one of three big, US-based tech companies will control all of the world's login data. Those 3 companies are all currently involved in the largest fascist-taint-tongue-polishing in US history, and we want to hand them control over the world's logins. That's a much, much bigger risk than some users doing something stupid.
I love passkeys, but they're still kinda hard to use. There's several sites that wont let you enroll multiple ones and it's easy for systems to step on each other like the aforementioned experience.
The problem is fallback. All my banking apps have SMS OTP fallbacks and that's no better than having only SMS OTP. If you're building these systems make sure you have good fallbacks. What matters in design is not so much how well it works when things go right but how well it works when things go wrong. With security you really cannot ignore edge cases
The easier it is to do things, like use another channel, the harder it is to keep secure.
The easier it is to keep secure, the harder it is to use.
Apple wants you to use iCloud passkeys, Microsoft wants you to use Microsoft Account passkeys, Google wants you to use Google passkeys. Even if you have a dedicated USB device plugged in, browsers keep defaulting to the cloud accounts.
Bitwarden's approach is to simply hijack the passkey request before the browser can respond and throw itself front and center. It's a terrible hack but it works on every browser at the very least.
If these companies cared about their users more than they cared about throwing up walled gardens, they wouldn't put a USB key behind "Choose another method" -> "Dedicated device" -> "Security key" -> "Confirm" while offering one-click login with their cloud account. And they would offer a proper API for third party applications to integrate into the native passkey storage.
Every login was the same: fails -> try again or try different method -> list of methods (including "security key") -> ok -> tap security key -> ok
It would not let me set the key as the default and there were two unnecessary clicks. The box literally only had a single button (besides the standard x on the window)! It was absolutely infuriating.
I'm with you. I don't believe these companies are actually trying to create the best solutions. And you can absolutely see that when you try to move from one ecosystem to another.
Look at my problem again and now consider had I been using my iCloud key and wanted to login from my Linux machine. It literally wouldn't be possible!
I've resigned to registering a passkey into all of my providers and just letting the most platform native option win for now.
In practice we don't actually want the best security though. We frequently make concessions. I mean with my bank I don't want "the best" security. If I lose my credentials I don't want to go broke. If my credentials get hacked (especially if hacked by no fault of my own!) I want that money recovered. These things would not be possible with "the best" security.
In fact, in a different interpretation I would call those paths less secure. Ability to recover is a security feature just as much as it's not.
Both security and privacy do not have unique all encompassing solutions. They are dependent upon the threat model.
Importantly when designing things you have to understand modes of failure. When you design a bridge you design it to fail in certain ways because when/if it fails you want it to do so in the safest possible way. Why does this pattern of thinking not also apply here? It seems just as critical here! In physical security you also have to design things for both fail open and fail closed. You don't want you always fail close, doing so gets people killed! So why is the thinking different in software?
In terms of security, yes. But not in terms of convenience.
[1] https://developer.chrome.com/blog/digital-credentials-api-sh...
https://www.gov.uk/eta
I also uploaded my passport to Delta to make traveling to both Costa Rica and London faster this year.
https://www.delta.com/us/en/travel-planning-center/know-befo...
I've never seen a legitimate use case where I need to prove my identity to use a website.
Overall it’s not terrible but I think these edge cases are going to keep biting people and need to be addressed in some way. And yes I understand that I could use a Yubikey or Bitwarden or some such but the point was that I wanted to see how this flow works for “normal” users who just use the iCloud Keychain and the experience leaves something to be desired.
The messed up thing is that the simplest backup option is a magic login link which is obviously less secure. Also you cannot sink a passkey between platforms unless you use a third party Authenticator so you have to have a backup method of some sort even if not for recovery reasons.
This is why I strongly prefer to not use OSX passkeys. How the fuck am I supposed to login on my nix machines if you only allow me to enroll one passkey?!
But FWIW, I have the least friction with Linux. But that's more that Windows and Apple have their walled gardens and that's where the friction comes from, though in different ways.
Example: this article.
I've decided to stop adding new ones. I'll just OTP 2FA. It's simple, reliable, and I can keep it in Bitwarden safely.
Safari on iOS can store and use passkeys from any app that implements the right system API, including the default Apple Passwords but also Bitwarden and Chrome.
For desktop, you can either use a browser extension provided by some password managers (such as Bitwarden), or if you're on a Mac, Safari and Chrome can access passkeys from other apps similarly to on iOS (but not as many providers support this API on Mac as on iOS, and in particular Bitwarden doesn't, so you'd have to use the extension for that).
I'm curious on why there would be any legitimate reason for that. Security wise it should not happen, it's just some implementations being crappy or some bad practice like reusing same passkey with different devices ?
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.
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.)
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/