How to Code Sign Your iOS App on Codemagic with an App Store Connect API Key

A practical guide to setting up automatic iOS code signing on Codemagic using an App Store Connect API key, so your cloud builds produce distributable, signed archives.

Why Automatic Signing with an API Key

iOS code signing is the step where a compiled app is stamped with a certificate and provisioning profile so Apple's devices and the App Store will accept it. On a local Mac, Xcode's automatic signing quietly manages this. In the cloud, there is no logged-in developer account, so you must give Codemagic an authenticated way to fetch or create signing assets. The cleanest approach is an App Store Connect API key. Rather than manually exporting certificates and profiles and keeping them in sync, you provide an API key that lets Codemagic talk to App Store Connect on your behalf, retrieve or generate the distribution certificate and provisioning profile matching your bundle identifier, and sign the archive. This is more robust than manual signing because it reduces the chance of an expired or mismatched profile silently breaking your pipeline, and it centralizes trust in a single revocable key rather than scattered credential files. It does require an active Apple Developer Program membership, since the API key derives its authority from your team's enrollment. The API key also underpins publishing, so configuring it well here pays off again when you wire up TestFlight and App Store uploads later in the pipeline.

Create an App Store Connect API Key

Sign in to App Store Connect with an Account Holder or Admin role and go to Users and Access, then the Integrations or Keys area for App Store Connect API keys. Generate a new key and give it an access role appropriate for build and distribution work; App Manager is commonly sufficient for uploading and managing builds, though your team's policies may dictate otherwise. When you create the key, App Store Connect gives you three things you must capture: the Key ID, the Issuer ID (shown at the top of the keys page and shared across your team's keys), and the private key file itself, a .p8 file that you can download only once. Store the .p8 securely; if you lose it you must revoke the key and generate a new one, because Apple never lets you re-download it. Treat this key like a password — anyone holding all three pieces can act against your App Store Connect account within the key's permissions. Do not commit the .p8 to your repository under any circumstances. A good practice is to store the .p8 in a password manager or a secrets vault immediately after download, alongside a note of its Key ID and the role you granted, so you can audit and rotate it later.

Add the API Key to Codemagic

In Codemagic, add the API key so builds can authenticate. In the team or application settings you will find a code signing identities or integrations area for App Store Connect. Provide the Key ID, the Issuer ID, and upload the .p8 private key file. Codemagic stores these securely as an integration or as encrypted environment variables, depending on how you configure it. Give the stored key a clear reference name so you can point workflows at it. If you prefer codemagic.yaml, you reference the App Store Connect integration in the workflow's environment section rather than pasting raw credentials into the file. Never hardcode the Key ID, Issuer ID, or the contents of the .p8 into codemagic.yaml or any committed file — always use Codemagic's encrypted variables or its managed integration. Once added, this single key can serve both signing and later publishing to TestFlight and the App Store, which is one reason the API key approach is so convenient: you configure trust once and reuse it across the whole delivery pipeline. If you manage several apps under one Apple team, you can reference the same stored integration from each app's workflow rather than re-entering the credentials per project.

Configure Automatic Signing in Your Workflow

With the key stored, configure your workflow to use automatic signing. In codemagic.yaml, the iOS signing configuration references the App Store Connect integration and specifies the bundle identifier of your app and the distribution type — typically app_store for TestFlight and App Store builds, though ad_hoc and development types exist for other scenarios. Codemagic uses its CLI tools to fetch or create the distribution certificate and a matching provisioning profile for that bundle identifier, install them into a temporary keychain on the build machine, and apply them during the archive step. The bundle identifier you specify must exactly match the one registered in your Apple Developer account and set in your Xcode target; a mismatch is the single most common cause of signing failures. If your app has extensions — a widget, a notification service, a watch app — each has its own bundle identifier and needs its own profile, so make sure your configuration accounts for every target that ships in the archive, not just the main app. Codemagic can match profiles by a bundle identifier prefix or wildcard in many setups, but confirming each embedded target resolves to a valid profile before your first release build saves a frustrating round of failed archives.

Match Bundle IDs and Capabilities

