iOS Code Signing Demystified

, ,
iOS Code Signing Demystified
Reading Time: 4 minutes

If you’re developing an app for iOS, you need to sign your builds in order to send them to App Store or to beta testers. And figuring out iOS Code Signing can be challenging to many.

Whether you’re developing natively using Swift/Objective-C, or using a multiplatform technology like React Native or Flutter, a good understanding of Apple’s Code Signing processes are a must.

This is a comprehensive guide to help you understand how Code Signing on iOS works.

What is iOS Code Signing for?

Code Signing is a way for iOS devices to know that the app to be install on the device is from a known source.

Just like we sign things in real life for authenticity, code signing is similar: we add our unique signature to our app.

There are 3 main concepts in code signing:

1) Certificates
2) Bundle IDs
3) Provisioning Profiles

Certificates

Certificates are the actual signatures, if we continue the methaphor. They are an encrypted file that contains a public-private key pair. There are 2 main kinds of certificates. Development and Distribution.

Development certificates are “signatures” for individual developers that lets them install apps on their personal devices.

Distribution certificates are for distributing the app to others. You can distribute your app to a list of known beta testers (Ad Hoc), or to general public (Testflight Public Beta or App Store) or inside your organization (Enterprise).

To create a certificate, you need to use Xcode’s automatic generator or generate a certificate request using the Keychain Access app on your Mac. Mobile CI/CD tools like Appcircle can also generate this request. Follow the steps explained in our docs to learn both methods:

https://docs.appcircle.io/signing-identities/ios-certificates-and-provisioning-profiles

After we create the certificate, do we sign the app right away? No. We need to determine which signature will be used on which apps.

Bundle IDs

Bundle IDs are unique strings that identify an app. Every app on your Apple devices have a Bundle ID. That’s how Apple and your devices separate your app from others.

For every app that needs to be signed, you need to register its Bundle ID to Apple’s Developer Portal.

Xcode also does this automatically. We’ll go in detail for the caveats of automatic code signing later. If your app has other targets such as an Apple Watch app, a Share extension, an App Clip etc. you need to register additional bundle ID’s for them.

Provisioning Profiles

We’ve created our certificate and registered our app’s bundle ID. Now it’s time to put it all together. You do this with Provisioning Profiles. These are special files that contain which Bundle ID will use which certificate, and the devices that can install the apps created using this file.

When creating a provisioning profile, Apple’s developer portal will ask what type of profile you want to create. Just like certificates, these have 2 main types: Development and Distribution. Development is for to test the apps on registered devices connected to your development computer. You can pick from iOS, tvOS or Mac Development profiles.

Distribution profiles are for distributing apps outside the development team. There are 2 kinds: Ad Hoc and App Store. Ad Hoc is to distribute the app on a limited number of devices. These devices need to be registered by you on Apple’s Developer Portal in order to be able to install it. App Store profiles are to send the app to the App Store or Apple’s Testflight Beta Distribution system.

After choosing the type, developer portal will ask which Certificate will be used for this profile, following with which app will use this profile. If it’s an Ad Hoc profile, final step will show you a list of devices you’ve registered. Pick the ones you want to support.

After creating the provisioning profile, you can now sign your apps for the type of distribution of your choice. Download the provisioning file manually and drag it onto Xcode. Then go to build settings to select the profile when creating a release build.

Adding Devices to Apple Developer

You can add up to a 100 devices for each category (iPhone, iPad, Apple Watch, Apple TV or Mac). You can add a device by obtaining device UDID info. To obtain device UDID, you need to connect your Apple device to your computer. Then use iTunes or Finder app to locate the UDID.

Finder:

Find UDID on Mac - Finder

 

iTunes (Music App):

Find UDID on Mac - Music App

Creating Certificates and Provisioning Profiles via Xcode

As mentioned, you can let Xcode Create these signing identities Automatically for you. You only specify what type of distribution you want for the app scheme you’re building. There are 2 default schemes: Debug and Release. You can specify iOS Development for Debug, and Distribution for Release.

For Ad Hoc Deployment though, you need to do this process manually from Apple Developer Portal.

When you turn on Automatic Code Signing, Xcode will check whether the computer you’re developing on has the correct type of certificates and provisioning profile in its system. If they don’t exist, Xcode creates them from Apple’s Developer portal. Certificates will be added to your computer’s keychain. Provisioning files are different though, you can download those files from Apple Developer Portal.

Managing Signing Identities on Appcircle

Appcircle has a complete signing identity module to handle Certificates and Provisioning Profiles.

For Certificates, you have to upload your certificate, exported with its private key as a .p12 file to Appcircle.

You can also upload provisioning profiles manually, or Appcircle can connect to your Apple Developer Account and provide you a list of profiles to add. To do this, you must add an App Store Connect API Key to Appcircle. Here’s a detailed guide on how to create API Keys on App Store Connect and add them to Appcircle.

Once you add the Provisioning Profiles and Certificates that are used by that profile, you can sign your apps. Appcircle shows a green checkmark on the profile listing. This indicates the corresponding certificates are also saved in your account.

Final step is to add these profiles to the config of your branches. Go to your build profile detail page, and select a branch, then select Config. Go to Code Signing Tab and add entries for each target and its provisioning profile file. We’ll fill the selection with the list of saved provisioning files. Remember, iOS apps with multiple targets have multiple provisioning files. Once you add all the targets, you’re good to go.

Just make sure that Install Certificates and Provisioning Profiles component is inside your workflow.

Where to go from here?

For the more curious, there is a deep dive document on Apple’s documentation about how iOS Code Signing works: https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html

 


Share this post!