Demystifying the iOS App Provisioning Process
You’ve probably heard the story of the blind men and the elephant. Each of the blind men grabs a different part of the elephant. The guy with the tail thinks an elephant is like a rope. The guy with the leg thinks the elephant is like a tree. I can appreciate their confusion.
Most of the documentation for iOS certification and provisioning is like that. It tells you how to create a single piece of the puzzle, but it doesn’t tell you why you need it. And certainly doesn’t tell you how it fits into the larger picture of iOS app provisioning. I hope to provide that information with this post.
Who Is This Post For?
I assume that you want to set up provisioning for your app and that you have spent at least a little time with Xcode (check out my other piece on tweaking Xcode to simplify your build scripts) doing iOS development and are comfortable using your Mac for development.
What Is All This For?
You might be wondering why iOS apps need provisioning in the first place. The reason is that Apple wants to provide a safe and stable experience for the end user. To that end, they want to make sure they can:
- Ensure that a piece of code has not been altered since it was signed.
- Identify code as coming from a specific source (a developer or signer).
- Determine whether code is trustworthy for a specific purpose.
In order to accomplish this, they have set up a chain of authority (not unlike the chain of custody for evidence) that links Apple (as the certificate authority) link by link to your compiled application. This chain of authority contributes to the stability for which iPhones and iPads are known.
The Big Picture and the Quick Overview
This is a high-level view of all the pieces in the chain with no detail at all. We’ll run through it quickly to establish a mental map and then come back to discuss each piece in greater detail.
At the top, you’ll see the Apple Certificate Authority. There are other certificate authorities, but Apple is the only authority that will allow you to push your app to App Store Connect (previously iTunes Connect). App Store Connect is the gateway to the Apple store.
One of the first things you do as an iOS developer is to create a Signing Certificate. The Signing Certificate guarantees that you are you and that Apple knows about you. The process for doing this is explained completely in the Apple documentation. The gist is that you create a public/private keyset on your development computer that you give to Apple. This process links the Apple Certificate Authority and you (or your team) in the creation of your signing certificate.
Then for each application or app extension, you create an App ID. The App ID links your signing certificate with your app (identified by its bundle ID).
Finally, you create one or more Provision Profiles. Each profile declares links to one of your App IDs and declares whether a particular build is destined for internal development, Ad Hoc distribution, or release distribution through the store. For internal development and Ad Hoc distribution, it may also contain the list of devices where the app may be tested or distributed.
That’s all the major players in the provisioning drama. But the devil is in the details and now we need to look at each piece of the provisioning puzzle in greater detail.
The Signing Certificate
There are two flavors of signing certificate – development and distribution. A development certificate identifies you as a developer and contains your developer identifier. A distribution certificate contains your team identifier and identifies your team. Both certificates are useful, but only the distribution certificate can be used to sign apps intended for the App Store. Also note that even if you sign up as an Apple developer as an individual, you will still have both a developer and a team identifier (both these identifiers are short hex strings).
To create a signing certificate you first create a Certificate Signing Request using the keychain Access app on your Mac. This creates the public and private keys that will identify your certificate. You then upload the request to developer.apple.com where you can turn that request into a certificate. The resulting certificate guarantees that you know Apple and they know you (or your team). Recall that when you signed up for your Apple ID, you gave them your credit card information or your Dun and Bradstreet number if you signed up as a corporation. When you receive your certificate (in the form of a .cer file), you add it to your keychain so that it’s available to Xcode and the build process. Once you have done all of this, anything signed with your certificate can be guaranteed to come from you.
The App ID(s)
When you create a new application using Xcode, you are required to give it a bundle ID. This is a string that uniquely identifies your application. Apple recommends using a reverse domain name format using your internet address (but reversed). But the only real requirement is that the bundle ID be unique, i.e. your bundle ID cannot already be used by another application preceding it. That’s why Apple recommends the reverse domain name. It makes it less likely that your bundle ID will run into a conflict.
As I mentioned above, every app and every app extension (Watch App or Watch App Extension, for instance) must have its own bundle ID and will therefore need its own App ID. So an iPhone app with an associated Watch App will have three App IDs:
There are also two flavors of App ID – explicit (containing a unique bundle ID) and development (which can use the wildcard app ID). You can recognize wildcard app IDs because they contain (and sometimes solely contain) an asterisk. Wildcard app IDs allow you to develop your applications without deciding what the bundle ID will be - until release time.
There are other ways to create your App ID now; but I recommend creating any explicit App IDs on the developer.apple.com website. Your App ID record will contain a reference to your Team ID. This guarantees that you vouch for this app.
Your App ID record also contains the list of entitlements you wish to use. Entitlements are extra services or behaviors you would like your app to support. Your app will not be allowed to access the APIs for these behaviors unless you have enabled the entitlement in the capabilities tab of the Xcode application and you have enabled the entitlement in the App Services section of the App ID. If you declare a Capability in Xcode that you have not enabled in your App ID, you will get a signing error when trying to run an Ad Hoc or Release build. Entitlement = Capabilities = App Services. I think Apple might be uncertain about what they want to call these things. I won’t be discussing Entitlements further. There is plenty of documentation on what to select when specifying these. Documentation on each of these services discusses what to enter in the entitlements.
Provisioning profiles join together all the information about your app and your team. The provisioning profile includes information about the intended distribution (development, ad hoc, or App Store) and may also include the specific devices it’s targeted at. It is the profile(s), along with the team or personal signing certificate, that validate your app during the build process.
The Device List
In order to use either Development or Ad Hoc distribution, you must specify the device(s) that the app will be loaded onto. In order to do this, you add the UDID and a common name for the device in the Devices list that is part of the Certificates, Identifiers, and Profiles section of the Apple developer website.
In review, then:
- Everything starts from Apple as the signing authority.
- They know who you (or your company) are via your application for your Apple ID through your credit card or your D&B number. Your Apple ID identifies your team and/or you as a developer.
- The App ID identifies a specific application or extension and the reference to the signing certificate identifies it as yours.
- The Provisioning Profile brings all the above together and identifies where and how this app can be distributed.
There are four kinds of app distribution targets. We’ll cover development, ad hoc, and App Store distributions. Enterprise distribution requires a more expensive Enterprise Program ID specific to enterprise development and is less often encountered, so we won’t cover it here.
When you create a Provisioning Profile, you must select which distribution for which the profile is intended:
- An app validated with a development profile may be run and debugged on the simulator or the developer’s device(s) only.
- An app validated with an ad hoc profile may be run on a limited number of test devices. This is useful for distributing to a QA organization, for instance.
- An app validated with an App Store profile may be submitted to the iTunes App Store.
Each flavor of app distribution has its own requirements for what must be contained in the Provisioning Profile, the App ID, and the Signing Certificate.
Development profiles have the most leeway. You may use either a team or an individual signing certificate. You may use either an explicit (fully defined) bundle ID, or you may use the wildcard (*) bundle ID. Finally you must specify which devices the app will be loaded onto.
Ad Hoc Distribution
You must use a team signing certificate. You must use an explicit (fully qualified) bundle ID, and you must refer to a team signing certificate. Finally you also must specify which devices the app will be loaded onto.
App Store Distribution
You must use a team signing certificate. You must use an explicit (fully qualified) bundle ID, and it must refer to a team signing certificate. Finally, of course, you must specify the App Store distribution in the Provisioning Profile.
Assuming you have an app acceptable to the App Store, signing an app using an App Store Provisioning Profile will allow you to upload the app to appstoreconnect.apple.com. However, before you can upload an app to App Store Connect you have to create an entry for it - a place for it to go. You should be aware that part of that process is to specify the bundle ID and app name for your app. Either one of these may be rejected by Apple. The bundle ID and app name are only validated for uniqueness in App Store Connect, not in the developer website. So if you are sure of the app name and bundle ID you want to use, you should create your App Store Connect record early in the development process.
Even when you have an approved App Store Connect record and the app has been uploaded, there is still another (less well known) step. Apple has to evaluate your app and approve it for the app store. At that point, Apple will re-sign it with an Apple certificate and profile.
So it may be true, as Joyce Kilmer says, that only God can make a tree, but only Apple can sign an App Store app.
One More Thing
This post is not complete. I have entirely left out the how-to aspect. But that’s where the Apple documentation is most complete. And having read this post, you should now be prepared to read theirs.
Here is the main Apple provisioning document at the time of this writing.