How to manage iOS Provisioning Profiles
While the process of managing iOS Provisioning profiles continues to be refined by Apple, it still is not a totally obvious process, especially when it comes to some of the finer details like updating profiles, ensuring you have all the data associated with signing like your public and private keys for the certificates and how to create a setup that is easy to backup and maintain.
Here I am going to share with you how I manage my provisioning profiles, and it’s my hope that doing so will make it easier for you to manage yours. Using this setup I am able to manage and use a number of different accounts without confusion between them (i.e., I am able to ensure client privacy and confidentiality) and with only a slight headache due to Xcode’s not providing a way to specify which keychain to use for a project, even though the actual program Xcode uses for signing takes a keychain parameter.
NOTE: I highly recommend turning off Xcode’s auto-management of profiles! While this does work well for single person development, it creates confusion when multiple developers are wanting to manage signing profiles and application ids. It’s better long term to take a bit of extra time to setup an organized system for creating and updating this information vs letting xcode handle it, as this will save a lot of time down the road when it comes to managing more applications, developers, and devices. (i.e., instead of having to have 10 developers add a new device to their profiles, you can add it once to a single profile).
We want to keep things organized in a way that lets us manage all aspects of the provisioning setup, so the first step is perform some setup:
- Create a unique keychain to store your certificate signing information in. Even if you do not want to use a unique keychain for development (it does add an extra step and can be somewhat of a pain), you do want to use a unique keychain during the setup process so that you have a clean storage bin for the signing keys and certificates. Without this it can be quite difficult to locate your keys for instance Also, once done, you can copy all the items to your login keychain and just save the unique keychain as a backup.
- Create a folder named AppStore in your documents folder, or anywhere else that gets backed up by Time Machine or whatever backup solution you are using. You are using some type of backup solution, right? (I also create an alias to this on my desktop for ease of access, but that’s up to you.)
- Create an alias to the provisioning profiles folder on your desktop. The provisioning folder is located at “~/Library/MobileDevice/Provisioning Profiles” (where ~ is your user folder, for example “/Users/jsmith”). We do this because it allows us to determine which profiles are what, as apposed to the automated install process).
Generating a Certificate Signing Request (CSR)
OK, now we are ready to start the typical setup for the store. I am going to assume that you have not done this already, or that you are willing to start from scratch. If you already have any certificates, you need to revoke them from both the development and distribution tabs before beginning!
The first step is to create a signing certificate. For the sake of completeness, I am including the section from Apple’s docs on this below, with minor modifications for improving management of the resulting data:
To request an iOS Development Certificate, you first need to generate a Certificate Signing Request (CSR) utilizing the Keychain Access application in Mac OS X Leopard. The creation of a CSR will prompt Keychain Access to simultaneously generate your public and private key pair establishing your iOS Developer identity. Your private key is stored in the login Keychain by default and can be viewed in the Keychain Access application under the ‘Keys’ category. To generate a CSR:
- In your Applications folder, open the Utilities folder and launch Keychain Access.
- From File menu, select “New Keychain…” and create a new keychain located in the default location (~/Library/Keychains). I suggest naming the keychain something like “AppStore_MyCompany” so it’s easily identifiable. Choose a password that you do not mind sharing should the need arise to share your AppStore login information. This is handy, for instance, in cases where the CEO of a company is the store agent but the CTO is the one that will actually be creating the AdHoc and AppStore builds.
- Your new keychain will then appear in the keychain list on the left side of the keychain window. Click on it to select it, and then from the File menu choose the last item, “Make keychain <your keychain name> default”. This will set your new keychain to be used as the first place to look for keychain data or for storing new information. The main benefit is that the public/private keys used for the certificate you are about to create will be easily found.
- In the Preferences menu, set Online Certificate Status Protocol (OSCP) and Certificate Revocation List (CRL) to “Off”.
- Choose Keychain Access -> Certificate Assistant -> Request a Certificate from a Certificate Authority. Note: If you have a noncompliant private key highlighted in the Keychain during this process, the resulting Certificate Request will not be accepted by the Provisioning Portal. Confirm that you are selecting “Request a Certificate From a Certificate Authority…” and not selecting “Request a Certificate From a Certificate Authority with <Private Key>…”
- In the User Email Address field, enter your email address. Please ensure that the email address entered matches the information that was submitted when you registered as an iOS Developer.
- In the Common Name field enter your name. Please ensure that the name entered matches the information that was submitted when you registered as an iOS Developer.
- No CA (Certificate Authority) Email Address is required. The ‘Required’ message will be removed after completing the following step.
- Select the ‘Saved to Disk’ radio button and the ‘Let me specify key pair information’ checkbox, then click ‘Continue’.
- You will be prompted for a location and filename to save your CSR. Use the default filename, and save it to the “AppStore” folder you created during the setup steps.
- In the following screen select ‘2048 bits’ for the Key Size and ‘RSA’ for the Algorithm. Click ‘Continue’.
- The Certificate Assistant will create a CSR file in your AppStore folder.
Requesting Your Certificates
Next you need to submit your CSR to the Apple iOS Provisioning Portal for approval. Using your agent login information, perform the following steps:
- Log in to the iOS Provisioning Portal, navigate to ‘Certificates’ > ‘Development’ and click ‘Request Certificate’.
- Click the ‘Choose file’ button, select your CSR and click ‘Submit’. If the Key Size was not set to 2048 bits during the CSR creation process, the Portal will reject the CSR.
- Upon submission, Team Admins will be notified via email of the certificate request.
- As the team agent, your requested certificate will be automatically approved one it has been issued, unlike requests from admins or developers where each request must be approved by the agent or by an admin.
- Repeat the process in the Distribution tab. (Development profiles are used for debugging and profiling, while Distribution profiles are used for AdHoc (testing) and App Store (submission to Apple) builds.
Downloading and Archiving Your Certficates and Keys
After your certificate has been issued, which should take only a minute or two but sometimes longer, you need to:
- If you have not already done so, download the WWDR intermediate certificate.
- Download both the distribution and development profiles. These will be downloaded to your default download folder, and named (at the time of this writing) ‘developer_identity.cer” and ‘distribution_identity.cer’.
- Copy both signing certificates and the WWDR intermediate certificate to your AppStore folder, along side the signing request file. I also highly recommend renaming your two signing certificate files by prefacing each with your name, for example ‘jsmith_developer_identity.cer’, so that you can distinguish them from other identity certificates you may request or download in the future.
- Add the WWDR intermediate certificate and your two signing certificates to your AppStore keychain created in the setup steps. The easiest way to do this is to select the AppStore keychain in the Keychain Utilities application window, and then drag each file from the finder into the keychain listing window (which at this time should only have the public and private keys generated during the creation of your CSR).
- Once you have added the certificates, I recommend you export the public and private keys to your AppStore folder as a backup. To do this, right click on each and select “Export…” from the popup menu. Again, I recommend prefixing the saved file name, for example “jsmith_Public.pem” and “jsmith_Private.p12”. (Note that the public and private keys are exported in different formats.)
Generating an App ID
Next you will need to create an application ID, if you have not already done so. The following is from Apple’s How To on the subject, however before jumping into that I would like to advise paying close attention to the wildcard references. Specifically, unless you have an actual need, you should only use a single Bundle Seed ID for all of your app id’s. In addition you should create a ‘company wildcard’ app id, that looks something like “8E549T7128.com.apple.*”, and can be used to sign any of your applications that do not need specific id’s (ie, for instance to use Push Notifications, In App Purchase or Game Center).
Note that if you use * to create a wildcard that looks like “8E549T7128.*” then that app id can be used to create a profile that will sign any application, useful for instance if you are a developer working on another company’s application as you do not need a signing profile from that company (you can use yours). However, such a signing profile can also cause issues, as it can override desired signing profiles! In other words, the full wildcard is powerful, but also dangerous so use with caution.
An App ID is a unique identifier that iOS uses to allow your application to connect to the Apple Push Notification service, share keychain data between applications, and communicate with external hardware accessories you wish to pair your iOS application with. In order to install your application on an iOS based device, you will need to create an App ID.
Each App ID consists of a universally unique 10 character “Bundle Seed ID” prefix (generated by Apple) and a “Bundle Identifier” suffix that is entered by a Team Admin in the Provisioning Portal. The recommended practice is to use a reverse-domain name style string for the “Bundle Identifier” portion of the App ID. An example App ID would be: 8E549T7128.com.apple.AddressBook.
If you are creating a suite of applications that will share the same Keychain access (e.g., sharing passwords between applications) or have no Keychain Access requirements, you can create a single App ID for your entire application suite utilizing a trailing asterisk as a wild-card character. The wild-card character must be the last character in the App ID string. Example App IDs for this situation could be: R2T24EVAEE.com.domainname.* or R2T24EVAEE.*
In these wild-card situations, you’ll simply replace the asterisk with whatever string you wish in the CF Bundle Identifier field in Xcode.
- Team Agents or Team Admins should navigate to the ‘App ID’ section of the Provisioning Portal.
- Click ‘Add ID’.
- Enter a common name for your App ID. This is a name for easy reference and identification within the Provisioning Portal.
- Enter a Bundle Identifier in the free-form text field. The recommended usage is a reverse-domain name style string, e.g., com.domainname.applicationname. For a suite of applications sharing the same Keychain access, you should use a wild-card character in the Bundle Identifier (e.g., com.domainname.* or *). This Bundle Identifier will need to match whatever CF Bundle Identifier you use for your application in Xcode.
- Click ‘Submit’. At this time, the 10 character Bundle Seed ID is generated and concatenated with the Bundle Identifier you entered. This resulting string is your App ID. Note: The Bundle Seed ID does not need to be entered into Xcode.
- Generate a new App ID for each set of applications with shared Keychain Access needs. If you are creating a suite of applications that will share the same Keychain access (e.g., sharing passwords between applications) or have a set of applications with no Keychain Access requirements, create a single App ID for all applications utilizing a trailing asterisk as a wild-card character.
Creating Your Provisioning Profiles
The final step is to create the actual provisioning profiles you will use to sign your applications. Provisioning profiles are created by associating application ids with devices and determining which developer certificates are allowed to sign the profile. Typically you will want to have all of your developers able to sign each development certificate. A copy of Apple’s How To guidelines for doing so are below.
Note that for security purposes Apple only allows the team agent to sign AdHoc and AppStore provisioning profiles. While this does make sense and I believe was a good decision on Apple’s part it is not always the case the agent will either be able to or want to create app builds. By creating a separate keychain for the AppStore we simplify the secure sharing of the information needed to sign AdHoc and AppStore builds with another person or persons within the company.
A Provisioning Profile is a collection of digital entities that uniquely ties developers and devices to an authorized iOS Development Team and enables a device to be used for testing. A Development Provisioning Profile must be installed on each device on which you wish to run your application code. Each Development Provisioning Profile will contain a set of iOS Development Certificates, Unique Device Identifiers and an App ID.
Devices specified within the provisioning profile can be used for testing only by those individuals whose iOS Development Certificates are included in the profile. A single device can contain multiple provisioning profiles.
- In the ‘Provisioning’ section of the Portal, Team Admins should click ‘Add’ on the Development tab.
- Enter a name for the provisioning profile. I recommend the following naming convention here (where, if you are creating a wildcard profile MyApp would be Wildcard): “MyCompany_MyApp_Dev_001”
- Specify which devices will be associated with the provisioning profile. You must specify a device in order for that device to utilize the provisioning profile. If a device’s UDID is not included in the provisioning profile the profile and your application cannot be installed on that device.
- Specify which iOS Development Certificates will be associated with the provisioning profile. You must specify an iOS Development Certificate in order for the application code signed with that same certificate to run on the device.
- Specify a single App ID for the Development Provisioning Profile. Each Development Provisioning Profile can specify only ONE App ID, therefore, if you have applications requiring different Keychain access, you will need to create a separate Development Provisioning Profile for each of those applications. If you are installing a suite of applications with the same required Keychain access or have a set of applications not requiring access to the Keychain, use an App ID containing the wild-card asterisk character to build all of your applications.
- Click ‘Submit’ to generate your Development Provisioning Profile.
Repeat the process for your distribution builds, noting that you need to create one for both the AdHoc and AppStore for each App ID you wish to use. I recommend the following naming convention here (where, if you are creating a wildcard profile MyApp would be Wildcard):
- AdHoc: “MyCompany_MyApp_AdHoc_001”
- App Store: “MyCompany_MyApp_Store_001”
Downloading and Archiving Your Provisioning Profiles
Once you have created your development, adhoc and appstore profiles you need to download them. Typically by the time you have completed creating the distribution profiles your development profile will be ready, and by the time it’s done downloading your distribution profiles will be ready. After these are downloaded, move them to your AppStore folder created during the setup steps. Assuming your user name is “jsmith”, you have created only one AppID, “Wildcard”, and that your company name is “MyCompany”, you should have the following items in your AppStore folder at this point:
- MyCompany WildCard AdHoc 001.mobileprovision
- MyCompany WildCard Dev 001.mobileprovision
- MyCompany WildCard Store 001.mobileprovision
In your AppStore keychain you should have the following items:
- Jeff Smith (public key)
- Jeff Smith (private key)
- iPhone Developer: Jeff Smith (certificate)
- iPhone Distribution: MyCompany (certificate)
Backup Your Data
Before you do anything else, take the time now to archive your AppStore folder and keychain! That way, if anything goes wrong you have something to recover with.
Installing Your Provisioning Profiles
Now, instead of installing provisioning profiles in the Apple recommended way I instead recommend installing them manually. The reason I do this is because the automated installer will rename the files, making it difficult to later determine which files belong to which profiles. Of course, you can manage all of that in Xcode’s Organizer, so this is strictly a ‘nicety’ feature that I have found useful.
Installing profiles manually is actually very easy, especially if you have created the “Provisioning Profiles” alias recommended in the setup steps. To do so, simply copy the profiles you wish to install from your AppStore folder (i.e., the “.mobileprovision” files) to the Provisioning Profiles folder alias. Easiest method is to select the files, start dragging them to the alias and while doing so press the option (i.e., alt) key which will cause the drag operation to display a plus (+) indicator to let you know the files will be copied instead of being moved.
Updating a Provisioning Profile
Once a provisioning profile is created you will often find the need to update it to renew the profile (development profiles expire after 3 months, AdHoc and AppStore profiles expire after 12 months). This can be accomplished by following these steps:
- Log in to your iOS Developer account and go to the iOS Provisioning Portal (a link should be found in the upper right of the main page)
- Click on the Provisioning side tab, which will display the provisioning view (which has a development and distribution tab, plus history & how to)
- For each profile you want to update, click on the “Edit” link on the right side of the window (next to the Download button). This will display a pop-up menu with two options, “Modify” and “Duplicate”. You want to choose the “Modify” option.
- On the Modify screen you can update who can sign the profiles (i.e., which certificates to use) and what devices the certificate will work with. Typically you never want to change the AppID but you can do so if needed. Finally, a step I have found incredibly useful is to always update the name to indicate a new “version” is being created. I do this even if I am just going to renew the profile (although in this case you have to check the new button first). If you used the naming convention I provided in the setup steps, you might change the name from “MyCompany Wildcard Dev 001” to “MyCompany Wildcard Dev 002” for instance. Of course, you can use any naming style you wish (ex: a, b, c) but updating the name each time will allow you to easily determine if a developer, tester, reviewer, manager, etc., is using the correct profile when they have installation issues, or when you have signing issues in Xcode.
Using Provisioning Profiles With a Single Account
- If you only have one developer account to worry about, then the easiest way to use your provisioning profiles will be to copy the items from your company keychain (your private/public keys and development/distribution certificates tied to those keys) to your login keychain. This can be done just as it is in the finder, by dragging the items while holding down the Option (alt) key from the AppStore keychain to the login keychain. Of course you will need to open the AppStore keychain in the Keychain Access application before you will be able to do this. You should be able to double-click on the keychain to open the Keychain Access file, but you may have to use the “Add Keychain” item from the File menu (of the Keychain Access application). Your added keychain will show up in the “Keychains” list on the left side of the Keychain Access window (the left side should have a Keychains and a Category list).
Using Provisioning Profiles With Multiple Accounts
- If you have more than one iOS developer account you need to develop for (i.e., you have multiple clients for instance) there are two methods that can be used to do so cleanly, and which one you use would depend on you situation:
- Use a Wildcard profile – While I don’t consider this very useful anymore, if you only need to make debug/release (i.e. development) builds, never need to build AdHoc or AppStore releases, and either are provided a profile or have your own iOS developer account but never create your own apps, then you can use a wildcard profile for all of your development. Such a profile would use an AppID of ‘*’ (displayed as something like “8E549T7128.*”) and will work no matter what the App’s bundle identifier is. The downside is that this ID is likely to be used for all signing, preventing you from signing an AdHoc build in another project for instance, and possibly being used in other projects where you would not want it. Note: this wildcard profile is different from a company wildcard profile! A company wildcard looks like “8E549T7128.com.mycompany.*” and can be used to sign any company app, but will not work for signing apps from other companies/clients.
- Use multiple keychains — this is the method I use personally, and it works pretty well. It would actually work perfectly if Apple would update Xcode to allow specifying which keychain to use in a project (i.e., as part of the personal data associated with a project). But that’s not the case, so it’s a bit messy: to use this method you have to use Keychain Access and set the desired keychain as the “Default” before Xcode will use the information it contains. And, because of that, your AppStore keychain is likely to become cluttered with un-related entries like iChat certificates, etc. So you want to set the “login” keychain back to being the default as soon as possible.
- Multiple keychains + a Wildcard profile – I actually keep a wildcard provisioning profile for my personal account around for cases where I don’t have any credentials for a client’s account. In this case I’ll temporarily add the wildcard profile to my Provisioning Profiles folder to allow me to create builds of their application, and then remove it again when no needed so that it doesn’t get in the way of other development.
That’s it, hope this helps!