Hello, I am currently implementing a biometric authentication registration flow using WebAuthn. I am using ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest, and I would like to know if there is a way to hide the "Save to another device" option that appears during the registration process.
Specifically, I want to guide users to save the passkey only locally on their device, without prompting them to save it to iCloud Keychain or another device.
If there is a way to hide this option or if there is a recommended approach to achieve this, I would greatly appreciate your guidance.
Also, if this is not possible due to iOS version or API limitations, I would be grateful if you could share any best practices for limiting user options in this scenario.
If anyone has experienced a similar issue, your advice would be very helpful. Thank you in advance.
Passkeys in iCloud Keychain
RSS for tagUse public-key-based credentials using the WebAuthn standard that are synced with iCloud Keychain.
Posts under Passkeys in iCloud Keychain tag
90 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello, I am currently working on implementing credential registration for biometric authentication using WebAuthn in an iOS app. I am using ASAuthorizationPlatformPublicKeyCredentialProvider to create a credential registration request based on the data retrieved from the WebAuthn options endpoint.
At the moment, I am only using user.id, user.name, and challenge from the options response, and I am unsure how to utilize the other fields effectively. I would greatly appreciate advice on how to use the following fields:
**Fields I would like to use:
**
rp (Relying Party)
I am retrieving id and name, but I am not sure how best to pass and utilize these fields. Is there an explicit way to use them?
authenticatorSelection
How can I set requireResidentKey and userVerification in ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest? Also, what are the specific benefits of using these fields?
timeout
Is there a way to reflect the timeout value in the credential registration request, and what would be the best way to handle this information in iOS?
attestation
The attestation field can contain values such as none or direct. How should I reflect this in the credential registration request for iOS? I would appreciate a sample implementation or guidance on the benefits of setting this field.
extensions
If I want to customize the authentication flow using the extensions field, how can I appropriately reflect this in iOS? For instance, how can I utilize extensions like credProps?
pubKeyCredParams
Regarding pubKeyCredParams, which is a list of supported public key algorithms, I am unsure how to use it to select an appropriate algorithm in iOS. How should I incorporate this information into the request?
excludeCredentials
I understand that setting excludeCredentials can prevent duplicate registration, but I am not sure how to use past credential information to set it effectively. Any advice on this would be appreciated.
**Current Code
**
Currently, I have implemented the following code, but I am struggling to understand how to add and configure the fields mentioned above.
let publicKeyCredentialProvider = ASAuthorizationPlatformPublicKeyCredentialProvider(
relyingPartyIdentifier: "www.example.com"
)
let registrationRequest = publicKeyCredentialProvider.createCredentialRegistrationRequest(
challenge: challenge,
name: userId,
userID: userIdData
)
let authController = ASAuthorizationController(authorizationRequests: [registrationRequest])
authController.delegate = self
authController.presentationContextProvider = self
authController.performRequests()
In addition to the above code, I would be grateful if anyone could advise on how to configure fields like rp, authenticatorSelection, attestation, extensions, and pubKeyCredParams as well. Furthermore, I would appreciate any insights into the benefits of setting each of these fields in iOS, and any security considerations to be aware of.
If anyone has experience with this, your guidance would be extremely helpful. Thank you very much in advance!
Our desktop app for macos will be released in 2 channels
appstore
dmg package on our official website for users to download and install
Now when we debug with passkey, we find that the package name of the appstore can normally arouse passkey, but the package name of the non-App Store can not arouse the passkey interface
I need your help. Thank you
I once changed my Apple ID. Before changing it, I had set up a passkey for the Apple ID website. After changing my Apple ID, whenever I log in to Apple ID, it still shows my previous Apple ID. Additionally, the passkey for the Apple ID website is not present in my 'Passwords' app, so I am unable to delete it.
My organization routes all device traffic through a network security device that performs TLS intercept (SSL inspection). As might be expected, this breaks passkey Cross-Device Authentication (CDA) functionality, since the thumbprints don't match end-to-end between the authenticator (iPhone) and the client (laptop). As soon as I disable the VPN tunnel through our security device, the passkey login works as expected.
The security team is willing to exclude the relay servers from SSL inspection, but we are unable to find a list of the relevant endpoints. Is there a list of Apple relay servers that are used for passkey tunnelling? We can review the network logs to find the traffic, but I'd prefer an authoritative list.
For full context: we are using device-bound passkeys via Microsoft Authenticator to login to Entra but, as I understand it, the passkey is still handled via Apple's standard passkey infrastructure and APIs.
Thanks!
Hello,
I’m working on creating an NFC-enabled Apple Wallet pass and I need assistance with the proper implementation of the pass.json file to include NFC functionality. My goal is to enable NFC interactions, such as tapping to unlock a door or interacting with other NFC systems.
Here is what I have done so far:
Set up a Pass Type ID and Certificates:
I have registered a Pass Type ID in my Apple Developer account.
I have generated and installed the required certificates (Pass Type ID certificate and WWDR certificate).
Backend Integration:
I have set up a backend service for generating passes, and I can successfully create and deliver standard Wallet passes without the NFC functionality.
Adding the NFC Field:
I understand that to enable NFC interactions, I need to add an nfc dictionary to the pass.json file.
The key components for NFC include the encryptionPublicKey, message, and payload.
Here’s an example of my current pass.json:
{
"formatVersion": 1,
"passTypeIdentifier": "pass.com.example.mypass",
"serialNumber": "123456",
"teamIdentifier": "TEAMID12345",
"webServiceURL": "https://example.com/api/passes",
"authenticationToken": "my_secure_token",
"nfc": {
"message": "Tap to unlock door",
"encryptionPublicKey": "MY_ENCRYPTION_PUBLIC_KEY",
"payload": "encrypted_nfc_payload"
},
"organizationName": "My Company",
"description": "NFC-Enabled Access Pass",
"logoText": "My NFC Pass",
"foregroundColor": "rgb(255, 255, 255)",
"backgroundColor": "rgb(0, 0, 0)",
"barcode": {
"format": "PKBarcodeFormatQR",
"message": "https://example.com",
"messageEncoding": "iso-8859-1"
}
}
Questions:
Are there any additional steps or configurations required to ensure that NFC is enabled in the pass?
Is there a specific method to test or validate NFC functionality in the pass to debug why it’s not being activated?
Any guidance or solutions to enable NFC in this pass would be greatly appreciated.
Thank You
I'm trying to implement WebAuthn conditional credential creation but I'm not able to get it to work.
From this video https://www.youtube.com/watch?v=p8a6ODX1zHY I understand I should call navigator.credentials.create with "mediation: conditional" but the explainer at https://github.com/w3c/webauthn/wiki/Explainer:-Conditional-Registration-Extension also mentions a call to navigator.credentials.get with "mediation: conditional" and "extensions: { conditionalCreate: true }".
The explainer seems to suggest they should be called both but for me, both calls never resolve with a credential or an error.
What am I doing wrong?
I am trying to implement a login page in SwiftUI for an idp that relies on passkeys only, following the sample code from the food truck app.
The registration of a new passkey works fine but when it comes to signing in, ASAuthorizationPlatformPublicKeyCredentialProvider().createCredentialAssertionRequest returns a signature that cannot be verified by the server.
On safari (and other browsers) the signing in&up process works fine and additionally, a passkey registered from the swift app works on the web, which leads me to believe there is an issue in the AuthenticationServices framework as every other steps works without any problem.
The verification of the signature happens on the server side (after several validation steps of the other parameters) with WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
With the data argument being a concat of the clientDataJSON and the authenticatorData and for an apple authenticator, the key argument (which is the public key stored by the server) is an EC2 key with the following verifyAlgorithm argument:
verifyAlgorithm = {
name: 'ECDSA',
hash: { name: SHA-256 },
};
After carefully analyzing multiple responses, coming both from the app and safari, either on iOS or macOS, I can safely say that the ASAuthorizationResult.passkeyAssertion returns the expected values for:
rawAuthenticatorData
rawClientDataJSON
credentialID
userID
Which all match the expected values during the server-side validation. The only remaining value from the ASAuthorizationResult.passkeyAssertion is the signature, which as mentioned above, is invalid when verified by the server.
I already submitted a bug report (FB15113372) as well as a DTS request, but haven’t received any feedback yet.
In order to further narrow down the problem, I replicated the signature verification process in a sage notebook. I got the same result: the signature produced in Safari is fine, but the one from the Swift app is invalid. I collected some thoughts of potential issues in this notebook, but I still haven’t been able to draw a clear conclusion on why does this issue occur.
Hence if anyone has knowledge of this issue or has a similar problem with signature verification, their advice is most welcomed.
Thank you in advance for your help
PS: All the recent tests were made on the latest publicly available OS releases (iOS 18.01, macOS 15.0.1) and Xcode 16.0
We’re trying to get Passkeys to work with iOS and macOS Catalyst.
Apple fails to accept the associated domain, without giving a reason why.
The JSON is correct and shows up on Apple’s CDN.
We are stuck.
The peripheral is initiating a passkey entry mechanism, IOS device is getting a pop up to enter the passkey but the WatchOS device is not displaying any pop-up.
Is there anything to be enabled from the watch side?
when I performAutoFillAssistedRequests ,my keyboard cannot show passkeys that could choose,and nothing callback.i don't know the error reason.but I could request successfully by authController.performRequests.
Hello,
I am using the prf extension for passkeys that is available since ios 18 and macos15.
I am using a fixed, hardcoded prf input when creating or geting the credentials.
After creating a passkey, i try to get the credentials and retrieve the prf output, which works great, but i am getting different prf outputs for the same credential and same prf input used in the following scenarios:
Logging in directly (platform authenticator) on my macbook/iphone/ipad i get "prf output X" consistently for the 3 devices
When i use my iphone/ipad to scan the qr code on my macbook (cross-platform authenticator) i get "prf output Y" consistently with both my ipad and iphone.
Is this intended? Is there a way to get deterministic prf output for both platform and cross-platform auth attachements while using the same credential and prf input?
We are using performRequestsWithOptions to enable passkey on ios app.
[authController performRequestsWithOptions:ASAuthorizationControllerRequestOptionPreferImmediatelyAvailableCredentials];
Based on apple doc, this will "Tells the authorization controller to prefer credentials that are immediately available on the local device.", and fail silently if there are no credentials available.
However, in recent testing, we identified that on one device, we are seeing QR code popping up even though there's no credential on the device. Question
is this a bug on the OS system?
If this is a bug, what are the causes that will trigger this condition?
Is there a recommendation to mitigate the issue? Should we move to the new api?
Thank you.
My device has open passkeys , in setting app. when I performAutoFillAssistedRequests,callback performRequests ASAuthorizationError(rawValue: 1001)".at same time,authController.performRequests could request successfully
Hi Team,
Exporting the archive through the Jenkins pipeline (executing commands on a Mac EC2 instance as a Jenkins agent) isn't working, while exporting directly from the Mac terminal successfully generates the IPA file. What might be the cause?
When we execute it on directly Mac terminal, it asks Keychain password first time & after that it automatically generates IPA file.
Note : We are using below working command to open keychain access.
security unlock-keychain -p "my_password" /Users/ec2-user/Library/Keychains/login.keychain-db
Export command :
xcodebuild -exportArchive
-archivePath $PWD/build/Archive/MyApp.xcarchive
-exportPath $PWD/build/IPA
-exportOptionsPlist ../../Dev_exportOptions.plist
-allowProvisioningUpdates
Current details:
Node version : node-v18.17.0-darwin-arm64
Npm version : 9.6.7
Ionic version : 5.2.6
Xcode version : 15.4
Macos : Sonoma 14.6.1
After iOS 17.4, Passkey Autofill stopped working inside ASWebAuthenticationSession.
iOS 17.5 re-enabled users to pick passkeys if they tap "🔑" icon on right bottom of keyboard and opened Safari password manager.
However, it still doesn't recommend passkeys on the first view.
Even on the latest iOS 18.0 developer beta, the behaviour is not fixed yet.
In AuthorizationServices support for displayName exists in:
class ASAuthorizationSecurityKeyPublicKeyCredentialProvider func createCredentialRegistrationRequest( challenge: Data, displayName: String, name: String, userID: Data ) -> ASAuthorizationSecurityKeyPublicKeyCredentialRegistrationRequest
but is not supported in the corresponding class:
class ASAuthorizationPlatformPublicKeyCredentialProvider func createCredentialRegistrationRequest( challenge: Data, name: String, userID: Data ) -> ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest
I was under the impression that this should be supported in public key credential registration?
I'm using the same code to authenticate using passkeys on iOS and macOS. On iOS (simulator, on-device, and deployed with TestFlight), I have no issues registering or authenticating with a passkey. On macOS using Catalyst, when I attempt to authenticate with a passkey (ASAuthorizationController#performRequests), I see the following error:
Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "Application with identifier TEAMID.com.bundle is not associated with domain bundle.com" UserInfo={NSLocalizedFailureReason=Application with identifier TEAMID.com.bundle is not associated with domain bundle.com}
I've double-checked my apple-app-site-association file is being served from the associated domain, and I've double-checked that the Apple CDN is also returning that same association file with webcredentials for my team/bundle.
Any ideas why it would succeed in iOS environments but fail under macOS with Catalyst?
Referring to this explainer(https://github.com/w3c/webauthn/wiki/Explainer:-Conditional-Registration-Extension) for enabling passkey automatic upgrades. As per the explainer wiki, the credential manager's GET API needs a flag "conditionalCreate: true" before invoking the create API with "mediation: conditional". There is an assumption here that the password autofill needs to be completed as part of the GET API call and only then the passkey automatic upgrades are enabled via conditional mediation in the create API call. Are these assumptions correct?
If the previously stated assumptions are correct would automatic passkey upgrades work in native iOS applications if I use the native credential manager APIs for GET and the web based credential manager API for CREATE? (The sign-in pages are opened in a web view for native application)
Hello, I would like to know how I recreate the data that was signed by the private key during assertion flow.
I read on various sources that my code should get the 37 bytes of authenticator data, append the SHA-256 hash of clientDataJSON string to the end and verify that data given the signature and the public key! But it doesn't seem to work.
I have opened a StackOverflow issue to it where I've provided broader details: https://stackoverflow.com/q/78819955/26530591