Cruising through the Complexities of Signing Native Mobile Apps

With the upcoming release of version 10 of OutSystems Platform, we’ve made it easy to build native mobile apps for iOS and Android. While on this journey of bringing you this new feature, we had to address a lot of aspects of mobile app development, including just exactly how developers can sign their apps. Apple and Google require this step when building the package used to install your app in devices so everyone knows who produced that binary and you’re assured that it has not been tampered with.

We knew upfront that signing iOS apps was a complex task that involves certificates, provisioning profiles and handling a number of items on the Apple Developer Program website (where you can manage everything you need to sign iOS apps). However, we also wanted to know more about Google’s mechanisms for signing apps that end up in the Play store.

Therefore, we reached out to teams with mobile app development experience to see how they overcome the challenges associated with this process.

iOS App Signing in a Nutshell (More Like a Coconut Shell)

The iOS app signing process becomes clearer when you have background information about Apple’s developer programs. So let’s take a look.

There are two separate programs for developing iOS apps, both with a subscription fee:

  • Apple Developer Program for building apps to submit to the public iOS App Store.
  • Apple Enterprise Developer Program for distributing apps to members of your organization outside of the App Store and perfect for internal corporate apps.

When you enroll in a program, you can request the two main assets that are needed to build an app:

  • A certificate: A cryptographic asset that effectively and securely signs your app with your own identity;
  • A provisioning profile: A collection of attributes pertaining to how you will use the app binary. It may define the type of binary you produce, the devices where it can run and also Apple services it is authorized to use. Some examples are iCloud, Apple Pay and Push-Notifications.

Apple Developer Program

Here are the Apple Developer Program options:

Let’s break this down a little by development and production.

Development Side

A development certificate is used with a development provisioning profile by developers while they are working in the app’s code, building new features. These builds can only be run on a set of devices that have to be specified on the Apple Developer Center website (up to 100 devices) when generating the provisioning profile. They’re also the only binaries that will include the data necessary to enable debugging the app with Xcode. Furthermore, there are some differences when using some Apple services when comparing to a store build: push-notifications, for instance, will be sent through a “development” infrastructure (a sandbox APNS server).

This is essentially the perfect certificate and provisioning profile combination for a development setup.

Production Side

The production certificate can be used with ad hoc or app store provisioning profiles. Both of these profiles can be used to produce release-grade binaries, with no debug flags, and are similar in nature. They use the same infrastructure for push-notifications.

Ad hoc is great for an internal testing phase, when you want to distribute your app to a very limited number of users. People can just use a link you give them to download the binary and then install it. Of course, their devices have to be registered in the provisioning profile, just like in the development profile. Having to handle this “device list” (maximum 100 once again) can be a hassle, but there are situations where it can also be useful: sometimes you want to make sure that if a pre-release build falls into the wrong hands, it can’t be installed in just any device.

The App Store profile is the one you’ll use to produce binaries to submit to Apple so they can go through the Apple approval process before being made available in the iOS App Store.

Test Flight allows you to invite up to 2000 beta users to install an app before it is released in the App Store and you can use the same binary builds as those for the App Store. Downloads and updates are handled by the Test Flight app in each user device and you can gather feedback. Binaries submitted to Test Flight are reviewed by Apple but it is usually a faster process than that for the App Store (1 day usually).

Apple Enterprise Developer Program

Let’s look at the Apple Enterprise Developer Program now:

As you can see, there are a lot of similarities to the Apple Developer program. The development certificate and provisioning profile combination works the same way and so does the ad hoc provisioning profile with the production certificate.

The main difference is that there isn’t an App Store provisioning profile, but an in house profile instead. It allows you to build a binary for distribution in your organization (Apple’s contractual terms enforce this) with no device restrictions. Users just have to accept your organization as “trusted” when installing the app. There’s no Test Flight option because that technology makes more sense for App Store apps.

And Then There’s Teams…

Now that you know the options for the Apple Developer and Developer Enterprise programs, it’s obvious what a single developer inside an organization can do: enroll in one of the programs, generate certificates and provisioning profiles, and start producing builds.

However, what happens if there is more than one developer working on the same project for the same account? What if some of the developers collaborating on your app are from an outside contractor? Surely you’ll want to control their access to your Apple Program account, your certificates and provisioning profiles. You’ll also want to be able to identify who has generated each specific build. This is where team provisioning profiles come into play.

