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.com passkey 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

  1. You visit a site and kick off passkey creation
  2. Browser prompts for biometric/PIN verification
  3. Device generates a public-private key pair
  4. Private key stays on-device (or syncs encrypted to a cloud fabric)
  5. Public key goes to the server, tied to your account

Authentication

  1. You visit the site and hit login
  2. Server sends a random challenge
  3. Browser finds the matching passkey for that domain
  4. You unlock with fingerprint/face/PIN
  5. Device signs the challenge with the private key
  6. 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

  1. Check your devicepasskeys.dev/device-support will tell you if your OS + browser combo is covered.
  2. 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)
  1. 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.
  2. 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.