Demystifying iOS Signings
Welcome to the rescue zone. If you have come so far, it is probably because you found yourself cursing Apple for their iOS signing process and the confusion around it. Stay calm, we have all been there and survived to tell.
This is not another how-to article. Plenty of those exist around. Here, I will try and draw a higher level picture of how the iOS signing work. Getting a mental model of the process is useful when things go less smoothly and you need to trouble shoot your errors.
This article is written and published on March 2019. XCode 10.2 is the current version. This is important as Apple keeps changing its signing methods and capabilities, so at some time this article will also become obsolete.
(What is this good for? Skip this if you are already convinced signing is important).
There are 2 reasons that applications need to be signed:
- To allow Apple to authorize each app before it is available for users and signing the app ensures that the app has not been modified by bad people and that no malicious code into your app.
- To allow Apple make heaps of money by limiting builds to run only on Macs and by charging for its developer’s account license.
The Apple “Closed Garden” philosophy drives them to not only limiting the applications downloaded from the App Store, but anything installed on your device. So if you are now developer that built a beautiful shiny Tinder for cats, you will not be able to install it on your device unless you will get an explicit signed permission from Apple to do so.
And this is where the whole mysterious process of application signing starts.
The Signing Entities
(The participants in iOS signing hell)
There are 3 things Apple needs to know to allow you installing any app on any device: Who? What? Where?
- Who — a certificate will identify the owner
- What — the application to develop and install
- Where — on which devices the apps will be installed.
Let’s start with the easy one:
A unique device identifier (UDID) is a 40-character string assigned to Apple devices. In the mac it can be found by accessing the hardware info. On iPhone / iPad this site can help finding it: http://whatsmyudid.com/
Next is the Application identified. This is something that you can make up:
Application Identifier (App Id / Bundle Id)
This is a key that identifies your application. It is customary to have the App Id as a reverse order of the domain, e.g. com.company.app. Application IDs are owned by a team and therefore they need to be registered on the Team developer portal.
The application Id needs to be registered on the team’s developer portal. Each app also specifies what Apple services to be used. Such services can be push notifications (via APS → Apple Push Services. Only apple can push notifications to devices), iCloud, Siri and so on.
[To be really accurate the com.company.app is called the bundle Id. The App Id is a combination of the Team identifier and the Bundle ID, such as ABCD1234.com.company.app]
The most complex one is the certificate.
The certificate’s goal is to verify that a person or a team is the true owner of the application, and that its identity cannot be stolen by another person. A person is identified by its Apple Id, and it can also belong to a team.
A development team is created on the Apple Developer Portal and the administrator can add additional developers to it. Adding developers (with certain privileges) mean that the team administrator is trusting them to distribute the application on his behalf.
A new application is defined on the provisioning portal and the users are becoming the owners in this application. But how can someone tell if an App was actually modified only by this user? For this the user can generate a signing certificate. A signing certificate works (very loosely) like a broken heart necklace. Apple holds one half of the necklace and the user needs to present the other half when changing the application so Apple will know they are who they said they are.
A certificate is identified by a string of 8 characters and also contains the name of the certificate holder (developer or team). There are 2 types of certificates:
- Developer certificate is generated for a specific person, or in fact a single Apple Id and can used during development (we will see how in a moment)
- Distribution certificate, as the name implies, allows distributing the application for users who are not the developers. The distribution certificated is generated to an organization or a team (which might be only a single person).
(Putting them all together)
As described above, apple wants to make sure what software is installed on which device. A provisioning profile is where everything comes together: it tells who is the authorized user, what is the application and which devices can be used.
There are 4 different types of provisioning profiles used in different stages of the application development:
- Development — this is used to enable a developer install the application during development to specific devices during the development process. The device needs to be connected to the development computer. This provisioning profile is using a development certificate, and the devices that will be used need to be registered and installed.
- Ad Hoc — This enables user to install the application on a known and limited number of devices for testing purposes. The devices do not need to be physically connected to the development computer, but they are need to be known and registered on the development portal. Although this provisioning profile is a using a distribution certificate, an application signed with adhoc provisioning profile cannot be uploaded to the App Store.
- App Store — this is the provisioning profile that is used for distributing the application to the app store. It uses a distribution certificate, but is not limited to specific devices.
- Enterprise — a 4th type of provisioning profile is aimed for larger organizations that want to control which applications are limited on their users’ devices. It requires joining Apple Enterprise program (yes, more money!) and is using special registration.
Each provisioning profile has a unique identifier The provisioning profiles are signed and embedded in the application, but a short googling will tell you how to extract it from the packaged IPA.
The Provisioning files themselves are signed and cannot be viewed just by looking at the file, but thanks to this guy https://github.com/ealeksandrov/ProvisionQL, you can install a finder add-on that will show you all the information inside easily.
The signing Verification Process
(What do they do with it?)
The last part is to explain, in a very high level, how the provisioning profile verification work. But first let’s talk about 2 tools involved in the process:
- Keychain is a safe that knows how to store secret items (and in fact is a nice UI for the openssl protocol used for Apple security).
- XCode build tools (and the UI) know how to sign the application with the correct signing profile.
Step 1 — Generating Signing certificate
- An authorized user logs into the developer portal and requests a signing certificate for itself.
- The user generates a private key locally (a half of broken heart) and sends a reflection of it to Apple via the developer portal.
- Apple creates the certificate (the other half of the broken heart) based on the private key signed.
- The newly created certificate is installed in the development computer of the user. The certificate is only valid when it is paired with the private key signed.
Step 2 — Generating the Provisioning profile
- The singing certificate is registered on the portal, and now the user can log into the portal and request a provisioning profile. The user specifies the application and the type of provisioning profile that is requested.
- For development or adhoc provisioning profiles the user specifies the devices from the list of registered devices.
- For development provisioning profile the user may define a set of valid development certificates that can use the same provisioning profile.
- The user downloads the provisioning profile to the development machine. The default location for storing the provisioning profiles is ~/Library/MobileDevice/Provisioning Profiles.
Step 3 — Building the application
- Application is built and signed on a development computer. The signing is done with a provisioning profile that fits what is specifies in the xcode signing properties.
For a debug signing a provisioning profile that has a development certificate is required, and for release signing a distribution certificate will be needed. Of course, only provisioning profiles that were generated for the specific application that is built can be used.
If the app is aimed for App Store distribution it needs to be uploaded via the iTunes Connect portal. App that has any provisioning profile other than App Store will be rejected.
If you use the automatic signing, XCode will attempt to find a suitable provisioning profile, but if it will not find one it will simply access the developer portal APIs and generate a new one according to the type of build.
Step 4 — Installing the Application
The last step occurs when a user tries to install the application.
- If the application is downloaded from the App Store after it has been approved, it can installed on any device (there are some limitation such as regional, but this will be ignored for the time being).
- If the app is Ad Hoc or Development, when attempting to install on a device, the UDID will be checked and the installation will be approved or rejected.
(Can we avoid the mess?)
If you have been working with iOS applications for a while in an organization, you might have learned about Fastlane. Fastlane has multiple tools (actions) that can simplify the process of building iOS and Android applications.
Fastlane tools allow you to perform the certificates and provisioning profiles generation without the need to access the developer portal. It is even more useful as it let’s you share provisioning profiles between users on your team using a shared git repository, such as one on Github. All certificates used by the team will be stored on the git repository and users can use them to build their application without the need to access the developer portal.
Fastlane documentation is quite comprehensive for each action, but somewhat lacking on explaining the concepts. It is useful to know that Fastlane has 3 actions that are relevant for iOS signings:
- Cert (alias for
get_certificates)— allows managing certificates profiles
- Sigh (alias for
get_provisioning_profile) — allows managing certificates profiles
- Match (alias for
sync_code_signing) — allows synchronizing certificates and provisioning profiles with the centrally managed repository of certificates and provisioning profiles.
With this understanding, you can now go back to fastlane documentation and learn more about the different options.
I am no hacker or security expert. My first experience with iOS signing was a terrified one. I have noticed my company’s team certificate on my keychain and was sure that accidentally deleting will make our application access lost forever. The truth is that no actions done locally can harm the application in an irreversible manner. At worse, you will need to generate a new profile or certificate. (Note: Developer portal and iTunes Connect can have more destructive impact).
If this article has reduced your level of anxiety from Apple signing and helped clarifying things. If you have found some horrible mistakes, do point them out. I would hate to mislead people. If you find this helpful , a clap, a share, or both will be highly appreciated.