What Are Passkeys?
Passkeys are cryptographic key pairs that replace passwords:
Private key - Stays on your device, stored in iCloud Keychain, syncs across your Apple devices
Public key - Sent to the server, stored instead of a password hash
When you sign in, your device creates a cryptographic signature with the private key (without revealing it). The server verifies this signature using the public key. Match = authenticated.
Unlike passwords where you send the same secret every time, passkeys prove you have the secret without transmitting it.
How Passkeys Work
The flow has two parts: registration (creating an account) and authentication (signing in). Both follow a challenge-response pattern that prevents replay attacks.
See the flow diagram:
The challenge is critical - it's a random value that makes each authentication unique. Even if someone intercepts a signature, they can't reuse it because the next attempt uses a different challenge.
Why Passkeys Matter
Security wins:
- No password reuse - Each passkey is unique to your domain
- Phishing-proof - Passkeys only work on the exact domain they were created for
- Server breaches don't matter - Public keys are useless without private keys
Better UX:
- No password resets - Users can't forget their passkeys
- Faster than passwords + MFA - Biometric auth is quicker and more secure
Real adoption:
- 69% of users have at least one passkey (FIDO Alliance, 2025)
- 4x higher sign-in success vs passwords (Google)
- 97% sign-in success at scale (TikTok)
This isn't experimental anymore. It's production-ready.
What You Need
Server side:
- WebAuthn/FIDO2 endpoints (libraries exist for Node.js, Python, Go, Java)
- Four endpoints: registration challenge, registration verify, auth challenge, auth verify
iOS side:
- iOS 16+
- Associated domains configured
- Valid domain with SSL certificate
Domain setup:
-
apple-app-site-associationfile at/.well-known/path
Setting Up Associated Domains
Add to your entitlements:
<key>com.apple.developer.associated-domains</key>
<array>
<string>webcredentials:myapp.example.com</string>
</array>
Create /.well-known/apple-app-site-association on your server:
{
"webcredentials": {
"apps": ["TEAMID.com.yourcompany.yourapp"]
}
}
This links your app to your domain. Both sides must verify the relationship.
The Challenge-Response Pattern
Every auth action starts with the server generating a random challenge (16-32 bytes, base64-encoded). Used only once.
Your app passes the challenge to iOS with your domain and user ID. iOS prompts for Face ID/Touch ID, then uses the private key to sign the challenge. This signature proves possession of the private key without revealing it.
Your server verifies the signature using the stored public key. Valid signature = authenticated.
Challenges prevent replay attacks. An intercepted signature is useless for the next authentication because it'll have a different challenge.
What Happens on Device
iOS handles the heavy lifting:
- Checks device supports passkeys (Face ID/Touch ID + iCloud Keychain)
- Shows biometric prompt with your app name and domain
- On success, accesses Secure Enclave (hardware security chip)
- Generates signature with private key (key never leaves Secure Enclave)
- Returns credential/signature to your app
If multiple passkeys exist for your domain, iOS shows a picker. Your app never sees the private key.
iCloud Keychain Sync
Passkeys sync automatically across your Apple devices (end-to-end encrypted). Create once on iPhone, use on iPad and Mac.
Benefits:
- Seamless multi-device access
- Automatic backup when getting new devices
- QR code sharing for non-Apple devices
Planning Your Implementation
Key decisions:
Onboarding timing:
- During account creation (makes passkeys default)
- After first password login (captures verified users)
- In settings (user-controlled)
Fallback strategy:
- Keep password auth during transition
- Handle devices without Face ID/Touch ID
- Support users who disabled iCloud Keychain
Backend changes:
- New endpoints for WebAuthn
- Database schema for public keys
- User education about passkeys
Start by adding passkeys alongside passwords, not replacing them immediately.
Next: Implementation
Part 2 covers the actual code: SwiftUI views, authentication view model, error handling, and server integration. You'll have working passkey authentication you can adapt for your app.


Top comments (6)
Passkeys are cryptographic key pairs that replace passwords:
Private key - Stays on your device, stored in iCloud Keychain, syncs across your Apple devices
Public key - Sent to the server, stored instead of a password hash
Awesome breakdown! Makes passkeys and passwordless sign-ins in SwiftUI way easier to understand.
thanks for the appreciation
Really enjoying your articles (new here😊) - great stuff! When I checked out your page and saw “I like to keep it simple: if you’re curious, building something, or just feel like connecting…” I thought I’d reach out, but couldn’t seem to find a way to connect directly.
Thanks for pointing it out. I added the link.
This is an excellent, high-level overview of Passkeys and their architecture! I especially appreciate the clear explanation of the challenge-response pattern that prevents replay attacks.