## Context Safari 16 on iOS and macOS (and probably iPadOS too) always shows the hybrid auth QR code in cases where no entries in allowCredentials, with only ["internal"] specified for their transports, are recognized by the local platform authenticator. As an RP, if we do not communicate to the browser that "hybrid" transport is possible for any provided credentials we would not expect the QR code to appear. For sake of comparison, Chrome on macOS and Android shows a "no passkeys available" message in this same scenario. ## Environment - Safari 16.6 - macOS 13.5.1 - iOS 16.6 ## Reproduction This basic HTML document can be used to recreate the scenario outlined above: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { max-width: 40em; margin: auto; } </style> <title>Safari Bug - Hybrid shown for unrecognized ["internal"] entry in allowCredentials</title> </head> <body> <h1> Safari Bug - Hybrid shown for unrecognized ["internal"] entry in allowCredentials </h1> <p> Demonstrating how Safari shows hybrid auth QR code as an option even though the only entry in allowCredentials has just ["internal"] for its transports. </p> <button id="auth1">Authenticate w/["internal"]</button> <script> // button#auth1 document.getElementById('auth1').addEventListener('click', () => { navigator.credentials.get({ publicKey: { challenge: new Uint8Array([1,2,3,4]), allowCredentials: [ { id: new Uint8Array([1]), type: 'public-key', transports: ['internal'] }, ] }, }).then(console.log); }); </script> </body> </html> ```
Created attachment 467593 [details] Hybrid auth QR code shown in iOS Safari
Created attachment 467594 [details] "No passkeys available" message shown by Chrome for same scenario
<rdar://problem/115144326>
If a credential is available over "internal," then it follows that it would also be available over hybrid if it's on another device's platform authenticator.
John - if a credential is also available over hybrid, it should have both `internal` and `hybrid` transports. It can't be assumed that internal and hybrid are always coupled.
> If a credential is available over "internal," then it follows that it would also be available over hybrid if it's on another device's platform authenticator. A specific pain point with this line of reasoning is that, if a passkey is registered via macOS Safari, but iCloud Keychain sync is OFF in iOS, then there's no way to scan the QR code that iOS shows by any device running macOS. It seems like an impossible scenario for a user to complete auth in because of macOS' lack of a OS-level way to scan QR codes. There's an alternative idea that came up this morning: what if Safari consistently showed the same prompt to enable iCloud Keychain sync that it shows during registration, but during authentication as well? If Safari is given a credential with ["internal", "hybrid"] then how can it test if the platform authenticator on the iOS device recognizes it if iCloud Keychain sync (which still seems to be a hard requirement to use a platform authenticator on an Apple device) is disabled? I'm going to attach a couple screenshots of the registration CTA to turn on sync that I think could also unstick users here.
Created attachment 467605 [details] iOS prompt to turn on iCloud Keychain sync during registration
Created attachment 467606 [details] macOS prompt to turn on iCloud Keychain sync during registration
For the record, I'd still prefer Safari to act like Chrome and show a "no passkeys available" when ["internal"] is unrecognized by the access device.
The fix for this issue needs to be made outside of the WebKit Open Source project. Resolving as MOVED. We believe this has been resolved in the now-shipping iOS 17.2 and macOS 14.2 releases.
I retested just now in Safari 17.2.1 on macOS 14.2.1. Now if I try to authenticate with the same example as above then nothing happens at all - there's no visual indication that a WebAuthn call was ever attempted. When I view try again while looking at the console in Web Inspector there's a single `NotAllowedError: Operation failed" and nothing else to help either user or RP understand that this call to `.get()` is erroring out because the platform authenticator doesn't recognize the only allowed credential? I've attached a screenshot with this error visible. Can you please confirm that this the new expected behavior?
Created attachment 469164 [details] Retesting in Safari 17.2.1 on macOS 14.2.1
I just reviewed the radar referenced here, and I show this fix as having shipped in iOS 17.3 and macOS 14.3.
Created attachment 471735 [details] The issue continues in Safari 17.5 on macOS 14.5 Apologies but I have to reopen this, I just tested the HTML above in Safari 17.5 on macOS 14.5 and I'm still shown a QR code. Please see the latest screenshot I took this afternoon.
Reopening because of potential regression.
Fix is still outside of WebKit, so setting to MOVED.
The regression claim will be tracked by: rdar://130446659
> Fix is still outside of WebKit, so setting to MOVED. Ah, "MOVED" means that this may be an issue at the Safari level instead?