iOS Certificate Migration: 2026 Mac Handoff Checklist
đź“‹ Table of Contents
Apple’s current upload documentation states that App Store Connect requires Xcode 14 or later for uploads starting in 2026. That makes a Mac handoff a release-control problem, not just a file-copy task. Apple’s upload requirements also distinguish a successful local build from a build that has been processed by App Store Connect.
Symptom: You import a certificate, but Xcode still says the private key is missing.
Fastest fix: Move the complete signing identity, including its private key, or create a new certificate on the new Mac. Then verify the App ID, entitlements, Provisioning Profile, Archive signature, and App Store Connect upload before retiring the old machine.
This guide is for you if you are moving from an old Mac to a remote Mac, replacing a damaged build machine, or maintaining an unattended iOS build host. It also fits small teams that need a repeatable handoff process instead of relying on one developer’s personal Keychain.
What must move together: certificate, private key, and profile
An iOS certificate migration fails most often because the certificate is treated as the whole signing setup. It is not.
The certificate contains public information that identifies the signing authority. The private key performs the cryptographic signing operation. Together, the certificate and matching private key form the signing identity that Xcode can use.
Apple’s signing documentation explains that a signature is created with a private key and checked against the corresponding public key. A certificate file without its matching private key cannot recreate that signing capability. See Apple’s signing and verification documentation.
A Provisioning Profile is a separate asset. It links the signing authority to an App ID, permitted capabilities, and the distribution or development use case. Apple states that an App Store provisioning profile contains one App ID and one distribution certificate. See Apple’s Provisioning Profile update documentation.
| Asset | What it proves or enables | Can a copied file alone restore signing? | Migration action |
|---|---|---|---|
| Distribution certificate | Public identity of the signing certificate | No | Export with its matching private key |
| Private key | Performs the signing operation | Yes, only with the certificate | Protect with a strong export password |
| Provisioning Profile | Authorizes the App ID, certificate, and entitlements | Sometimes, but it may need regeneration | Back up and validate against the new identity |
| App ID and capabilities | Defines the bundle identifier and enabled services | No | Recheck in the developer account and Xcode |
| App Store Connect API key | Authenticates automated upload workflows | No | Inventory and transfer separately |
| APNs key | Supports push notification authentication | No | Treat as an independent credential |
The practical rule is simple: do not move only .cer files. Export the identity from the old Mac in a protected format, or create a replacement identity on the new Mac.
First step: freeze the old environment before changing it
Do not revoke certificates or delete profiles at the beginning of the migration. First capture the state that currently produces a valid release.
Record these values for each target:
- Team ID:
TEAM_ID_PLACEHOLDER - Bundle ID:
com.example.app - App extensions and their bundle IDs
- Enabled capabilities
- Development certificate type
- Apple Distribution certificate type
- Provisioning Profile name and UUID
- Xcode version
- Build configuration used for release
- Export method and destination
- App Store Connect upload method
- API key ID, issuer ID, and key location, without copying the private key into a document
Keep the old Mac usable while the new Mac is prepared. The old machine is your rollback path if the new environment cannot produce a valid Archive.
You should also save the project’s signing configuration. Check the Xcode project, workspace, target settings, export options, CI variables, and scripts. Avoid turning this into a generic certificate inventory. The goal is to reproduce one real release path.
Automatic signing, manual signing, and CI signing are different
Automatic signing lets Xcode request or manage profiles based on the selected team, App ID, capabilities, and available credentials. Manual signing expects you to choose a certificate and profile deliberately. An automated pipeline may use either model, but it adds Keychain access, environment variables, unlock behavior, and upload credentials.
Do not assume that a successful interactive build proves an unattended build will work. A developer session may have an unlocked login Keychain, an active Xcode account, or cached profiles that a background job cannot access.
Second step: export the signing identity instead of the visible certificate
On the old Mac, open Keychain Access and locate the certificate used by the release target. Expand the certificate entry. You should see a private key attached to the same identity.
Apple’s certificate guidance identifies Keychain Access as the Mac tool for creating certificate signing requests and managing certificate-related key material. See Apple’s certificate signing request instructions.
If the certificate appears without a private key, stop. Exporting that entry will not repair the missing key. Search other Keychains and user accounts only if you can document why the original identity may be stored there.
When the matching key is present:
- Select the certificate and its private key together.
- Use Keychain Access to export them in a password-protected identity format.
- Set a temporary transfer password that is not reused elsewhere.
- Move the protected export through an approved private channel.
- Delete temporary copies from shared folders, downloads, and shell history.
- Store the transfer password in your approved secret manager, not in the project repository.
- Keep the old identity available until the new Mac passes release validation.
Do not commit identity exports, private keys, API keys, or passwords to Git. A private signing key is not a normal build artifact. Apple also advises developers to protect Apple accounts and certificate materials and not share them outside the organization. See Apple’s certificate protection guidance.
Security reminder: A remote Mac still has a real Keychain and real signing authority. Root access helps you administer the machine, but it does not make private keys safe by default. Limit access, record who can reach the host, and remove temporary transfer files after validation.
Why Xcode still reports “missing private key” after import
This error usually means the new Mac has the public certificate but not the matching private key. It can also appear when the identity was imported into a different user account or Keychain than the one used by Xcode or the build agent.
Use this sequence:
- Open Keychain Access under the same macOS user that runs the build.
- Search for the certificate’s common name.
- Expand the certificate and confirm a private key is listed.
- Confirm the private key is accessible to the build user.
- Restart Xcode after importing the identity.
- Check the selected team and signing certificate in the target.
- Run a clean build after removing stale signing selections.
- For CI, test the same command under the service account rather than your interactive account.
A .cer file is not a substitute for a .p12 identity export or a newly generated private key. If the original private key is gone, the new Mac cannot reconstruct it from the public certificate.
Third step: when the old Mac is dead, choose rebuild or recovery
If the old Mac cannot boot, first determine whether you have a protected identity export or a working backup of the original Keychain. If neither exists, assume the private key is unavailable.
You cannot derive the private key from a public certificate. The recovery path is to create a new signing certificate, then update the related Provisioning Profiles where your role permits it.
The order matters:
- Confirm that you have the Account Holder or Admin access required for the certificate operation.
- Create a new certificate or use Xcode to generate one.
- Identify every target that used the old certificate.
- Regenerate profiles that reference the old certificate.
- Recheck capabilities and entitlements.
- Update the build environment with the new identity.
- Run a real Release Archive before revoking anything.
Do not revoke the old certificate merely because you are moving machines. Apple explains that a profile may become invalid when a certificate is revoked, and profiles may need regeneration after certificate or capability changes. See Apple’s profile editing and regeneration guidance.
Revocation is appropriate when the private key is suspected to be exposed, when the old identity must be retired for security reasons, or when your account’s certificate limits require cleanup. It is not a harmless migration button.
Keep upload credentials separate from code-signing credentials
An App Store Connect API key is used for API authentication. It is not the same thing as an Apple Distribution certificate. An APNs key is also a separate credential with a different purpose.
Inventory these credentials independently:
- App Store Connect API key ID
- Issuer ID
- Encrypted API key file
- APNs key ID
- Team ID
- Upload method
- Secret storage location
- Rotation owner
Apple documents JWT-based authentication for App Store Connect API workflows and lists Xcode, Transporter, and command-line tools as upload paths. See Apple’s App Store Connect upload documentation.
This separation prevents a common mistake: replacing code-signing assets but forgetting that the upload job still points to an API key stored only on the old Mac.
Fourth step: restore the new Mac and rebuild the signing relationship
Install the required Xcode version and project dependencies on the new Mac. Do not begin by copying the entire old user profile. Restore only the items required for the release path.
Import the protected signing identity into the Keychain used by the build user. Then verify all of the following:
- The certificate is present.
- The matching private key is present.
- The identity is visible to Xcode.
- The selected Team ID is correct.
- The Bundle ID matches the App ID.
- The target capabilities match the profile.
- The profile contains the expected certificate.
- The export method points to the intended distribution type.
- The build user can access the Keychain without weakening protection.
For manual signing, compare the certificate and profile explicitly in Signing & Capabilities. For automatic signing, sign in to the correct team and allow Xcode to refresh managed assets only after you have recorded the original configuration.
Provisioning Profiles may also be cached locally. Apple identifies the usual profile cache location as:
~/Library/MobileDevice/Provisioning Profiles/
See Apple’s profile download and regeneration instructions.
Do not delete every cached profile as a first response. Remove stale profiles only when you understand which target needs a refresh. If a capability changed or a profile expired, regenerate the profile and download it again.
Fifth step: use a layered acceptance test, not one successful build
A migration is complete only when the new Mac passes each layer of the release path.
| Validation layer | Test | Pass condition | Failure usually points to |
|---|---|---|---|
| Compile | Build the real project in Release mode | No compile or dependency errors | Xcode, SDK, package, or environment mismatch |
| Archive | Create a clean Release Archive | Archive completes for the intended scheme | Signing settings, build phase, or dependency issue |
| Inspect | Review certificate, profile, Team ID, and entitlements | All values match the release plan | Wrong identity, stale profile, or capability drift |
| Export | Export the intended distribution artifact | Export completes without signing errors | Profile, certificate, or export-option mismatch |
| Validate | Run signature and entitlement checks | The artifact passes local validation | Embedded signing or entitlement problem |
| Upload | Send the build to App Store Connect | Upload is accepted and processing begins | Credential, bundle, version, or platform issue |
| Process | Wait for platform processing | Build appears with the expected status | Processing, compliance, or metadata issue |
The important distinction is between Archive success and upload success. A locally exported IPA can still fail during upload. Apple states that the uploaded build must be processed before it appears in App Store Connect. Use the App Store Connect build processing guidance as the final platform check.
For local inspection, use placeholders rather than real secrets in documentation:
xcodebuild \
-workspace Example.xcworkspace \
-scheme Example \
-configuration Release \
-archivePath "$PWD/build/Example.xcarchive" \
archive
codesign --display --verbose=4 \
"$PWD/build/Example.xcarchive/Products/Applications/Example.app"
security find-identity -v -p codesigning
These commands help you inspect the environment. They do not replace a real App Store Connect upload.
Save the complete Xcode or command-line log, but redact:
- Private key names if they reveal sensitive ownership
- API key contents
- Issuer and secret values
- File paths containing personal information
- Session tokens
- Internal hostnames
- Customer data
Decision branch: export the old identity or create a new one?
Use this decision tool before touching the developer account.
- If the old Mac shows the certificate and matching private key in Keychain Access: export the complete identity, import it into the new Mac, and keep the old certificate active during validation.
- If you have a protected identity backup but cannot access the old Mac: restore it into the new Mac, then validate the profile and project settings.
- If you have the certificate but no private key: do not keep trying to import the
.cerfile. Create a new certificate and regenerate affected profiles. - If the private key may have leaked: isolate the old identity, create a replacement, update profiles and automation, then revoke the compromised certificate.
- If automatic signing works interactively but CI fails: compare the build user, Keychain access, profile cache, and team authentication.
- If Archive succeeds but upload fails: inspect upload credentials, bundle ID, version, build string, role permissions, and App Store Connect processing status.
- If the new Mac has not completed a real upload: do not shut down the old Mac.
This branch keeps the migration based on evidence instead of guessing from the filename of a certificate.
Final step: upload, repeat, then retire the old Mac
After the first successful upload, run the release path again without relying on cached interactive state. The second run should use the same build user, same scripts, and same credential method that your scheduled job will use.
Test at least these operational conditions:
- A fresh login session
- A locked and then unlocked Keychain
- A machine restart
- A scheduled or unattended build
- Dependency restoration
- App Store Connect authentication
- A second Archive with a new build string
The exact test count can follow your release risk, but one interactive Archive is not enough for an unattended build host.
Only retire the old Mac after the new environment has produced a valid Archive, passed signature inspection, exported the expected artifact, uploaded it, and confirmed processing in App Store Connect. Then remove old identity exports, delete temporary secrets, rotate credentials that were exposed during the move, and update the recovery runbook.
For a remote build host, also define its retention period. A short-term migration machine may be enough for one release rehearsal. A frequently updated app may justify keeping a dedicated host as an always-available iOS build server. If you are comparing deployment models, document whether you need a real bare-metal macOS environment rather than virtualization; MacDate’s bare-metal and virtualization comparison can help frame that decision.
Current setup or remote Mac: choose based on the failure you need to avoid
Keeping the old Mac is attractive because the signing identity already works. Its weaknesses are less visible: hardware failure, storage wear, a single-person Keychain, forgotten credentials, and no clean rollback plan. A local replacement also leaves you responsible for power, updates, backups, and physical access.
A remote Mac does not remove signing risk, but it can give you a separate environment for migration rehearsals and unattended builds. The better approach is to rent it for a short period, restore the identity or create its replacement, and complete a real release before deciding whether to keep it as a permanent build host. You can review available MacDate remote Mac options without treating the rental as a substitute for proper key management.
The migration is successful when the release can be repeated by the new environment, not when the certificate icon appears in Keychain Access. If you need a temporary migration machine first, start with a short rental period, complete the Archive and upload checks, and extend the environment only if your release frequency justifies a standing build host.