Passkeys are an emerging authentication technology. Major sites including Google, GitHub and Ebay now support passkeys. In this post I will briefly explain what passkeys are, but I’ll focus on why you should support them … and some of the pitfalls.
Passwords are finished
Pretty much every developer and certainly every security practitioner recognises the limitations of the shared secret password model. We employ password policies to mitigate some of the risks, but even the most restrictive password policy can’t protect against a site against:
-
Phishing – It looks like your site but it isn’t
-
Credential Stuffing – Someone used the same username/password on another site that was compromised.
The Green Bar experiment
The industry has recognised the thread posed by phishing attacks for years. Today many people don’t even know a website address, relying instead on Google or links in emails/social media.
Even the EV/”Green Bar” experiment failed to protect users from fraudulent websites. In reality, we can’t rely on users to determine a website’s authenticity.
The security vs usability tradeoff
Users don’t like password policies. Even in an era of password managers, many users still choose to select their own passwords.
Rejecting a user’s choice might make sense from a security perspective, but from a usability/onboarding perspective it’s not great. We shouldn’t have to make a usability/security tradeoff in 2024.
Two factor authentication is a pain
Most operators recognise the problems associated with passwords and resort to secondary authentication. Typically this takes the form of SMS codes or TOTP (Google Authenticator) one-time codes.
However, multi factor authentication adds yet more friction to the signup and login process. It’s also not as secure as often perceived.
Whilst one time codes make phishing attacks harder, a spoofed site can simply prompt the user to enter their code, then proxy it onto the target site in realtime. Even a “script kiddie” can do this stuff.
Passkeys to the rescue
Today many users rely on password managers to store their passwords. The industry recognised that since we’re now using our devices to remember passwords, it’s time to revisit the whole concept of web authentication.
We no longer need to generate keys that can be remembered by users, in fact we don’t even need to constrain ourselves to symmetric (shared secret) keys anymore. We can use computer generated asymmetric key pairs in place of passwords. That’s basically what a passkey is.
Passkeys are an evolution of the Web Authentication API, an API that allows people to use “authenticators” (e.g. YubiKeys) with their browsers.
Passkeys extend the concept of an “authenticator” to the device itself (smartphone, desktop browser etc.) So there’s no need for an external device.
Client side certificates
Passkeys use a public/private key pair. The server sends a challenge, the browser/device signs the challenge with a private key and the server verifies it with the corresponding public key.
This is a vast improvement over the shared secret password model. Third party breaches are a thing of the past – private keys are never shared with websites so they can’t be hacked.
Passkeys are more than client side certificates. They’re associated with user accounts, not devices and a user can have multiple passkeys for a single website.
Frictionless strong authentication
Not only are passkeys far more secure than passwords, they’re also much easier to use. The browser simply creates a key pair. The public key is uploaded to the target website. No more “Password must be N characters or longer” or “You previously used that password” nonsense.
Authentication is equally smooth. The user clicks a button, the browser asks them if they want to log in and that’s it. They may need to look at the device (Face ID) or provide their fingerprint, but it’s still much quicker than copying one time codes.
Biometric authentication
Passkeys support a feature known as user verification. Essentially developers can ask a device to locally re-authenticate the user before signing with a passkey. Whilst the passkey standards don’t require biometric verification, most devices use facial or fingerprint recognition to authenticate the user.
Phishing resistance
It doesn’t matter if two sites look identical, the browser simply won’t allow a passkey created for example.com to be used on exxample.com.
This is the major advantage passkeys have over passwords. It’s the device that decides whether to “enter” a passkey on a site, not the user.
Browser support
Most browsers now support passkeys, although support for some advanced capabilities remains limited.
Drawbacks and pitfalls
As I’ve been evangelising about passkeys, it’s only fair to highlight some of the drawbacks. Some of these issues are being addressed by the W3C and FIDO working groups but this is the state of play as of April 2024…
-
User awareness – Most people haven’t heard of passkeys. If you’re target audience is tech savvy you’ll have few issues, but other users will need some education and persuasion.
-
Browser support – Most browsers now support passkeys, but if you need to support “legacy” browsers passkeys won’t be an option.
-
Javascript – Users must have javascript enabled, as the underlying APIs can only be accessed using script.
-
Browser quirks – Like any new technology, passkeys are not without bugs. I’ve run into countless bugs and quirks. Fortunately, things are improving.
-
Same site restrictions – Passkeys can only be used on the host/domain for which they were created. However, this phishing protection is a double edged sword…
Same site restrictions
The same site restriction works similarly to cookie same origin policies. A passkey created for example.com can be used on en.example.com and de.example.com, but en.example.com can’t be used on de.example.com.
The problem arises when we want to change domains. Whilst we can redirect users (and search engines) from old.com to new.com, the old.com passkey won’t work on new.com.
This is a major issue and it is being addressed by the standards bodies. In the meantime there are a couple of workarounds that can be applied.
Same site workarounds
Firstly we can authenticate a user on old.com then redirect them to new.com. Of course we can’t set a cookie, but a JWT would work well in this scenario.
Once authenticated we can then prompt the user to create a new passkey for new.com so they can sign in directly in future.
We can also adopt a process similar to the reset password flow. Assuming we have the user’s email address (and trust their mailbox security) we can email a secure “create passkey” link to new.com.
Adopting passkeys
I hope I’ve persuaded you to at least evaluate passkeys. If you’re looking for a quick start guide please see my Supporting passkeys in 2024 post here on dev.to and do let me know if you have any questions. Thanks for reading!