Passkey Authentication - Planning and Implementation
Overview
I recently integrated passkey support into my cookbook app. Join me as I walk you through the planning and implementation process I used to integrate this cutting-edge authentication technology!
What are Passkeys?
Passkeys are a user-friendly name for WebAuthn/FIDO2 credentials! Is that helpful? Anyway, they are digital signatures based on public key cryptography and a second factor like biometrics (face, fingerprint) or a secret (PIN, pattern). Check out this helpful Wikipedia article for more.
Why Passkeys?
Passkeys have a multitude of advantages. Here are some of my favorite benefits. :)
As a user:
- Easier and faster
- No need to think of a password when signing up
- No need to remember and type a password when signing in
- Improved security - verification is handled by the device, providing phishing protection
As a developer / admin:
- Improved user authentication experience
- Minimizes time and effort spent dealing with phishing activity
- Reduces value of credential data as a target (i.e. data breach)
Passkey Planning
To plan for passkey implementation, I listed the existing authentication scenarios for my application. Then, I added scenarios for passkeys. Notice that some scenarios are shared and can use passwords or passkeys, while other scenarios are specific to a particular authentication mechanism.
Authentication Scenarios - Passwords
Scenario | New or Existing User | Authenticated |
---|---|---|
Sign up | New | No |
Sign in | Existing | No |
Change Password | Existing | Yes |
Account Recovery | Existing | No |
Authentication Scenarios - Passwords and Passkeys
Scenario | Mechanism | New or Existing User | Authenticated |
---|---|---|---|
Sign up | Password / Passkey | New | No |
Sign in | Password / Passkey | Existing | No |
Change Password | Password | Existing | Yes |
Create New Passkey | Passkey | Existing | Yes |
Edit Passkey Label | Passkey | Existing | Yes |
Delete Passkey | Passkey | Existing | Yes |
Account Recovery | Magic Link | Existing | No |
My goal for this effort was to add passkey support while retaining password capabilities for existing users (and as a fallback). I'm not going for a fully passwordless app ... yet! To support the transition from passwords to passkeys both authentication mechanisms are available for sign up and sign in. Users can then set up and manage either mechanism from their account page.
Implementation Items
Let's go over the changes required to support passkeys in my app using MongoDB, Node, and Vue. This is a high-level overview, along with some details for my specific case. I utilized libraries from SimpleWebAuthn; the general principles apply regardless of the technology or library you use. (Pick something with good docs and read them thoroughly!)
Storage: MongoDB
A new data model was created following the guidance here. My schema ended up closely following the example. I would, however, like to draw your attention to the following important comment:
// Caution: Node ORM's may map this to a Buffer on retrieval
// Convert to Uint8Array as necessary
So if you are using an ORM for Node, let's say as an example.. mongoose, be sure to handle that conversion to a Uint8Array!
// Format the passkey public key as a Uint8Array
// SimpleWebAuthn expects a Uint8Array for the public key
;
API: Node
New routes were required for the passkey scenarios I outlined above. Again, I will spare you the implementation details, but here are the routes for reference and inspiration:
Sign up with Passkey
Method | Endpoint | Description |
---|---|---|
POST | /api/auth/sign-up/webauthn/begin | Start sign up using passkey |
POST | /api/auth/sign-up/webauthn/finish | Complete sign up using passkey |
Sign in with Passkey
Method | Endpoint | Description |
---|---|---|
POST | /api/auth/sign-in/webauthn/begin | Start sign in using passkey |
POST | /api/auth/sign-in/webauthn/finish | Complete sign in using passkey |
Passkey Management
Method | Endpoint | Description |
---|---|---|
GET | /api/auth/manage/webauthn | Get user's passkeys |
POST | /api/auth/manage/webauthn/register/begin | Start passkey registration for authenticated user |
POST | /api/auth/manage/webauthn/register/finish | Complete passkey registration for authenticated user |
DELETE | /api/auth/manage/webauthn/:id | Delete a passkey |
PUT | /api/auth/manage/webauthn/:id/name | Rename a passkey |
UI: Vue
UI updates were required to handle passkey scenarios! A screenshot with a caption paints a thousand words:
Sign up
Add a section and help text for sign up using a passkey:
Sign in
Add a button for sign in using a passkey:
Account Management
Create new passkey management section for the following:
- View existing passkeys
- Register new passkeys
- Rename and delete passkeys
Future Enhancements
This project gave me a solid foundation for working with passkeys as a developer. As passkeys become more widely adopted, consider implementing them in your own projects to enhance security and user experience. Stay tuned for more updates as I continue to explore this technology further - perhaps going fully passwordless is in the future!
Additional resources
To learn more, please see these resources that helped me understand and implement passkeys: