How to Deliver iOS App with Fastlane and Apple API key

Tzimikas Dimitris
Coded Lines Digital Stories
5 min readJul 19, 2021

A while ago developers used to authenticate to Apple services with Apple ID without 2FA. Through this authentication users were allowed to upload the .ipa files to app store. However, this mode of authentication has changed when Apple updated their policy on 2FA.

Apple announced that as of February 27th 2019, it would enforce 2-factor authentication on developer Apple IDs with the “Account Holder” role. Since then, they extended this rule to all roles, and then later throughout 2020 they slowly enforced all existing accounts to register 2FA. As of March 3rd 2021, no accounts without 2FA registered are able to login until they register a 2FA method, essentially breaking all “non-2FA compliant Apple IDs” that still existed. For this reason, when using fastlane in your CI, you will have to work your way with 2FA.

source: https://docs.fastlane.tools/getting-started/ios/authentication/

This change has been causing many problems to developers that already had set up their CI environments. This article aims at providing helpful information on the transition from non 2FA auth to the new Apple API Key.

To generate the required API Key the user should connect to Apple Store Connect (https://appstoreconnect.apple.com) with an Admin or an Account Holder role.

To check your role navigate to Users and Access and search for your email to see your current role. If it is Admin or Account Holder you are good to go!

On the same page on top tabs select Keys.

On Keys page make sure you are in App Store Connect API, and then click on the plus (+) button

After you click the plus (+) icon a modal will appear with a “Name” field and “Access” field. In the Name field you can enter a relevant value to the usage of the API Key e.g. fastlane-key. In the Access field make sure you select Developer role. This is important because only some roles have rights to upload .ipa to the Apple Store.

After that download the API Key. The same should be made for Issuer ID & KEY ID both should be copy/pasted and kept in a safe place alongside with the API Key.

We have now finished from App Store Connect, time to move to our IDE. In our case we use Circle CI as our CI method of delivering the app but it could be adopted by any CI platform and also we will need a .env file to store our secret values.

We need to create three values in our .env to store the keys. The caveat here is the form of API PRIVATE KEY, we need to change the form from

to:

*Names of the variables are not important for the script to run but it should be something relevant to its usage.

  1. APP_STORE_API_PRIVATE_KEY
  2. APP_STORE_API_KEY_ID
  3. APP_STORE_API_KEY_ISSUER_ID

After that we can create the step in our CI process to create the AuthKey file and load the fastlane lane to generate the .ipa and deliver the files to Apple Store.

First we create the .p8 file that contains the Private Key with touch ./fastlane/AuthKey_$APP_STORE_API_KEY_ID.p8 (name of the file is not important but it is good practice to follow fastlane examples). We store it in ./fastlane folder.

Now that the file is created its time to fill it with the Private Key. To do so we use echo -e which will remove the \n character and add newlines to the file, so the Private Key will have its original form.

Next step is calling (in our case) the script that runs fastlane. It could be any fastlane command here e.g. fastlane ios master or fastlane ios production etc.

Last but not least we need to go to our Fastfile where the fastlane commands lies. Here is where we need to add the code to generate the api_key. First create api_key variable to store the outcome of app_store_connect_api_key. Make sure you load the values from .env and write the names of the variables correctly. The key_filepath should load the .p8 file that we generated on previous step.

Finally, we load the api_key in our upload_to_app_store so the fastlane can generate the api_key and connect to App Store Connect.

If everything goes as planned the output on your CI console should be something like this:

And that should be it! Hope this will make your lives easier on the transition from old to new authentication process 😉 🤙🏼

--

--