skip to content

For a React Native iOS release, what do the distribution certificate and the App Store provisioning profile each do when you archive and upload?

level: middleimportance: must knowfreq 55%

answer

  1. who you are vs what may run
  2. private key lives in the keychain
  3. profile binds App ID, certificate, entitlements
  4. bundle identifier must match
  5. Any iOS Device (arm64), then Distribute App

basics

~20 s

The distribution certificate, with its private key in your keychain, proves the build comes from your team. The App Store provisioning profile ties that certificate to one bundle identifier and its entitlements. Xcode signs the archive with both before upload.

solid answer

~50 s

The **distribution certificate** is your team's signing identity: Apple issues a certificate for a key pair whose **private key** lives in the Mac's keychain, and without that key the certificate is useless. The **App Store provisioning profile** is a signed file from Apple that ties together one **App ID** (the bundle identifier), the distribution certificates allowed to sign it, and the **entitlements** the app may use, such as push notifications. To ship a React Native app you select **Any iOS Device (arm64)**, run **Product > Archive** (Release), then **Distribute App > App Store Connect > Upload**, choosing automatic or manual signing. Signing fails when the profile does not match: a different bundle identifier, a certificate whose private key is not on this Mac, or an entitlement the profile lacks, such as a push capability added after the profile was made.

go deeper

for a junior

Know the two artefacts: a distribution certificate proves who signed, a provisioning profile says which app and capabilities are allowed. Know the Archive then Distribute App path.

for a middle

Explain why the private key matters, how the profile ties App ID, certificates and entitlements together, and why a new capability can break the Release archive.

for a senior

Diagnose signing failures from the error text, choose between automatic and manual signing for the team's setup, and make sure the distribution private key is backed up.

for a principal

Decide who owns Apple signing assets, how they are shared and rotated, and how releases avoid depending on one person's keychain.

## Two artefacts, two questions Apple code signing answers two separate questions, and each has its own artefact: | | Distribution certificate | App Store provisioning profile | |---|---|---| | Answers | *Who* signed this build? | *What* may this signed build be? | | Contains | Your team's public key, issued by Apple | App ID, allowed certificates, entitlements | | Secret part | The private key in the keychain | None; it is a signed file | | Scope | The team, reused across apps | One bundle identifier | | Created in | Apple Developer account, or by Xcode | Apple Developer account, or by Xcode | A React Native app is signed exactly like any native iOS app; the React Native docs say the publishing process is the same, with extra considerations for the JavaScript bundle. ## The distribution certificate - You create a **key pair** on a Mac and Apple issues a **certificate** for its public key. - The certificate plus the **private key** form the signing identity. The private key never leaves the keychain unless exported. - A new Mac or CI machine cannot sign with a certificate unless the private key is also installed there; seeing the certificate listed is not enough. - Certificates have an **expiry date**; after it, new builds cannot be signed with them. ## The App Store provisioning profile - It names one **App ID**, which must match the target's bundle identifier exactly. The React Native docs call this out: check that the Bundle Identifier is the same as the one registered under Identifiers in the developer account. - It lists the **certificates** allowed to sign the app. - It carries the **entitlements** the app may use: push notifications, associated domains, sign in with Apple and so on. The app's entitlements file must not ask for anything the profile does not grant. - It also has an **expiry date**. ## Archiving and uploading a React Native app 1. Open `ios/YourApp.xcworkspace` (the workspace, because CocoaPods adds the React Native pods). 2. Select **Any iOS Device (arm64)** as the destination. 3. Run **Product > Archive**. Archiving builds the **Release** configuration, so the JS is bundled into `main.jsbundle`. 4. In the Organizer, choose **Distribute App**, then **App Store Connect**, then **Upload**. 5. Choose **Automatically manage signing** or **Manually manage signing**. Automatic lets Xcode pick or create the certificate and profile; manual means you select a profile you created. 6. The build then appears in App Store Connect, ready for testing and submission. ## When signing fails | Symptom | Usual cause | |---|---| | No profile matches the bundle identifier | Bundle ID differs from the App ID, often after renaming the app | | Certificate shown but "missing private key" | The key pair was created on another Mac | | Profile does not include an entitlement | A capability, such as push, was added after the profile was generated | | Profile or certificate expired | The dates passed; a new one is needed | ## The scenario: a parking app adds push reminders A parking app adds push notifications to remind drivers before a session ends. The Debug build on a phone works, because development signing uses a separate development profile. The Release archive fails: the App Store profile was generated before the push capability was enabled, so it lacks the entitlement. Regenerating the App Store profile after enabling the capability, or letting automatic signing refresh it, fixes the archive. ## What ends up in the signed archive It helps to know what an `.xcarchive` for a React Native app carries, because each item has its own failure mode: - The **signed app**, with the distribution certificate's signature. - The **embedded provisioning profile** that authorised the signing, which is how the entitlements travel with the app. - **`main.jsbundle`** and the JS images, produced by the Release bundling phase. - **dSYMs**, the debug symbols for the native code, which stay with the archive rather than the app. ## Automatic or manual? - **Automatic** suits small teams and one release machine; Xcode keeps profiles current. - **Manual** gives predictable, reviewable signing and suits shared release machines, at the cost of regenerating profiles yourself. - Either way, the private key for the distribution certificate must be backed up; sharing it across a team is a separate topic.

  • A React Native iOS Debug build runs on a phone, but the Release archive fails signing after push notifications were added; why?
    Debug on a device uses development signing and its own development profile, while the archive uses the App Store distribution profile. If that profile was created before the push capability was enabled, it lacks the entitlement the app now requests. Regenerate the App Store profile, or let automatic signing refresh it, and archive again.
  • A React Native release Mac lists the team's distribution certificate but Xcode says the signing identity is missing a private key; what does that mean?
    The certificate is only the public half. The private key was generated on another Mac and never exported to this one, so Xcode cannot sign. Import the certificate together with its private key from a secure backup, or create a new certificate on this Mac and a profile that includes it.

saying these in an interview costs you the question

  • The certificate alone is enough to sign; the private key is optional.
  • One provisioning profile can cover several unrelated bundle identifiers.
  • The Debug profile used on a test phone is the one used for App Store upload.
  • React Native apps need a special signing flow different from native apps.
  • Entitlements come from the app's code, so the profile does not need to list them.