Set up code signing for iOS projects
Quick start guide
To get code signing working for your iOS app using our automated code signing support, you would need to do the following:
- Upload your provisioning profile (
.mobileprovision) and private key (
.p12) files in Project Settings > iOS Code Signing.
GYM_CODE_SIGNING_IDENTITYto match your code-signing identity, i.e.
iPhone Distribution: Acme Inc..
- Build with gym and deploy with fastlane.
Background: Code Signing Process
The code-signing process for iOS apps can seem difficult at first, but once familiar with the concepts the process is less daunting.
There are 2 necessary items for signing an app:
- A provisioning profile (
- A corresponding developer private-key (
With these 2 files, and an Xcode project the goal is to produce 2 files:
- A signed application (
- A debug symbols archive (
.ipa file is the application file that can be distributed to your
testers using a service such as
or Hockey App.
The debug symbols file will be used by your distribution service of choice
to produce call-stacks helping you to debug any crashes in your app that
macOS circle Keychain
When signing an app, Xcode will look in any keychains on the machine to find the necessary code-signing credentials. CircleCI creates a keychain containing any code-signing credentials that you have uploaded in Project Settings automatically, so you should not have to interact with the keychain in most circumstances.
The keychain that CircleCI creates is named
circle.keychain, and the
circle. This keychain is unlocked for the duration of the
build, and it is added to the default search path. Any P12 certificates
or provisioning profiles that you have uploaded are added to this keychain
before your build begins. Any futher credentials that you add to this
keychain will be available to Xcode.
1. Install Fastlane tools locally
This guide assumes that you are developing on a Mac running macOS. The first step is to install the Fastlane tools. If you are using the system Ruby, you can install using
sudo gem install fastlane
Or if you are using a Ruby installed using Homebrew you can install as the current user:
gem install fastlane
The tools take a few minutes to install, so a little patience is required. For more information check out the Fastlane installation documentation
2. Create and Upload a Code Signing Certificate
To create a code signing certificate and keys we will use the
Fastlane tool. Open a terminal in the root of the repository and run the
$ mkdir certificates $ fastlane cert --output_path certificates
This will create 3 files in the
certificates directly, all named after
the certificate. In my case the certificate is named
this will be different for each project.
$ ls certificates NK5Z971JCM.cer NK5Z971JCM.certSigningRequest NK5Z971JCM.p12
.cer files are not needed to sign your
app using CircleCI. You can delete these files if you have no need for
.p12 file is the private key for your code-signing identity.
Now use the
sigh tool to create a new provisioning profile.
$ fastlane sigh --output_path certificates
This will create a provisioning profile (a file with the
extension) in the
You can now upload the
.mobileprovision files to your project on CircleCI in
Project Settings >
iOS Code Signing.
3. Find Your Code Signing Identity name
One your local machine run the following command to list the current code-signing identities installed on your machine.
$ security find-identity -p codesigning
You should see output like the following:
Policy: Code Signing Matching identities 1) 0620A954DE3B589E378435B38B8D87B6C0436BB0 "iPhone Distribution: Acme Inc. (GL31ZZ3256)" 1 identities found Valid identities only 1) 0620A954DE3B589E378435B38B8D87B6C0436BB0 "iPhone Distribution: Acme Inc. (GL31ZZ3256)" 1 valid identities found
The string with the form
"iPhone Distribution: Acme Inc. (GL31ZZ3256)"
is your code-signing identity. You might have more than one identity on
your local machine, so choose the correct one for your app. You should
add this to your
circle.yml file as follows, so that it’s available
during the build:
machine: environment: GYM_CODE_SIGNING_IDENTITY: "iPhone Distribution: Acme Inc. (GL31ZZ3256)"
4. Sign Your App on CircleCI
machine: environment: GYM_CODE_SIGNING_IDENTITY: "iPhone Distribution: Acme Inc. (GL31ZZ3256)" deployment: beta_distribution: branch: master commands: - fastlane gym
You should take a few minutes to read the documentation on deployments
The deployment stanza above instructs CircleCI to run the
command on each successful build of the
master branch. The
is just a name for the deployment. You can use any name here.
You might need to pass additional parameters to
fastlane gym to specify
exactly which configuration to build, but in most cases these are not
necessary. If you are having problems building a signed app, you can run
fastlane gym command locally specifying
--codesigning_identity (and any other options that are necessary) until you
manage to generate a signed app locally. You can then edit the command in your
circle.yml file as necessary.
deployment: beta_distribution: branch: master commands: - gym --scheme "App" --workspace "App.xcworkspace"
5. Distribute the
.ipa file to your beta testers
Using fastlane you can easily distribute the
binary to your beta testers right after generating it. If you don’t have
fastlane set up for your project yet, run
All you have to add to your
lane :beta do sigh gym # You can use any beta testing service below: pilot # (TestFlight) crashlytics hockey s3 deploygate ... end
fastlane will automatically pass on information about the
.ipa file from
gym to the beta testing service of your choice, so you don’t have to manually
provide a path to the
In this section we show a few of the most common errors that can be seen with the code signing, and offer ways to work around these issues.
No valid signing identities
If you get an error like
Code Sign error: No code signing identities found: No valid signing identities (i.e. certificate and private key pair) matching the team ID “3EF4ATW3JB” were found. or Code Sign error: No code signing identities found: No valid signing identities (i.e. certificate and private key pair) were found.
Then Xcode was not able to find the correct keychain to use. The first step to take is to example the output of the “Install Code Signing Credentials” step of the build on CircleCI. This is listed under “machine”. Expand the output and you should see output like the following:
In this example there is one valid code-signing identity,
Distribution: UTAH STREET LABS INC (GL92ZZ6423)". The goal is to pass
this literal string to Xcode. If you are building with Fastlane and
gym, then you should ensure that you have your code-signing identity
string in your
circle.yml like this:
machine: environment: GYM_CODE_SIGNING_IDENTITY: "iPhone Distribution: Acme Inc. (GL31ZZ3256)"
Or that you pass this string to
gym with the
If you are calling
xcodebuild directly you should pass your
code-signing identity as the
CODE_SIGN_IDENTITY= parameter, for
CODE_SIGN_IDENTITY="iPhone Distribution: Acme Inc.
No provisioning profiles matching an applicable signing identity were found
If you get an error message that says:
Code Sign error: No matching provisioning profiles found: No provisioning profiles matching an applicable signing identity were found.
This means that you have a valid P12 file, but there was no matching
provisioning profile found. The first thing to check is that you have a
valid provisioning profile file (
.mobileprovision) checked in to your
repository. Then take a look at the output from the “Install Code
Signing Credentials” step of the build. It should no longer be saying
"No provisioning profiles found in repository." The output shout give
a list of the provisioning profiles that were found as follows:
Installed provisioning profile 616323a4-5216-42b0-b150-a128674ec52f (UTAH STREET LABS INC - CircleCI iOS Game - ["GL92ZZ6423"]) 1 certificate imported.
My build fails with a timeout during code-signing
If your build fails with a timeout during the code-signing process, the
issue is usually that the correct keychains are not unlocked, or the
keychains are not added to the system search path. The first thing to
check is the output of
security list-keychains. You should add a step
to your build to run
security list-keychains immediately before the
command that times out.
You should see the following:
$ security list-keychains "/Users/distiller/Library/Keychains/login.keychain" "/Users/distiller/Library/Keychains/circle.keychain" "/Library/Keychains/System.keychain"
You need to ensure that
circle.keychain are in
this list. If you are adding a custom keychain using your own commands,
make sure that you are unlocking the keychain too. Make sure you are
doing something like the following:
security unlock-keychain -p circle circle.keychain security set-keychain-settings -lut 7200 circle.keychain
What Does “Install Code Signing Credentials” Do?
The “Install Code Signing Credentials” step of macOS builds is where we prepare the container for code-signing before your builds runs.
- We create a new keychain called
circle. We unlock this keychain and add it to the system search path so Xcode can access it.
- We install any P12 certificates that you have uploaded in project settings to circle.keychain
- We look through your repo and find any provisioning profiles you
have. We copy any profiles to
~/Library/MobileDevice/Provisioning Profiles, and we add any certificates in the provisioning profiles to circle.keychain (the public key in the provisioning profile should match the private key in the P12 file).
- We call
security find-identity -p codesigningto list the keychains in the build output.