This implementation now supports both QR code/phone passkey AND security key options simultaneously in Google Chrome on Ubuntu Linux (and all other platforms).
- 📱 QR Code/Phone Passkey - Scan QR code to use your phone as authenticator
- 🔑 Security Key - Insert USB/NFC security key (YubiKey, etc.)
- 💻 Platform Authenticators - Touch ID, Face ID, Windows Hello
- 🤖 Android Credential Providers - Third-party credential managers with discoverable credentials
- 🌐 Universal Compatibility - Works across all browsers and platforms
When using the hybrid WebAuthn implementation, Chrome will present a dialog with multiple options:
- "Use your phone" - Shows QR code to scan with your phone
- "Use a security key" - For USB/NFC security keys
- Platform options - Touch ID (Mac), Windows Hello, etc.
The key changes are in the WebAuthn configuration:
// New hybrid registration method
let options = manager.generateHybridRegistrationOptions(username: username)
// Key features:
// - NO authenticatorAttachment restriction
// - Supports all transport types: ["internal", "usb", "nfc", "hybrid"]
// - Flexible userVerification: "preferred"New hybrid endpoints have been added:
- Registration:
POST /webauthn/register/begin/hybrid - Authentication:
POST /webauthn/authenticate/begin/hybrid
// The client now defaults to hybrid strategy
const { strategy } = await webauthn.getBestRegistrationStrategy();
// strategy will be 'hybrid' for maximum compatibility
// Use hybrid endpoints directly
const response = await fetch('/webauthn/register/begin/hybrid', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username })
});Use the test page to verify functionality:
open static/hybrid-webauthn-test.html
- Removed
authenticatorAttachmentrestrictions - This is the key change that allows Chrome to show both options - Added all transport types - Including "hybrid" for QR code support
- Flexible verification -
userVerification: "preferred"works with both types - New hybrid endpoints - Dedicated endpoints for hybrid functionality
// OLD (restrictive)
authenticatorSelection: {
authenticatorAttachment: "platform", // RESTRICTS to platform only
userVerification: "required"
}
// NEW (hybrid)
authenticatorSelection: {
// NO authenticatorAttachment - allows both platform and cross-platform
userVerification: "preferred", // Flexible
requireResidentKey: false,
residentKey: "preferred"
}
// Transport support
transports: ["internal", "usb", "nfc", "hybrid"] // All types supported- Open Chrome on Ubuntu Linux
- Navigate to the test page:
static/hybrid-webauthn-test.html - Click "Register with Hybrid WebAuthn"
- Chrome should show multiple options:
- QR code option for phone
- Security key option for USB/NFC keys
- Any available platform authenticators
When you select "Use your phone" in Chrome:
- Chrome displays a QR code
- Scan with your phone's camera
- Your phone prompts for biometric authentication
- Registration/authentication completes on your phone
- Chrome receives the credential
When you select "Use a security key" in Chrome:
- Chrome prompts to insert security key
- Insert USB key or tap NFC key
- Follow security key prompts (PIN, touch, etc.)
- Registration/authentication completes
- User Choice - Users can choose their preferred authentication method
- Backwards Compatible - Still works with existing security keys
- Future Proof - Supports latest WebAuthn standards
- Cross-Platform - Works on all operating systems
- Secure - Maintains all WebAuthn security guarantees
To migrate existing implementations:
- Use hybrid endpoints instead of platform-specific ones
- Update client-side strategy to use 'hybrid' by default
- Test with multiple authenticator types
- Update user documentation to mention QR code support
- Ensure
authenticatorAttachmentis NOT set to "platform" or "cross-platform" - Verify "hybrid" transport is included
- Check Chrome version (requires recent Chrome)
- Yes! The hybrid approach is fully backwards compatible
- Security keys will appear as "Use a security key" option
- Ensure phone supports WebAuthn (iOS 16+, Android with Chrome)
- Check phone's biometric setup
- Verify network connectivity
- Android's user agent contains "Linux", so
isLinux()now explicitly excludes Android - Check console for
🤖 Androidlogs (not🐧 Linux) - Android uses
/webauthn/register/begin/androidendpoint with discoverable credentials - Third-party credential providers require
residentKey: "preferred"and noauthenticatorAttachment