I have an iPhone app that uses the keychain for authentication-related storage.
I also had an expiring Provisioning Profile.
In the documentation for keychain access it states:
On iPhone, Keychain rights depend on the provisioning profile used to sign your application. Be sure to consistently use the same provisioning profile across different versions of your application.
Because my Provisioning Profile was expiring, I renewed it (in the provisioning portal), downloaded it, and double-clicked it which "installed" it into XCode's organizer.
After submitting an update to the app to the app store, I'm basically seeing an empty keychain (user's are being asked to log in again).
My question is: does renewing the provisioning profile used to sign an app affect keychain access when the renewed profile is used to submit an update to the app? The docs just say to use "the same provisioning profile", but is unclear about whether a renewed profile counts as a different profile (as my experience described above suggests).
What gives?
Update
Solved with help from tc's answer. Looking at the embedded.mobileprovision
file in each of the .ipas submitted to apple revealed that an expiring certificate and provisioning profile were used to sign version x of the app, and a different certificate and provisioning profile was used to sign version x+1 of the app (culprit: "Automatic Profile Selector" feature of XCode for the Code Signing Identity).
The 1st certificate and profile were leftover from when a developer used a different iOS Developer Program account to develop an unrelated app (on the same machine, with the same OSX user). Provisioning profiles across multiple iOS developer program accounts are apparently all stored together in ~/Library/MobileDevice/Provisioning Profiles
, so they are all candidates for XCode's automatic profile selection feature.
I changed the code signing identity by selecting a totally different distribution profile that I mistook as a renewed/valid version of the expiring distribution profile, and submitted an update. Same app, different cert, different provisioning profile == empty keychain. D'OH.
When an Apple iOS provisioning profile expires, device users cannot access the associated application, and new device users cannot install the application.
The profiles resource represents the provisioning profiles that allow you to install apps on your iOS devices or Mac. You can create and delete provisioning profiles, and download them to sign your code. Provisioning profiles include signing certificates, device identifiers, and a bundle ID.
When a Distribution Certificate is about to expire, you must create a new certificate and then create new App Store and Ad Hoc Provisioning Profiles that use the new certificate. These files are uploaded to the mag+ Publish portal where you then rebuild your app and submit an update to iTunes Connect.
A Distribution Provisioning Profile is a combination of your App ID and Distribution Certificates. It authorizes your app to use particular services (like Push Notifications) and ensures that your app is submitted by you.
The keychains you're allowed to use is determined by keychain-access-groups
in the entitlements, which is limited to a subset of the keychain-access-groups
in the provisioning profile, which is determined by the "bundle seed"/"prefix"/ (ApplicationIdentifierPrefix
in the provisioning profile), set in the "App ID".
Assuming you've kept the old submitted app (or have the .ipa
from iTunes, which is just a zip), look at embedded.mobileprovision
in both the old and new apps (less Foo.app/embedded.mobileprovision
in a terminal should do the trick, or you can open it in a text editor although sometimes they'll pick the wrong line endings). You're looking for something like this (you may see extra keys for push/iCloud):
<key>Entitlements</key>
<dict>
<key>application-identifier</key>
<string>A1B2C3D4E5.com.example.MyApp</string>
<key>get-task-allow</key>
<false/>
<key>keychain-access-groups</key>
<array>
<string>A1B2C3D4E5.*</string>
</array>
</dict>
You can also view the actual entitlements your app was signed with:
codesign -d --entitlements - Foo.app/Foo | vis
IIRC the keychain access groups default to e.g. A1B2C3D4E5.com.example.MyApp
, but you can set this to anything you want provided it matches A1B2C3D4E5.*
(Xcode 4 even has a nice GUI entitlements editor). If the bundle prefix is different, that'll cause the problem you're seeing. I think you can change it back provided you haven't enabled push/Game Center/etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With