Signing does not happen in a vacuum; the certificate and profile must agree with your app's identity and entitlements. Confirm that the bundle identifier in your Xcode target's build settings matches the App ID registered in the Apple Developer portal and the identifier you reference in Codemagic. Beyond the identifier, check capabilities. If your app uses Push Notifications, App Groups, iCloud, Sign in with Apple, or associated domains, those capabilities must be enabled on the App ID in the developer portal, and the provisioning profile must include the corresponding entitlements. When Codemagic generates a profile automatically via the API key, it can include registered capabilities, but the capability must first exist on the App ID. A frequent failure mode is enabling a capability in Xcode locally without registering it on the portal, which works with local automatic signing but breaks a clean cloud build. Keep your entitlements file, your Xcode capability toggles, and your portal App ID configuration in agreement. When all three align, the automatic signing flow produces a valid, distributable archive without manual profile juggling. If you recently added a capability, register it on the App ID first and only then trigger the cloud build, so the freshly generated profile carries the new entitlement.

Run a Signed Build and Verify

Trigger a build and watch the signing steps in the log. You should see Codemagic authenticate to App Store Connect, fetch or create the certificate and provisioning profile, install them into the build keychain, and then archive and export a signed .ipa. Declare the .ipa as an artifact so you can download and inspect it. To verify the signature, you can check that the exported .ipa contains an embedded provisioning profile and that its bundle identifier and entitlements match expectations; the build log usually prints the profile name and the signing identity used. A signed build that produces a valid .ipa is the gate you must pass before any distribution step will succeed, because TestFlight and the App Store both reject improperly signed or unsigned binaries. If the signing step fails, read the specific error — it will usually name a missing certificate, an absent profile, a bundle identifier mismatch, or an API key permission problem — and resolve that root cause rather than retrying blindly, since each retry consumes build minutes without changing the underlying configuration. On a Mac you can further inspect an exported .ipa by unzipping it and running codesign and security tools against the embedded profile, which is a useful sanity check when a build is signed but a later upload still complains.

Manual Signing as a Fallback

Automatic signing via the API key suits most teams, but there are situations where you may prefer or need manual signing — strict security policies that forbid programmatic profile creation, enterprise distribution, or a requirement to use a specific pre-existing profile. In manual mode you export your distribution certificate as a .p12 file with its password and export the exact provisioning profile you intend to use, then upload both to Codemagic as encrypted signing assets and reference them in your workflow. Manual signing gives you precise control but shifts the maintenance burden onto you: certificates expire after a period and profiles must be regenerated whenever you add a device or change capabilities, and a stale uploaded profile will silently break builds until you refresh it. For most native iOS teams the API key path is less error-prone because Codemagic keeps the assets current. Choose manual signing only when you have a concrete reason, and document the renewal cadence so an expired certificate does not surprise you right before a release deadline. If you do go manual, set a calendar reminder ahead of the certificate's expiry and keep the exported .p12 and profile in your secrets vault so a teammate can refresh them if you are unavailable.

Frequently Asked Questions

What are the three pieces of an App Store Connect API key?

The Key ID, the Issuer ID, and the private key .p8 file. You capture all three when generating the key in App Store Connect under Users and Access. The .p8 can only be downloaded once, so store it securely.

What role does the API key need?

For build upload and distribution, App Manager is commonly sufficient, though your team may have stricter policies. The key must have enough access to manage builds and, if using automatic signing, to work with certificates and profiles for your app.

Why does my signing fail with a bundle ID mismatch?

The bundle identifier in your Xcode target must exactly match the App ID registered in the Apple Developer portal and the identifier referenced in Codemagic. Even a small discrepancy prevents a matching profile from being found or created.

Do app extensions need separate signing?

Yes. Each extension or embedded target — widgets, notification services, watch apps — has its own bundle identifier and requires its own provisioning profile. Your signing configuration must cover every target shipped in the archive, not just the main app.

Should I ever commit the .p8 file to my repo?

Never. The .p8, Key ID, and Issuer ID together grant access to your App Store Connect account. Store them only in Codemagic's encrypted variables or managed integration, never in committed files like codemagic.yaml.

Is an Apple Developer Program membership required for signing?

Yes. The API key derives its authority from your team's Apple Developer Program enrollment. Without an active paid membership you cannot generate valid distribution certificates or provisioning profiles for TestFlight or the App Store.