App Transfer Keychain Loss: Solutions to users logging out - ios

I transferred an app to a new developer account. When I upload a build from the new developer account and deploy it through Testflight, I encounter that my users logged out from the app.
I think this is due to the Keychain Loss, because the Team ID changed. So, I contacted Apple, and they said that there is no way to have access to the old Keychain in the new developer account, but that I could transfer the app back to my old developer account.
This is really bad for us, since we have user-created data in the device that gets lost on logout. We also have anonymous users, and they can’t even regain access to their accounts because there are no credentials to login. This is not acceptable to us because we would be losing user data, but we also need to transfer the app to the new developer account... So we are trying to find possible solutions.
Possible Solution #1
Far from ideal: keep using the old developer account for a month, for example, and show an alert saying something like:
Please save/backup all your data and signup (if you have an anonymous
account) because all unsaved data will be lost on the [todays date + 1
month] due to a migration. Sorry for the inconvenience.
After a month, we transfer again to the new developer account. Users that didn’t see the message in that month or didn’t save data, bye bye data… terrible.
Possible Solution #2
I'm not sure if Firebase Auth iOS SDK has the APIs to do something like this:
Transfer the app back again to the old developer account
Upload a new build from there that saves the Firebase Authentication State (e.g. the token) temporarily in a file (I know it's insecure... maybe I could encrypt it)
Transfer the app back again to the new developer account
Upload a new build that checks if that file exists, and copies the Auth State into the Firebase Auth SDK again. This way the user is still logged in as if nothing happened.
This second solution is kind of insecure, complicated and difficult to test, but from the user point of view, it would be more ideal than the first solution (if everything goes well).
So, specifically my questions are:
Would solution #2 be possible with Firebase Auth?
Does anyone have more ideas on how to approach this? I guess that transferring apps (with login) is a common use case!
We currently only use Anonymous & Email/Password authentication methods.
Thanks!

So, I didn't find an ideal solution.
I ended up doing a mix of solutions #1 and #2:
I transferred the app back to the old apple account
I uploaded a new build that:
a. extracts keychain data (which has login credentials and other stuff)
b. encrypts this data (I used CryptoSwift)
c. saves it into a file in the documents directory
Waited 1-2 months so users can open the app to perform this first part of the migration
While waiting, we sent emails and push notifications asking users to backup their data, saying that a big migration was coming soon, with the excuse that we "grew" a lot lately and we were scaling stuff :P
Transferred the app to the new apple account
I uploaded a new build that:
a. checks if the migration file exists (in the documents directory)
b. if exists, read the migration file and decrypts data
c. puts this data into the keychain (which is empty after app transfer)
d. deletes the migration file from the documents directory
Left this migration code for some more months so people open the app and perform migration
Delete code, migration period is over.
I sent logs to the backend to see if migrations were successful or not. So far, users are all migrating correctly.
There are still cases where users could lose their data, for example, when anonymous users didn't perform the first part of the migration. But I can't think of a better solution... so far data loss is minimal. But it also took us some time to get things right and do all the proper testing.
If someone in the future has a better solution to this issue, please let me know!! I'm curious.
I hope the answer helps someone.

I think the Apple rep was wrong. Your keychain is tied to a bundle ID, not a Team ID.
Suppose for example that you transferred SomeApp from the original app owner, OldCo, to NewCo. The app comprises a custom keyboard, the actual SomeApp app, and an App Group. You have some Identifiers set up on developer.apple.com:
App ID:
com.OldCo.SomeApp
com.OldCo.SomeApp.keyboard
App Group ID:
com.OldCo.SomeAppGroup
If you change these to start with com.NewCo., users will lose their iCloud data. But if you leave them as com.OldCo., all should be well. Note that for you to create these IDs in NewCo's developer.apple.com account, OldCo will have to remove them from their account. It feels weird to have NewCo owning IDs with OldCo in them, but life is weird.
If I'm missing some nuance whereby the change in TeamID affects the keychain, please let me know, and I'll do more research.

Related

Preserving Keychain data during developer account migration

I am migrating our organisation's app to a new developer account, for internal reasons. I've learned that upon transferring the app to the new account, and after we release an update for the app from the new developer account, we will incur a one time loss of keychain data.
My concern is, that we cannot afford this loss of data. Due to security reasons and nature of the type of clients using the app.
So my question is 2 part;
1) Is there any way that I can prevent this keychain data loss?
2) If not, what are the alternate strategies I can use to prevent the users from getting logged out during this transition?
Assuming you're talking about a real, full App Transfer I don't think this is possible. Keychains are not just differentiated via the app ID, but also the organization's ID (or more precisely the organization's ID is part of an app ID). Since the app's ID de facto changes with a transfer, iOS will prevent it to look up its old keychain. Not even app groups get around this, as a group cannot consist of apps by different organizations AFAIK. Apple would need to implement a kind of exception to this for at least a certain "migration period", but I doubt that will ever happen (for security considerations).
The only way to circumvent a re-login so that the transferred app can save the credentials in its "new" keychain would be to first have an update for the old, not-yet transferred app and have it save the credentials elsewhere, then have the transferred app look them up from there. I'd strongly recommend against this for security reasons, but if you absolutely must do that, you could upload the credentials somewhere secure (via an encrypted connection, obviously, i.e. SSL). You might even be able to use shared web credentials for this, but I haven't looked into that too deeply, so I am not sure whether both apps can be configured to be associated with that website (they're coming from two different teams, after all, but it might be allowed).
Even then, some users might "miss" the update of the older app before the transfer (and update to the "new" one), then they would have to re-login anyways.
If you follow this idea, be aware that you're "moving around" users' private data in a new way! Considering the recent GDPR fuzz this might even have string legal implications, so check with your company's legal advisors about this, too!
1) There is no way your can prevent data loss, since the App ID Prefix has changed during app transfer TN2311 > A one-time loss in keychain data will occur if you switch your App ID prefix
2)
If you application utilizes Push Notification, you can use the APNs device tokens to remap the user account.
Once the new app is launched:
Send the device token to server
Find the username from your database
Generate a session token (add your own security design here)
Save username + the token in your new Keychain
For those who doesn't allow notification, just force them to relogin

