There is this app, which is a financial app, we use UUID to uniquely identify the app, since there no way of extracting IMEI etc on apple to identify a device. We store this UUID in a keychain, because in one instance of apple OS upgrade the UUID changed after the OS upgrade, this I think is well documented. Hence we cannot rely on this if it happens again, because honestly I can’t explain these things to our clients (who don’t understand the technical aspect of things) .
So our servers uniquely identify each device/user based on this UUID, and redirects him/her to either the login page or to the registration page.
We also have enabled biometric , we ask the Secure enclave to generate a public and a private key and we store the public key in our servers. So once server stores this public key it assumes the user has enabled biometric login. On launch of the app our server generate a token and sends it to the device. User then tries to login using face/Touch ID, we request the private key reference from the secure enclave (upon which biometric gets launched) get the private key reference , sign the token and send it to server , which will use the public key to check if the token is valid and that is our biometric authentication process.
Now the same user now buys a new iPhone, and then transfer his data from the old iPhone using iphone to iPhone transfer, guess what happens, the UUID in the Keychain gets transferred to the new iPhone even though I have specifically stated not to. i.e via kSecAttrAccessibleAlwaysThisDeviceOnly. Now the Secure enclave doesn’t gets transferred to the new iPhone. Now the user tries to access the app on his new phone, it directly goes to the login page instead of registration page because our server gets the original UUID that was used on the old iPhone. Then server assumes the user has already enrolled in biometric sends the token and then the device tries to access the private key reference ,it returns nil and our app crashes only on iOS 15. Used to return failure now it doesn’t.
Now there are other users who transfer (using the above same app which is in store by the way) their data via iCloud for them the UUID (Stored in keychain) doesn’t get transferred because of kSecAttrAccessibleAlwaysThisDeviceOnly, so all is well, it behaves as expected.
Now is my approach wrong? Or is it a bug at apple’s end?