# Signing iOS apps

> How to set up iOS code signing in codemagic.yaml



All iOS applications have to be digitally signed before they can be installed on real devices or made available to the public.


<br> 

{{< youtube idRJZxVafY0 >}}

## Managing and uploading files

Team admin permissions are required to upload and edit files under the **Code signing identities** section. However, all team members can view the file info for any of the uploaded files.

### Creating the App Store Connect API key

Signing iOS applications requires [Apple Developer Program](https://developer.apple.com/programs/enroll/) membership.

It is recommended to create a dedicated App Store Connect API key for Codemagic in [App Store Connect](https://appstoreconnect.apple.com/access/integrations/api). To do so:

1. Log in to App Store Connect and navigate to **Users and Access > Integrations >> App Store Connect API**.
2. Click on the + sign to generate a new API key.
3. Enter the name for the key and select an access level. We recommend choosing `App Manager` access rights, read more about Apple Developer Program role permissions [here](https://help.apple.com/app-store-connect/#/deve5f9a89d7).
4. Click **Generate**.
5. As soon as the key is generated, you can see it added to the list of active keys. Click **Download API Key** to save the private key for later. Note that the key can only be downloaded once.



> 
> Take note of the **Issuer ID** above the table of active keys as well as the **Key ID** of the generated key as these will be required when setting up the Apple Developer Portal integration in the Codemagic UI.
> 




### Adding the App Store Connect API key to Codemagic

1. Open your Codemagic Team settings, go to **Team integrations** > **Developer Portal** > **Manage keys**.
2. Click the **Add key** button.
3. Enter the `App Store Connect API key name`. This is a human readable name for the key that will be used to refer to the key later in application settings.
4. Enter the `Issuer ID` and `Key ID` values.
5. Click on **Choose a .p8 file** or drag the file to upload the App Store Connect API key downloaded earlier.
6. Click **Save**.



### Adding the Code signing certificate


Codemagic lets you upload code signing certificates as PKCS#12 archives containing both the certificate and the private key which is needed to use it. When uploading, Codemagic will ask you to provide the certificate password (if the certificate is password-protected) along with a unique **Reference name**, which can then be used in the `codemagic.yaml` configuration to fetch the specific file.





### Option: Upload certificate



1. Open your Codemagic Team settings, go to  **codemagic.yaml settings** > **Code signing identities**.
2. Open **iOS certificates** tab.
3. Upload the certificate file by clicking on **Choose a .p12 or .pem file** or by dragging it into the indicated frame.
4. Enter the **Certificate password** and choose a **Reference name**.
5. Click **Add certificate**






### Option: Generate new certificate



If you have added the **App Store Connect API key** to Codemagic, you can also generate a new `Apple Development` or `Apple Distribution` certificate.

1. Open your Codemagic Team settings, go to  **codemagic.yaml settings** > **Code signing identities**.
2. Open **iOS certificates** tab.
3. Click **Generate certificate**.
4. Provide a **Reference name** for the certificate.
5. Choose the **Certificate type**.
6. Select the **App Store Connect API key** to use.
7. Click **Create certificate**.

Once the certificate has been created, Codemagic will allow you to download the certificate and provides the password for it.

After downloading, please follow the steps in the **Upload certificate** tab to upload the certificate to Codemagic.



> 
> **Note**: The certificate can be downloaded **only once**, right after creating it.
> 


<br>


> 
> **Note**: Apple limits the number of `Apple Distribution` certificates to 3. If you have already reached the maximum number of certificates, the following error will be displayed:
> 
> 
> ```bash
> 
> There is a problem with the request entity - You already have a current Distribution certificate or a pending certificate request.
> 
> ```
> 
> 
> Similar errors can also arise in rarer cases with `Apple Development` certificates. To resolve the error, either remove some old certificate from the Apple Developer Portal or upload an existing certificate manually.
> 








### Option: Fetch from Developer Portal



Existing signing certificates previously generated by Codemagic can be automatically fetched from Apple Developer Portal based on your team's App Store Connect API key.

Fetching a certificate that was not generated by Codemagic is not possible because each certificate is linked with a private signing key to which Codemagic has no access.

1. Open your Codemagic Team settings, go to  **codemagic.yaml settings** > **Code signing identities**.
2. Open **iOS certificates** tab.
3. Click **Fetch certificate**.
4. Select a certificate from the **Development certificates** or **Distribution certificates** list.
5. Click **Fetch selected**.







### Adding the provisioning profile

Codemagic allows you to upload a provisioning profile to be used for the application or to fetch a profile from the Apple Developer Portal.

The profile's type, team, bundle id, and expiration date are displayed for each profile added to Code signing identities. Furthermore, Codemagic will let you know whether a matching code signing certificate is available in Code signing identities (a green checkmark in the **Certificate** field) or not.





### Option: Upload a profile



You can upload provisioning profiles with the `.mobileprovision` extension, providing a unique **Reference name** is required for each uploaded profile.

1. Open your Codemagic Team settings, go to  **codemagic.yaml settings** > **Code signing identities**.
2. Open **iOS provisioning profiles** tab.
3. Upload the provisioning profile file by clicking on **Choose a .mobileprovision file** or by dragging it into the indicated frame.
4. Enter the **Reference name** for the profile.
5. Click **Add profile**.





> 
> **Note:** If your app contains app extensions, an additional provisioning profile is required for each extension. Codemagic will use the bundle identifier to find the relevant provisioning profiles. If your bundle identifier is `com.example.app`, the matching profiles are the ones with `com.example.app` and `com.example.app.*` as bundle identifier.
> 





### Option: Fetch from Developer Portal



You can automatically fetch the provisioning profiles from the Apple Developer Portal based on your team's App Store Connect API key. The bundle identifier is listed for every available profile along with it's name.

The profiles are displayed grouped by category: `Development profiles`, `Ad Hoc profiles`, `App Store profiles`, and `Enterprise profiles`. For each selected profile, it is necessary to provide a unique **Reference name**, which can be later used in `codemagic.yaml` to fetch the profile.

1. Open your Codemagic Team settings, go to  **codemagic.yaml settings** > **Code signing identities**.
2. Open **iOS provisioning profiles** tab.
3. Click **Fetch profiles**
4. Select the desired profile(s) and enter a **Reference name** for each one.
5. Click **Download selected**. (scroll down if necessary)







<br>


> 
> **Note:** When you make essential changes to a provisioning profile, such as modifying the app ID, adding/removing capabilities from the profile identifier, or changing the certificates assigned to that profile, the provisioning profile becomes invalid. In such situations, you need to generate a new provisioning profile with these updates and then re-upload it to Codemagic.
> 

 


## Referencing certificates and profiles in codemagic.yaml

Codemagic provides two means of fetching the required certificates and provisioning profiles during the build with the use of `codemagic.yaml`. Fetching can either be configured by specifying the distribution type and bundle identifier, or for more advanced use-cases, individual files can be fetched by their reference names.


### Fetching files by distribution type and bundle identifier

To fetch all uploaded signing files matching a specific distribution type and bundle identifier during the build, define the `distribution_type` and `bundle_identifier` fields in your `codemagic.yaml` configuration. Note that it is necessary to configure **both** of the fields.


```yaml

workflows:
  ios-workflow:
    name: iOS Workflow 
    # ....
    environment:
      ios_signing:
        distribution_type: app_store # or: ad_hoc | development | enterprise
        bundle_identifier: com.example.id

```



Note that when using the fields `distribution_type` and `bundle_identifier`, it is not allowed to configure `provisioning_profiles` and `certificates` fields.



> 
> **Note:** If you are publishing to the **App Store** or you are using **TestFlight**  to distribute your app to test users, set the `distribution_type` to `app_store`. 
> 
> When using a **third party app distribution service** such as Firebase App Distribution, set the `distribution_type` to `ad_hoc`
> 



When defining the bundle identifier `com.example.id`, Codemagic will fetch any uploaded certificates and profiles matching the extensions as well (e.g. `com.example.id.NotificationService`).


### Fetching specific files by reference names

For a more advanced configuration, it is possible to pick out specific uploaded profiles and certificates for Codemagic to fetch during the build. To do so, list the references of the uploaded files under the `provisioning_profiles` and `certificates` fields, respectively. Note than when fetching individual files, the fields `distribution_type` and `bundle_identifier` are not allowed.

Steps `Initialize keychain` & `Add certificates to keychain` scripts are not required as those are automatically fetched during the build process.


```yaml

workflows:
  ios-workflow:
    name: iOS Workflow
    
    # ....
    
    environment:
      ios_signing:
        provisioning_profiles:
          - profile_reference
          # - ...
        certificates:
          - certificate_reference
          # - ...

```


Codemagic saves the files to the following locations on the build machine:

- Profiles: `~/Library/MobileDevice/Provisioning Profiles`
- Certificates: `~/Library/MobileDevice/Certificates`

It is additionally possible to include names for environment variables that will point to the file paths on the build machine.


```yaml

workflows:
  ios-workflow:
    name: iOS Workflow
    
    # ....
    
    environment:
      ios_signing:
        provisioning_profiles:
          - profile: profile_reference
            environment_variable: THIS_PROFILE_PATH_ON_DISK
          # - ...
        certificates:
          - certificate: certificate_reference
            environment_variable: THIS_CERTIFICATE_PATH_ON_DISK
          # - ...

```



## Using provisioning profiles

To apply the profiles to your project during the build, add the following script before your build scripts:


```yaml

  scripts:
    # ... your dependencies installation
    
    - name: Set up code signing settings on Xcode project
      script: xcode-project use-profiles
    
    # ... your build commands

```




>   
> See additional configuration options for setting up code signing settings to use given provisioning profiles [here](https://github.com/codemagic-ci-cd/cli-tools/blob/master/docs/xcode-project/use-profiles.md)
> 



To distribute signed iOS applications solely to internal testers without the need for Apple's beta review (TestFlight Internal Testing Only):


```yaml
  
  scripts:  
    # ... your dependencies installation  
    - name: Set up code signing settings on Xcode project  
      script: xcode-project use-profiles   
                --custom-export-options='{"testFlightInternalTestingOnly": true}'  
    # ... your build commands  

```
  


>   
> **Note:** Builds marked as TestFlight Internal Only will display "internal" next to the build number and can exclusively be added to internal tester groups. They cannot be submitted for external testing or distributed to customers. 
> 


