Passkeys are a new authentication standard backed by Apple, Google, and Microsoft that aims to replace passwords entirely. Built on the same FIDO2/WebAuthn cryptographic foundation as hardware security keys, passkeys provide phishing-resistant authentication without requiring a separate physical device. Major platforms — including Google, Apple, GitHub, and PayPal — already support them. This guide explains how they work and how to start using them today.
What Is a Passkey?
# Passkey = private/public key pair stored on your device
# Private key: stored in device's secure enclave (never leaves the device)
# Public key: stored with the website
# Unlike passwords:
# - Nothing to remember
# - Nothing to type
# - Nothing that can be phished (cryptographically domain-bound)
# - Nothing that can be leaked from a server breach (only public key stored)
# Authentication flow:
# 1. Website sends challenge
# 2. Device prompts for biometric (Face ID, fingerprint) or PIN
# 3. Device signs challenge with private key
# 4. Website verifies signature with stored public key
# 5. User authenticated - no password involved
Passkeys vs Passwords vs Security Keys
# Comparison:
Feature Password Security Key Passkey
Phishing resistant No Yes Yes
No hardware required Yes No Yes
Can be stolen Yes No* No*
Breach resistant No Yes Yes
No credential to No Yes Yes
remember/store
# *Private keys stored in device secure enclave cannot be extracted
# Passkeys can sync across your devices (unlike hardware keys)
# This is the key advantage: convenience + security
Synced vs Device-Bound Passkeys
# Synced passkeys:
# - Stored in iCloud Keychain, Google Password Manager, 1Password
# - Available on all your Apple/Google/other devices automatically
# - Convenient: lose your phone, still have passkeys on laptop
# - Slightly weaker security model (cloud provider can access)
# - Good for: most consumer accounts
# Device-bound passkeys:
# - Stored in hardware security key (YubiKey) or device TPM
# - NOT synced - if you lose the device, you need recovery
# - Highest security - private key truly never leaves hardware
# - Good for: high-security enterprise use cases
# Check which type you're creating:
# Most browser-based passkeys = synced to platform keychain
# Hardware key = device-bound
Creating and Using Passkeys Today
# On Google Account (passkey support since 2023):
# 1. myaccount.google.com/security
# 2. "Passkeys" > "Use passkeys"
# 3. Create passkey on your device
# 4. Future sign-ins: just Face ID or fingerprint
# On GitHub:
# 1. github.com/settings/security
# 2. "Two-factor authentication" > "Passkeys"
# 3. Add passkey
# 4. GitHub now signs you in with biometric only
# On iPhone (iOS 16+):
# Settings automatically creates and stores passkeys in iCloud Keychain
# Works with any website that supports WebAuthn
# Check passkey support at: passkeys.directory
# Tracks all services that have added passkey support
Implementing Passkeys in Your Web Application
# WebAuthn API (browser-side JavaScript):
// Registration (creating a passkey):
async function registerPasskey(username) {
const challenge = await fetchChallenge('/api/auth/challenge');
const credential = await navigator.credentials.create({
publicKey: {
challenge: challenge,
rp: { name: "My App", id: "myapp.com" },
user: {
id: new TextEncoder().encode(username),
name: username,
displayName: username
},
pubKeyCredParams: [
{ alg: -7, type: "public-key" }, // ES256
{ alg: -257, type: "public-key" } // RS256
],
authenticatorSelection: {
residentKey: "required", // Device stores credential
userVerification: "required" // Require biometric/PIN
}
}
});
// Send credential to server for storage
await saveCredential('/api/auth/register', credential);
}
// Authentication (using passkey):
async function authenticate() {
const challenge = await fetchChallenge('/api/auth/challenge');
const assertion = await navigator.credentials.get({
publicKey: {
challenge: challenge,
rpId: "myapp.com",
userVerification: "required"
}
});
// Server verifies the signature
await verifyAssertion('/api/auth/verify', assertion);
}
// Server-side (Python with webauthn library):
# pip install webauthn
from webauthn import verify_authentication_response
verification = verify_authentication_response(
credential=response,
expected_challenge=stored_challenge,
expected_rp_id="myapp.com",
expected_origin="https://myapp.com",
credential_public_key=stored_public_key,
credential_current_sign_count=stored_sign_count
)
Migration Strategy: Passwords to Passkeys
# Don't force users to switch immediately:
# Phase 1: Add passkey option alongside password
# Phase 2: Prompt users to create passkey at login
# Phase 3: Offer "sign in with passkey" as primary option
# Phase 4: For new accounts, create passkey by default
# Phase 5: Eventually deprecate password for existing users
# Progressive enhancement approach:
# Check if browser supports WebAuthn:
if (window.PublicKeyCredential) {
showPasskeyOption(); // Browser supports it
} else {
showPasswordOnly(); // Fallback to password
}
Wrap Up
Passkeys represent the most significant improvement in authentication security since the invention of two-factor authentication. They eliminate phishing, credential stuffing, and server-side breach exposure all at once. Enable passkeys on your personal accounts today, and if you build web applications, passkey support should be on your roadmap — the major platforms have done the hard work, and adoption is accelerating rapidly.