A demonstration macOS application showcasing passkey authentication with the PRF (Pseudo-Random Function) extension for deriving encryption keys.
Backend: See PasskeyBackend for the companion Vapor server implementation.
- Passwordless Authentication: Use passkeys for secure, biometric-based authentication
- Email-Based Registration: Simple registration flow using email addresses
- Unified Auth Flow: Automatically detects if a user exists and routes to login or registration
- PRF Extension Support: Derives deterministic encryption keys from passkeys
- End-to-End Encryption: Encrypt and decrypt data using PRF-derived symmetric keys
- Immediate Key Availability: Encryption keys are generated during registration
- SwiftUI: Modern declarative UI framework
- AuthenticationServices: Apple's passkey APIs
ASAuthorizationPlatformPublicKeyCredentialProviderfor both registration and login- PRF extension for encryption key derivation
- CryptoKit: AES.GCM encryption/decryption
- User enters email and clicks "Continue with Passkey"
- App checks if user exists:
- If user exists → Perform login
- If user doesn't exist → Create new account
- Passkey authentication using Face ID/Touch ID
- PRF extension derives encryption key from passkey
- User is authenticated with encryption key immediately available
The PRF (Pseudo-Random Function) extension is a WebAuthn feature that allows deriving cryptographic keys from passkeys:
- Deterministic: Same passkey + same salt = same encryption key
- Secure: Keys are derived on-device and never leave the Secure Enclave
- Available Everywhere: Keys are accessible wherever the passkey is synced (via iCloud Keychain)
- No Storage Required: Keys are derived on-demand, not stored
- Xcode 15.0+
- macOS 14.0+
- A deployed backend (see PasskeyBackend)
-
Update Domain: Change the domain in
PasskeyController.swift:private let baseURL = "https://your-domain.com/api/auth/passkey"
-
Associated Domain: Update
PasskeyDemo.entitlements:<key>com.apple.developer.associated-domains</key> <array> <string>webcredentials:your-domain.com</string> </array>
-
App ID: Ensure your backend's
apple-app-site-associationfile matches your app's Team ID and Bundle ID
- Open
PasskeyDemo.xcodeprojin Xcode - Select a macOS target (Mac with Touch ID or use Simulator)
- Build and run (⌘R)
- Enter your email address
- Click "Continue with Passkey"
- Authenticate with Face ID/Touch ID
- Your encryption key is immediately available
- Enter your email address
- Click "Continue with Passkey"
- Authenticate with Face ID/Touch ID
- Your encryption key is derived and ready to use
Encrypt:
- Enter text in the "Encrypt Text" section
- Click "Encrypt"
- Copy the encrypted output using the "Copy" button
Decrypt:
- Paste encrypted text in the "Decrypt Text" section
- Click "Decrypt"
- View the decrypted result
- Biometric authentication required for all passkey operations
- Encryption keys never stored - derived on-demand from passkeys
- Keys never leave device - generated in Secure Enclave
- Authenticated encryption using AES.GCM (provides both confidentiality and integrity)
- Associated domain verification prevents phishing attacks
This is a demonstration project and should not be used in production without additional security measures:
- No key rotation - Production apps should support key rotation
- Basic error handling - Production apps need comprehensive error handling
- No backup recovery - If passkey is lost, encryption key is permanently lost
- WebAuthn/FIDO2: Industry-standard passwordless authentication
- PRF Extension: WebAuthn extension for key derivation
- Passkeys: Apple's implementation of FIDO2 credentials
- iCloud Keychain: Sync passkeys across devices
- Secure Enclave: Hardware-isolated cryptographic operations
- CryptoKit: Apple's cryptography framework
- WebAuthn Specification
- PRF Extension Spec
- Apple Passkeys Documentation
- Apple AuthenticationServices Documentation
- FIDO Alliance
BSD 3-Clause License - See LICENSE.md for details