C.W.K.
Stream
Lesson 02 of 05 · published

Passkeys — The Real Replacement For Passwords (Mostly)

~15 min · passkeys, webauthn, phishing-resistant

Level 0Greenhorn
0 XP0/53 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

Passkeys (WebAuthn / FIDO2) are the closest the industry has gotten to "no more passwords". They're phishing-resistant, device-bound or synced, and work on every modern OS and browser.

What a passkey actually is

A keypair stored in your device's secure enclave (TouchID, Windows Hello, Android keystore) or your password manager (1Password, iCloud Keychain, Google). The server stores only the public key. Login = the device proves possession of the private key by signing a challenge — no shared secret to phish, no password to leak.

Why it beats PIN for multi-device, multi-user

PropertyPIN (Track 5)Passkey
Can be phishedYes (typed into a fake page)No (origin-bound by browser)
Brute-forceable10,000 combos for 4 digitsCryptographic key, not feasible
Per-user identityNo (shared PIN model)Yes (each device = its own credential)
Cross-device syncManual (you'd have to share)Native via iCloud / Google / 1Password
Setup complexity5 minutes20–60 minutes (server-side WebAuthn)
RecoveryRecovery token from Track 6Account recovery flow + backup passkey

The honest trade-offs

  • Recovery is harder. Lose all your passkey-holding devices = harder to get back in. Always register at least two: e.g., laptop + phone, or a hardware key as backup.
  • Server complexity is real. WebAuthn ceremonies have edge cases (user verification flags, AAGUIDs, attestation). Use a library; don't roll it from spec.
  • Old browsers / corporate restrictions still happen. Have a fallback (PIN, email magic link) for now.

Code

Passkey registration & authentication, conceptually·python
# Registration (one-time per device)
options = generate_registration_options(
    rp_id="myapp.example.com",
    rp_name="My App",
    user_id=user.id,
    user_name=user.email,
)
# Send options to browser → navigator.credentials.create(options)
# Browser returns a credential → verify and store credential.public_key

# Authentication
options = generate_authentication_options(rp_id="myapp.example.com")
# Send to browser → navigator.credentials.get(options)
# Browser returns assertion → verify against stored public_key
# On success → issue session cookie (same model as Track 5)

External links

Exercise

Register a passkey on github.com if you haven't (Settings → Password and authentication → Passkeys). Notice: it just works on TouchID / Windows Hello / your phone — no typing. Now you've felt the UX. If you ever build multi-user, this is the auth users will expect.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.