I've spent the last few posts in this series digging through SSH — keys, port forwarding, the whole authentication rabbit hole. Passkeys sit right next door to that conversation, and honestly, I've been putting off writing about them because "just use passkeys" felt like advice that needed more nuance than a tweet. So here's the nuance.
The short version: use passkeys everywhere they're supported. They kill password phishing stone dead, they fold your second factor into the same tap, and they log you in faster than you can type a password wrong twice.
# No command needed. Passkeys work through your browser/OS.
# Just tap your fingerprint or face when prompted.
That's the whole user experience. Everything below is why it works — and where it still falls short, especially if you're running Linux as your daily driver like I am.
What Are Passkeys, Actually?
A passkey is a cryptographic key pair standing in for your username and password. Instead of typing a secret you might reuse, forget, or hand over to a phishing page without realizing it, your device signs a challenge with a private key that never leaves the device. The server only ever sees the public key.
That's the whole trick, and it's the same trick SSH key auth has been using for decades — I keep coming back to this parallel because if you've already set up SSH keys, passkeys will feel familiar on day one.
What that buys you:
- Phishing-resistant — the credential is bound to a specific domain. Your browser won't hand a
github.compasskey to a lookalike site, full stop. - No shared secrets — a server breach only leaks public keys, which are useless to an attacker.
- Strong by default — you're not relying on humans to pick good passwords anymore.
- Faster — a biometric tap runs 2–5 seconds versus 9–14 seconds for typing a password.
The standards underneath
| Standard | Purpose |
|---|---|
| FIDO2 | The broader framework: WebAuthn (browser API) + CTAP (device communication) |
| WebAuthn | W3C browser API for public-key authentication |
| CTAP | Client-to-Authenticator Protocol — how the browser talks to hardware keys |
A quick update as of this writing (September 2026): WebAuthn Level 3 sat as a Candidate Recommendation Snapshot since May 26, 2026, and on July 20, 2026, W3C proposed advancing it to full Recommendation status — the last stage of the process. It's currently in Advisory Committee review. Worth noting: Level 3 doesn't add any new phishing resistance — that landed with Level 2 back in 2021. It mostly expands what a passkey can do under the hood (encryption key derivation, related-origin support, sync-list signaling). The spec formally recognizes "passkey" as the common name for these discoverable credentials, which is a nice bit of standards catching up to marketing.
How Passkeys Actually Work
Registration
- You visit a site and kick off passkey creation
- Browser prompts for biometric/PIN verification
- Device generates a public-private key pair
- Private key stays on-device (or syncs encrypted to a cloud fabric)
- Public key goes to the server, tied to your account
Authentication
- You visit the site and hit login
- Server sends a random challenge
- Browser finds the matching passkey for that domain
- You unlock with fingerprint/face/PIN
- Device signs the challenge with the private key
- Server verifies the signature against the stored public key
Why origin binding actually kills phishing
The browser enforces relying party scope at the protocol level. A passkey registered for github.com will never — not "shouldn't," never — get offered to githuh.com.
Real site: https://github.com → passkey offered ✓
Fake site: https://github-security.com → passkey hidden ✗
Compare that to passwords, where the entire defense rests on you eyeballing a URL bar correctly at 11pm after a long day. I don't love those odds for myself, let alone for an entire org.
Passkeys vs 2FA/MFA — They're Not the Same Category
This is where I see people get confused, including some sysadmins who should know better. Passkeys aren't "2FA but fancier." They replace both the password and the second factor in one cryptographic action.
| Dimension | Password Only | Password + MFA | Passkeys |
|---|---|---|---|
| Phishing resistance | None | Partial (SMS/TOTP can be relayed) | High (99%+ measured) |
| Login time | 9–14 sec | 22–45 sec | 2–5 sec |
| Credential stuffing | Vulnerable | Partially stopped | Eliminated |
| Server breach impact | Password hashes stolen | TOTP secrets at risk | Only public keys exposed |
| MFA fatigue / push bombing | N/A | Vulnerable | Not applicable |
| SIM swap risk | N/A | SMS vulnerable | Not applicable |
| NIST AAL ceiling | AAL1 only | AAL2 (AAL3 w/ hardware) | AAL2 default, AAL3 with device-bound |
Attack resistance, side by side
| Attack | Password Only | Password + SMS/TOTP | Password + Push | Passkey |
|---|---|---|---|---|
| Credential stuffing | Fails | Stops | Stops | Stops |
| Fake login page phishing | Fails | Fails | Partial | Stops |
| Adversary-in-the-middle proxy | Fails | Fails | Fails | Stops |
| SIM swap | N/A | Fails | Stops | Stops |
| MFA fatigue / prompt bombing | N/A | N/A | Fails | Stops |
| Server database breach | Fails | Partial | Partial | Stops |
| Malware on compromised device | Fails | Fails | Fails | Partial |
NIST SP 800-63B is blunt about this: passkeys qualify as phishing-resistant authentication, and SMS codes explicitly "SHALL NOT be considered phishing-resistant." That's about as close to a mic drop as a NIST document gets.
A passkey satisfies two factors in a single action — something you have (the device holding the private key) and something you are/know (the biometric or PIN that unlocks it). That's why it replaces 2FA rather than stacking on top of it.
OS Support: Where This Gets Uneven
Native platform support
| Platform | Minimum Version | Sync Provider | Native Biometric |
|---|---|---|---|
| Windows | 10 (limited), 11 22H2+ (full) | Windows Hello / MS Account | Face, Fingerprint, PIN |
| macOS | Ventura 13+ | iCloud Keychain | Face ID, Touch ID |
| iOS/iPadOS | 16+ | iCloud Keychain | Face ID, Touch ID |
| Android | 9+ | Google Password Manager | Fingerprint, Face, PIN |
| ChromeOS | 129+ | Google Password Manager | — |
| Linux | — | Third-party only | — |
See that last row? That's the whole reason I'm writing this post instead of just linking you to a vendor blog.
Browser support at a glance
| OS | Chrome | Edge | Firefox | Safari |
|---|---|---|---|---|
| Windows | ✓ | ✓ | ✓ | — |
| macOS | ✓ | ✓ | ✓ | ✓ |
| ChromeOS | ✓ | — | — | — |
| Linux | ✓ | ✓ | ✓ | — |
| iOS | ✓ | ✓ | ✓ | ✓ |
| Android | ✓ | ✓ | ✗ | — |
Windows specifics worth knowing
Windows 11 22H2+ gives you native passkey management: Windows Hello (PIN, fingerprint, or face) gates access, passkeys live in the device TPM, and cross-device auth works via QR code + Bluetooth. Edge 142+ can sync passkeys to Microsoft Password Manager across your Windows devices. Windows 11 24H2 also added a privacy consent prompt before passkey access — a small but sensible guardrail.
Windows 10 support is real but thin — you get browser-level WebAuthn without the OS-level management layer.
Apple's walled garden (in a good way, mostly)
iCloud Keychain handles sync across every Apple device, end-to-end encrypted — Apple genuinely can't read your passkeys. It requires iCloud Keychain plus 2FA on your Apple ID, and your iPhone can authenticate for your Mac via QR code + Bluetooth. Managed Apple Accounts support passkeys in enterprise setups too.
The catch: no Android, Windows, or Linux sync, beyond a limited Chrome extension. If your household or team spans ecosystems, plan for that friction.
Android
Google Password Manager syncs across Chrome and Android (9+ with Play Services 21+). Android 14+ lets you pick third-party passkey providers instead of being locked to Google's. Cross-device auth works the same QR-plus-Bluetooth dance as everyone else's implementation.
Linux: The Third-Party Reality
This is the section I actually care about writing, because it's the one every other "passkeys explained" post glosses over.
Linux has no native OS-level passkey support. No kernel or desktop-environment platform authenticator, no equivalent to Windows Hello or iCloud Keychain. WebAuthn itself works fine in Linux browsers — the gap is entirely in where the private key lives. There's a project called Passkeyd trying to fill that hole, but it's nowhere near mainstream yet.
Bitwarden — best for cross-platform sync
# Install the Bitwarden browser extension
# Chromium: https://bitwarden.com/download/
# Firefox: search "Bitwarden" in add-ons
# Enable passkey storage:
# 1. Open the Bitwarden extension
# 2. Settings → Security → Manage passkeys
# 3. Enable "Ask to save and use passkeys"
Current gotchas on Linux: the browser extension needs to be "popped out" into its own window to unlock with a passkey — a known Wayland bug, not a Bitwarden design choice. There's no native desktop-app passkey support yet either. Setup is otherwise straightforward: install the extension, log in, flip on passkey settings, and Bitwarden will offer itself as a storage option the next time a site prompts for one.
KeePassXC — best for offline/self-hosted purists
# Debian/Ubuntu
sudo apt install keepassxc-full
# Arch
sudo pacman -S keepassxc
# Fedora
sudo dnf install keepassxc
Setup: enable browser integration under Tools → Settings → Browser Integration, install the KeePassXC-Browser extension, turn on passkeys in the extension settings, and connect it to your database.
Two things worth flagging if you're already running KeePassXC: version 2.7.12 (released March 10, 2026) changed how the backup-eligibility (BE) and backup-state (BS) flags get stored for new passkeys — they now default to true instead of hardcoded false. The KeePassXC team's own release notes warn this may break existing passkeys created before the update, since those flags are treated as immutable once set. If you hit that after upgrading, their fix is to manually add two string attributes under "Advanced" on the affected entry: KPEX_PASSKEY_FLAG_BE=0 and KPEX_PASSKEY_FLAG_BS=0 to restore the old behavior. Also worth remembering: your database has to be unlocked for the passkey to work — no background daemon quietly handling it for you.
Bitwarden vs KeePassXC, head to head
| Feature | Bitwarden | KeePassXC |
|---|---|---|
| Cloud sync | Built-in, all devices | Manual (Syncthing, file sync, etc.) |
| Cost | Free tier available | Free, open-source |
| Offline | Requires internet | Fully offline |
| Cross-platform | Windows, macOS, Linux, iOS, Android | Windows, macOS, Linux |
| Server component | Cloud or self-hosted (Vaultwarden) | None |
| Passkey portability | Syncs across ecosystems | Local to database |
My honest take: if you're already self-hosting things the way I'm running Docker on VPS behind Caddy and Cloudflare, KeePassXC's "nothing leaves your machine unless you say so" model fits the philosophy. If you just want it to work across three devices without thinking about it, Bitwarden (or self-hosted Vaultwarden if you want the best of both) is the pragmatic pick.
Synced vs Device-Bound Passkeys — The Trade-Off Nobody Explains Well
Not all passkeys are created equal, and this distinction actually matters for how you think about security posture.
Synced
| Property | Detail |
|---|---|
| Private key storage | Exportable to a cloud sync fabric |
| Recovery | Platform account recovery (Apple/Google/Microsoft) |
| NIST AAL2 | Permitted |
| NIST AAL3 | Not permitted — key is exportable |
| Examples | iCloud Keychain, Google Password Manager, Bitwarden |
Device-bound
| Property | Detail |
|---|---|
| Private key storage | Never leaves the hardware |
| Recovery | None — lose the device, lose the credential |
| NIST AAL2 | Permitted |
| NIST AAL3 | Not excluded (with other requirements met) |
| Examples | Hardware security keys (YubiKey), Windows Hello device-bound |
Synced is recoverable but only as secure as the cloud account protecting it. Device-bound gives you the strongest assurance because the key physically can't leave, but you lose everything if the device dies without a backup registered elsewhere.
My recommendation, and the one I'm actually following: synced passkeys for daily convenience, and a device-bound hardware key registered on anything that really matters — admin panels, git hosting, your password manager itself. This is exactly the territory I'm heading into with the FIDO2/ed25519-sk hardware key post I teased in the SSH key generation article — same underlying tech, applied to SSH instead of the browser.
Getting Started, No Fluff
- Check your device — passkeys.dev/device-support will tell you if your OS + browser combo is covered.
- Enable a platform authenticator:
| Platform | How |
|---|---|
| Windows | Settings → Accounts → Sign-in options → Windows Hello |
| macOS | System Settings → Touch ID / Face ID |
| iOS | Settings → Face ID & Passcode |
| Android | Settings → Security → Biometrics |
| Linux | Install Bitwarden or KeePassXC (see above) |
- Create your first passkey on a site that actually supports it well — your Google Account, GitHub (Settings → Password and authentication → Passkeys), your Microsoft Account, or your password manager itself.
- Test cross-device if your phone and laptop live on different ecosystems: create the passkey on your phone, visit the same site on your laptop, choose "Use a different device," scan the QR code, and approve on your phone. You'll need Bluetooth on both ends.
Where This Still Falls Short
Provider lock-in is real, today, right now
FIDO's Credential Exchange Format (CXF) became a Proposed Standard back in August 2025 — it defines the data structure for moving passkeys between providers. The Credential Exchange Protocol (CXP), which would actually move the credentials, is still stuck at Working Draft. FIDO's own spec text is refreshingly honest about this: it says the draft is "not intended to be a basis for any implementations as the Specification may change."
Practically, that means you cannot cleanly move passkeys between Apple Keychain, Google Password Manager, and Bitwarden today. If you care about an account, expect to create separate passkeys per ecosystem until CXP actually ships.
Password fallback undercuts the whole point
As long as a site still offers password login as a fallback, you haven't actually eliminated the attack surface — you've just added a better option next to the bad one. The real win only lands once a site lets you delete your password entirely after setting up a passkey. Very few do that today; most keep the password around "just in case."
Edge cases worth knowing about
- Some browsers block passkey creation in incognito/private windows
- Shared computers don't play well with passkeys — no guest-account workaround
- Enterprise recovery flows need to avoid silently downgrading to weaker auth when someone loses a device
- Passkeys protect the login, not session theft after the fact — you still need short session lifetimes and proper token hygiene
The Verdict
| If you are... | Do this |
|---|---|
| Average user | Passkeys on Google, Apple, Microsoft accounts. Keep a password manager as backup. |
| Developer | Enable passkeys on GitHub, hosting providers, CI/CD accounts. |
| Sysadmin | Hardware security keys (device-bound) for admin accounts. Synced passkeys everywhere else. |
| Linux user | Install Bitwarden or KeePassXC, turn on browser extension passkey support, accept the extra friction for now. |
| Enterprise | Roll out passkeys for the workforce, keep TOTP/SMS as fallback for legacy systems that aren't ready. |
To be fair, passkeys do have their shortcomings, and it wouldn't be right to overlook them. Provider lock-in is still an open issue, cross-platform portability isn't quite where it needs to be, and Linux support remains somewhat behind — something I find a little frustrating each time I go through the setup. That said, the security improvement over passwords is genuinely significant — with 99%+ phishing resistance, no shared secrets at risk of being leaked, and credential stuffing effectively taken off the table.
Start with your most important accounts. Your Google, Apple, or Microsoft account is the best first passkey you'll ever create. Everything else follows from there.
The password era is ending. I'll see you on the other side — probably with a YubiKey in one hand and a KeePassXC database in the other.