As the owner of your organization’s Developer Program main account, you can create such a provisioning profile where you register certificates from other accounts and share it with developers. This way, each developer can create a personal Apple account, generate his or her own certificate and sign builds that use it with the shared team provisioning profile. Note that, although the main account must be a paid one, developers do not need to pay a subscription fee just to be able to generate their certificates.

This setup is pretty standard in the mobile app development industry. Organizations have better control of who can access the critical assets for creating production-grade builds and submitting them to the App Store. You can even set up different roles: the person that controls the main account is the team agent. The team agent can assign a team admin role to other trusted members of the organization so they can manage most aspects of the account and a team member role to developers who should only have access to the shared provisioning profile.

The Pains of Getting Your App Signed

One of the main hassles of signing apps has to do with having to reissue one of the assets necessary for building a native app. Imagine, for instance, that a development certificate expires (they have a 3 year lifespan). The developer must go into the Apple Developer Center website to access his or her account, renew the certificate, download it and then reconfigure the tools he or she is using to develop.

When it comes to a provisioning profile, this process happens even more often since there are more reasons for a reissue:

  • Profile expirations, which happen after a year.
  • Changing the list of devices where a binary can run, for an ad hoc or development profile. This happens a lot during demo and testing phases.
  • Changing the app services allowed in the profile or even the developer certificates allowed in a team provisioning profile.

Now suppose you have a large team and are generating builds in several workstations. You have to make sure that everyone is using the latest provisioning profile for everything to go smoothly. The process becomes more complex because there are more places to reconfigure and probably more people involved, and doing everything manually is likely to introduce errors.

As one team leader in a company that has built hundreds of mobile apps once told us, “There’s a running joke here: if the device is new, we’re sure that the first binary that gets installed won’t work!”

To tackle this problem, we’re now seeing development teams automating parts of the process. A lot of developers work using continuous integration setups where code is committed to a version control system like GIT and then a CI system, such as Jenkins, handles the builds.

In recent years, tools have emerged to automate the process of configuring the certificates and provisioning profiles in Jenkins from the ones available in Apple Developer Center. One popular option is Fastlane. This is a series of tools for automating app deployment, which includes Match, Sigh and Spaceship, specifically suited for handling the app signing assets.

This way, development teams can update their certificates and profiles in the Apple Developer Center and rest assured that all the subsequent builds will be performed with the latest assets. In a world where continuous delivery practices and tools are becoming standard, we see that this sort of setup is gaining a lot of popularity.

What about Android?

Android app signing isn’t as complex as it is in the iOS world. There’s only two types of builds: Debug and Release. There’s also nothing similar to provisioning profiles and no need to enroll in a program. You only have to pay a registration fee to Google when you submit your first app to the Play Store.

You sign your app in debug mode during development and in release mode when you are ready to distribute your app.

To sign an app you just need a keystore file that stores the necessary certificate information used for signing. Android developers often do not even deal with this keystore file directly while producing binaries because, by default, Android Dev Studio will sign debug builds with a default certificate to ease the process.

Google recommends that an organization sign all its submitted apps with the same certificate, as it enables secure code and data sharing between apps and also allows them to run in the same process. However, there two important things to take into account when signing Android apps:

  • The certificate should never change: If the certificate used to sign an app is compromised or lost and a new one needs to be generated, a new version of the app is seen by Google Play as a different app. There’s no way to circumvent this. As such, it is very important that you store your keystore in a secure place.
  • The certificate should never expire: If your certificate expires, you have to generate a new one and, again, Google sees that as a different app. Google recommends that you issue your certificates with an expiration date that surpasses the expected app’s lifetime.

As you can see, handling certificates in Android is a simpler process and there are fewer things to take into account. However, Google app signing mechanisms don’t offer as many options as Apple for people looking to secure pre-release builds; an app can generally be installed in any Android device once it is out in the open.

Wrap-up

Signing mobile apps can be a tricky business, especially if we’re talking about the iOS world.

It is important you understand what sort of options you can get from each Apple Developer Program and the best setup for the nature and size of your development team. There are also some issues you may face when dealing with lots of devices and different types of builds, so having the right tools and processes in place will save you a lot of headaches and time related to certificates and provisioning profiles.

The Android world, on the other hand, is a simpler one. But, you should know that keeping your certificates safe is crucial and that there are fewer options for restricting what can be done with each build you produce.

Editor’s Note: João Proença is a devops expert at OutSystems, and spends his days thinking about the safest and fastest way to stage mobile and web applications to end-users.