Building Passkey Authentication Into My Own Admin Panel
I deployed FIDO2/WebAuthn passkey authentication on my portfolio admin panel. This post explores why usability matters more than security checkboxes—and what I learned building it for real.
The Problem With Most MFA Advice
"Enable multi-factor authentication. It's more secure."
True. Also useless if people disable it after a week.
I've been working in IT infrastructure for twenty years. I've watched this cycle a thousand times: deploy a security measure that's technically sound, then watch users route around it because the friction is unbearable. SMS codes that never arrive. TOTP seeds lost in a phone backup. Security keys locked in a drawer.
For my MSc research at the University of York, I'm studying whether people will actually keep using three MFA methods: TOTP, FIDO2 security keys, and SMS OTP. The research question sounds academic until you realize the implication: the most secure system means nothing if people disable it.
So I stopped theorizing and built it.
The Implementation: Passkeys on My Portfolio Admin
My portfolio admin panel (jaynguyen.fyi/admin) now runs entirely on passkey authentication. No passwords. No codes. Just biometric + a security key bound to the device you own.
Here's what that means in practice:
What's Live
- Registration: Users can register FIDO2 security keys or platform authenticators (Face ID, Touch ID, Windows Hello)
- Login: No email typed first, no password prompt. Tap the key or use biometric, and you're in.
- Recovery: Signed recovery codes stored offline, single-use, generated at registration
- Threat Detection: Signature counter on every key to detect cloned authenticators
Why Passkeys
FIDO2/WebAuthn solves the three problems that sink other MFA:
- No phishing vector. A passkey is bound to the domain—registered on
jaynguyen.fyiwill not authenticate on a lookalike. OAuth can't claim that. - Friction collapses. Biometric on your phone is faster than typing a password. The security measure becomes easier than the insecure alternative.
- Recovery doesn't break you. Unlike TOTP seeds, a passkey doesn't expire. Lose the device? Use the recovery code. But—and this is critical—you need to have registered that code before you lose the device.
The Research Insight
Building this for real—not in a lab, but in production handling actual admin sessions—changed how I think about the usability research.
The usability question isn't "does this work?" It's "will people prefer this over the alternative?"
With SMS OTP, people prefer it because it's familiar. With TOTP, people tolerate it because the alternative is no MFA. With passkeys, people want to use it because it's faster and easier than passwords.
That's the difference between a security measure people enable and one they keep.
How It Works (Technical)
Tech stack:
@simplewebauthn/server + @simplewebauthn/browser 13.3.2
Payload CMS auth strategy (custom)
Neon Postgres for passkey storageSigned session cookies + counter-based cloned-key detection
Flow:
- User registers a passkey with their device
@simplewebauthn/browsercreates the credential- Public key + counter stored in Postgres
- On login, server challenges with a random value
- Device signs the challenge with the private key (never transmitted)
- Server verifies signature + counter
- Session cookie issued
Why this matters: The server never sees the private key. The device proves possession without exposing it.
The Honest Gaps
Building this as a solo project on weekends exposed limitations the research papers gloss over:
Recovery is harder than authentication. I generate recovery codes at registration. If you lose both authenticators before you've used (or stored) the recovery code, you're locked out. This is a feature, not a bug—but it means you need discipline.
Not all devices implement it the same. iPhone biometric works seamlessly. Windows Hello has permission gates. Security keys need to be bought ($30+). The UX delta is real.
User testing changes everything. My implementation works for me. It might not work for a support team handling password resets at scale. The architecture is sound; the deployment context matters.
Why I Built This
Three reasons:
- Research. For the dissertation, I need real data on whether people will actually keep using passkeys. A deployed system that handles my own access generates better data than a prototype.
- Portfolio credibility. I can now say "I've shipped FIDO2 in production" instead of "I've read about FIDO2." Recruiters know the difference.
- The problem is real. Twenty years in IT taught me that security and usability are usually in tension. Passkeys are one of the few cases where they're aligned. That's worth proving works at scale.
What Comes Next
The research phase: I'll be running both passkey and password authentication for the next few months, collecting usability data as I use each method. The MSc dissertation will publish results by January 2027.
In the meantime, the admin panel works. It's fast. It's verifiable. And it proves that the most secure method doesn't have to be the most painful one.
The Real Takeaway
If you're deploying MFA, ask the usability question before the security one: Will your team actually keep using this?
If the answer is no, it doesn't matter how secure it is.
Questions? Reach out—I'm always happy to talk security, infrastructure, or why this matters.
Research platform: University of York MSc Computer Science with Cyber Security | Live implementation: jaynguyen.fyi/admin