Preventing users from creating multiple accounts on my server

I have a game I originally wrote for PC that I'm now porting to ios.
It is an online multiplayer game that requires the user to have an account with us. To do this they sign up and register right in the game.
We want to try to prevent the same user creating lots of accounts. If it happens it's not critical, but we want to diminish it.
On PC we store a file in app data saying an account has been created with this computer. so it is hard for the average user to circumvent that.
Unfortunately on ios, there does not seem to be a way to permanently store something to prevent the user from creating multiple accounts. They can uninstall and reinstall the app, clear keychain data, etc.
What is / are some ways that can be used help prevent multiple account creation?
Thanks
Actually keychain items are not cleared on app uninstall. You can store their playerId there. And you can fetch that the next time user installs the app.
There is no sure shot way using which you can prevent users from creating multiple accounts. At most you can make it difficult for an average user to do so.

How to ban an iOS user?

A while ago, I got banned from an iOS app. Not a user ID ban, but it seems to have been a device ban. Even if I delete and reinstall the app and try to make a new account, it would automatically get banned. My question is, how are they doing this? What are all the possible ways to ban a device that is persistent even after deleting and re-installing the app?
It is not possible to access UDID anymore, so there's that. And I don't think iOS allows them to view iTunes account, so that's not possible. Are they perhaps storing anything in the keychain? From what I know, some things in the keychain don't get removed even if the app is uninstalled.
I'd like to implement something like this in my app, so I want to know all the possible methods, with pros and cons for each.
When the app is uninstalled, all data goes with it. So writing anything to disk isn't going to work.
You can store something in the keychain, although users can edit the keychain if they sync it to a mac. That makes it pretty insecure.
The best option is to store it off the device, in iCloud. I'd go with key/value storage: https://developer.apple.com/library/mac/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForKey-ValueDataIniCloud.html
Another option you could choose is Apple's replacement for reading the UDID which is to grab the advertising identifier. However it is possible for users to block this in Settings and your app could theoretically be kicked out of the store if it's used for something other than the intended purpose. I don't think it's actively policed, but still probably not a good idea to use it.
A belts and suspenders option would be to do everything:
save it to disk (in application support)
save it to key value storage in icloud
save it to keychain
use the advertising identifier to and send it to a remote server that you control (personally I'd skip this to avoid having the app banned from the store)
However... I'm not sure if Apple allows users to be banned. You might well be violating the developer rules by doing so. Especially the last one, which goes something like "this list is incomplete and constantly changing, your app might cause us to add a new rule to the list".
If it's a paid app or has in app purchases I'm pretty sure they would issue refunds to any customer who complains, and they'd probably follow the refund up with kicking your app out of the store.
Were I tasked to implement something like this, I would do exactly what you suspect: generate a simple random token, keep it in the keychain, and include it in API requests.
Nothing in the iOS keychain is removed when the app is uninstalled. I don't actually know of a good way to manually remove stuff from it.

Where to store a piece of important data (away from users) that will be backed up by itunes

I am currently making an app and there is an important piece of information I need to store. The user can make a one time in-app purchase.
My question is, what is the apple recommended or approved method for storing this?
No. 1 is most important to me. For example imagine the user can purchase 10 lives. After his purchase he will use some of them so imagine he now has a balance of 5. Where should this number be stored.
The issues or thoughts or random ideas I have as a result of reading things are;
if its saved in a simple file then a jailbreaker can just go in an
edit the file.
if its saved in an encrypted file I think I have extra issues with my
app/Apple/certain countries because I am using encryption.
what happens when the user accidentally removes the app. He cannot
restore his purchases as its a one time purchase
should I be and how should this important piece of information be
backed up on a sync
how do I ensure this information is saved as part of a backup.
I am not sure there is one answer to this problem. In my case I save the information in the keychain. Other iOS SDKs such as Amazon's or Facebook's do the same thing as far as I can see.

change ownership of Personal Apple Developer account

I hope somebody can help here, its an ongoing issue with no obvious solution.
The background
I created my own personal apple developer account back in 2010 to tinker about with iOS development. The company I worked for at that time asked me to write an app as a test to see if we could a) write an app and b) sell it. It so happens both cases were true and the app has flourished into a successful venture.
The issue:
I am leaving this company and we are trying to figure out how I can give them this app, they did after all still pay a salary while I was making the app so I consider it their app really only its tied to me and my personal developer license. I currently forward any funds it makes to them each month.
We contacted Apple and they suggested the company i work for set up a company developer account and then ask for an app transfer. This sounded great and we started the process but then it occurred to me that re-signing the app under a different developer license would effectively kill the existing app on the store. All our ratings would be wiped (and there are quite a few) which is unacceptable. The ratings of an App are extremely important to its success on the store. Apple confirmed that the ratings and reviews do not get transferred across. We stopped.
So, here I am at this block again.
The company I work for even suggested buying my personal account off me so they can run it themselves but I am worried about this, it seems fraudulent as I am the one responsible for contracts on that account and any issue would come back to me. THey wouldn't be able to change the owner "name" on the account either from what I have read.
Any suggestions how we can resolve this?
Thanks
Geoff
it occurred to me that re-signing the app under a different developer license would effectively kill the existing app on the store.
This is false. As long as you transfer the app like Apple suggests (you need to contact them for this), the company just needs to submit a new version from their account and it will work. You don't lose your ratings, nothing. It all gets transferred to the new account including the iTunes Connect side of things. They can sign it with a different certificate and submit. As long as the app ID is the same as before (which it will be), there is no problem.
It sounds like you have old or inaccurate information, because I know somebody who did a transfer like this, and they kept all the ratings etc.
I have faced this same issue, after contacting apple several times, we concluded that there was not other choice, so we removed the app and re uploaded it a gain on the other account
Not only the rating has been wiped, but also users with old app will not be able to update it when you push a new version to the app store
Its a very tough decision, but we had no other choice

Resources