Passkeys AutoFill Provider

We are trying to implement the new feature that was introduced in iOS 17, Passkeys Autofill Provider.

  1. We've created a new 'AutoFill Credential Provider' target and embedded it into our host app.

  2. We've implemented the 'CredentialProviderViewController,' which is inherited from 'ASCredentialProviderViewController.'

  3. When we go to 'https://webauthn.io' to trigger the passkeys view, everything is working as expected when we press 'Register.'

  4. The function 'override func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest)' is called, but...

  5. We know that we need to call 'self.extensionContext.completeRegistrationRequest(using:)' but we don't know how to construct the response.

We didn't find any examples or explanations of how to use this API. Can someone help us with this?

Thank you.

Post not yet marked as solved Up vote post of Incogn1to Down vote post of Incogn1to
908 views
  • Hi @Incogn1to , maybe a stupid question but could you please detail the user experience a bit on how we support third party provider model? Like in step 3 you mentioned that you go to 'https://webauthn.io' and click on Register. What happens next? Do you scan the QR code generated by the browser using the iPhone Camera app and then OS prompts for your app to generate passkey? Also, are you aware if in this model, does the passkey get synced to iCloud Keychain and if yes, can we restrict it?

Add a Comment

Replies

The answer is that it's mostly up to you! Your passkey provider can implement passkey creation and management however you want, as long as you give us back a valid passkey WebAuthn response at the end. For details about how the individual fields need to be formatted, the best documentation is the WebAuthn spec itself.

Thank you for the quick response, @garrett-davidson.

Below is a piece of code that we are trying to use, along with comments to clarify the situation. Your comments will be greatly appreciated.

// Example: We visit https://example.com and press the register button, which internally triggers `navigator.credentials.create()`.
override func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest) {
    self.request = registrationRequest as! ASPasskeyCredentialRequest
    
    let response = ASPasskeyRegistrationCredential(
        // What string should be used here? example.com or https://example.com?
        // Is this the correct documentation? Refer to: https://www.w3.org/TR/webauthn-2/#relying-party-identifier
        relyingParty: self.request.credentialIdentity.serviceIdentifier.identifier,
        
        // Is this the correct documentation for `clientDataHash`? See: https://www.w3.org/TR/webauthn-2/#collectedclientdata-hash-of-the-serialized-client-data
        clientDataHash: self.request.clientDataHash,
        
        // Is this the correct documentation? Check: https://www.w3.org/TR/webauthn-2/#credential-id
        credentialID: Data(UUID().uuidString.utf8),
        
        // Is this the correct documentation? See: https://www.w3.org/TR/webauthn-2/#sctn-generating-an-attestation-object
        // Should the attestationObject be a CBOR map in bytes?
        attestationObject: Data()
    )
    
    self.extensionContext.completeRegistrationRequest(using: response)
}
  • Yep you've gotten the right documentation for everything. Yes the attestationObject needs to be CBOR and generating it is the bulk of your work.

  • Is that above snippet worked for you ? For me the clientDataJSON was received empty on 'didCompleteWithAuthorization' after the registration. I just gone with the same flow as you mentioned.

Add a Comment

After a few days of research, we finally found out why it didn't work.

The problem lies here: https://www.w3.org/TR/webauthn-3/#flags According to the official documentation, Bits 3-5 are reserved for future use (RFU2), and they MUST remain as zeros. However, in this source https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API/Authenticator_data,) those bits are used. It seems that on iOS, if those bits are zeros, you always get an error. This aspect is not mentioned anywhere.

  • Hi @Incogn1to . If those bits 3-5 which pertain to backup eligibility and backup state are set to 1 for it to work on iOS, does that mean the passkey generated will get synced to a different iPhone/iOS device via iCloud Keychain for the same apple id?

Add a Comment