I work with a team that is responsible for our company's centralized infrastructure for code signing various products within our portfolio, including iOS apps. For security purposes, we want to sign apps before their posting on the App Store, and also to log this activity for eventual security audits. Not surprisingly, we need automated processes; we can't use an IDE like Xcode to do the work. We must queue, process, and log all signing jobs, and have Macs dedicated to this purpose.
I can't go into many details about our infrastructure due to confidentiality concerns, so I'll apologize now if my questions seem a little vague.
We currently require our iOS developers to submit one or more new provisioning profiles as well as their IPA archive for signing. We support supplying multiple provisioning profiles because some of our developers include embedded third-party extensions within their IPAs, and these extensions can also have their own provisioning profiles. Within our back end, we open the archive, sign the relevant portions using the entitlements in one of the profiles (that we believe to be the appropriate one for the particular archive element), overwrite each supplied provisioning profile with (what we believe to be) the appropriate one from user input, and re-compress the archive.
Here come the questions:
-
When we receive multiple provisioning profiles, how do we know which profile should be used to help with signing which archive elements? What data (e.g. entitlements application-identifier, team-identifier) can we use?
-
We also need to know which provisioning profiles from their input correspond to those that already exist within the archive. What data can we use to map profiles from one set to the other?
-
Should we be requiring our users to submit new provisioning profiles in the first place? Or should we edit/recycle the existing ones in some way? We'd like to remove any unnecessary burdens for our users, if possible.
Lemme me be clear about one big picture point: DTS doesn’t support folks re-signing .ipa
files. From our perspective, the format of an .ipa
file is not documented for third-party use.
The technique we recommend instead is to have your developer’s submit an Xcode archive (.xcarchive
). You can then export a .ipa
from that archive, allowing Apple to take care of all the re-signing complexities.
If you need to automate that, xcodebuild
can do it via its exportArchive
command.
Still, it’s certainly true that a lot of folks do re-sign .ipa
files. IMO this is Working Too Hard™ and they should just change their process. Clearly there are other opinions (-:
But the unsupported nature of this task explains why you’ve been having such a hard time finding definitive answers about it. We generally don’t document unsupported processes.
If you are committed to this re-signing .ipa
approach, the place to look for answers is the Mac code signing documentation, because DTS does support code signing by hand for Mac products. Specifically:
-
Check out Creating distribution-signed code for macOS. This explains the general process for re-signing a Mac app, and iOS apps are quite similar [1].
-
Also read the Inside Code Signing technote series, which collectively explain how this stuff actually works.
-
If you’re ever in any doubt, use Xcode to export an archive as an
.ipa
then look at the log of what it did.
Now, let’s come back to your specific questions:
When we receive multiple provisioning profiles, how do we know which profile should be used to help with signing which archive elements?
A profile is tied to its executable via the App ID entitlement. See The what section in TN3125 Inside Code Signing: Provisioning Profiles.
Note that a profile can apply to a wildcard App ID. IMO wildcard App IDs cause more problems than they solve for production code [2], so if I were in your shoes I’d not support them.
We also need to know which provisioning profiles from their input correspond to those that already exist within the archive. What data can we use to map profiles from one set to the other?
Again, this is the App ID.
Should we be requiring our users to submit new provisioning profiles in the first place? Or should we edit/recycle the existing ones in some way?
You can’t edit a provisioning profile. It’s signed by Apple, and it must be signed by Apple to be effective.
You could build infrastructure to create a distribution profile for the code that you ship. The easiest way to do that is to switch to using an Xcode archive, and then xcodebuild
can take care of that for you. If you don’t want to do that, look at the App Store Connect API.
If you have any follow-up questions, post ’em here. It’s good to get this stuff written down.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] There are important structural differences between iOS and macOS apps. We touch on that somewhat in Placing Content in a Bundle. Some of that stuff is cosmetic — iOS apps use the ‘shallow’ bundle structure whereas macOS apps use the ‘deep’ one — but it’s more than just that. Notably:
-
iOS frameworks and Swift system libraries must be at the top level.
-
iOS doesn’t support third-party standalone dynamic libraries.
Still, as someone who’s trying to re-sign an app, that doesn’t actually matter, because you can assume that each team will give you a correctly structured app. If they don’t, that’s on them.
[2] They create for small test projects though.