Configure iOS code signing on Bitrise the reliable way — using codesigndoc to collect the right certificate and profiles, the Code Signing tab to upload them, or an App Store Connect API key for automatic managed signing.
iOS code signing exists so Apple can guarantee that an app came from an identified developer and has not been tampered with. To sign, you need two kinds of assets: a signing certificate, which pairs a public certificate with a private key and identifies you or your team, and a provisioning profile, which ties a certificate, an app's bundle identifier, a set of entitlements, and — for development builds — specific device UDIDs together. On your own Mac these live in the Keychain and in Xcode's managed store, which is why local signing often feels invisible. On Bitrise, builds run on fresh, ephemeral macOS machines that start with none of your signing assets, so you must supply them explicitly. Bitrise offers two strategies. The first is uploading exported certificates and profiles into the app's Code Signing tab and letting a Certificate and profile installer Step place them on the machine. The second is connecting an App Store Connect API key so Bitrise can fetch or manage signing assets automatically. Understanding this ephemeral-machine model is the key to debugging every signing problem you will encounter.
The hardest part of manual signing is knowing exactly which certificate and which profiles your scheme uses, because a project can reference several. Bitrise publishes an open-source command-line tool, codesigndoc, precisely to solve this. You run codesigndoc on your own Mac, point it at your Xcode project or workspace and the scheme you build for release, and it performs an actual archive to observe which signing identity and provisioning profiles Xcode selects. It then exports your distribution certificate as a .p12 file and collects the matching .mobileprovision profiles, optionally uploading them straight to your Bitrise app if you provide an access token. This observed approach is far more reliable than guessing, because it captures the real assets Xcode resolves rather than every certificate in your Keychain. Before running it, make sure the project archives cleanly in Xcode with your intended distribution signing, since codesigndoc simply mirrors whatever Xcode does. Keep the exported .p12 password safe; you will enter it in Bitrise so the installer Step can import the certificate into the build machine's temporary Keychain.
With your .p12 certificate and .mobileprovision profiles in hand, open your app on Bitrise and go to the Code Signing tab, sometimes labeled Code Signing & Files. There you upload the distribution certificate and enter its export password so Bitrise can decrypt and install it at build time, and you upload each provisioning profile you need — typically an App Store distribution profile for TestFlight and release builds, and possibly Ad Hoc or Development profiles if you also produce internal test builds. Bitrise stores these securely and exposes them to the Certificate and profile installer Step, which you add near the start of your workflow before any archive Step. During a build, that Step imports the certificate into a temporary Keychain and places the profiles where Xcode expects them, so the subsequent Xcode Archive & Export Step can sign successfully. Make sure the profile's bundle identifier exactly matches your app's, that the profile has not expired, and that it was created for the correct distribution method, because mismatches here are the leading cause of signing failures on otherwise-correct pipelines.
The more modern and generally more robust approach is to connect an App Store Connect API key. You generate this key in App Store Connect under Users and Access, in the Integrations or Keys area, choosing an appropriate role such as App Manager or Admin depending on what your pipeline must do. Apple gives you a Key ID, an Issuer ID, and a downloadable .p8 private key file, which you can download only once, so store it securely. In Bitrise you register these three pieces under your app or team settings so Steps can authenticate to Apple's services without an Apple ID password or interactive two-factor prompts, which never work well in automation. An API key enables automatic managed signing, where Bitrise's signing tooling can create and download the certificates and profiles it needs on demand, and it is also what the Deploy to App Store Connect Step uses to upload builds. This path reduces the number of files you manage by hand and avoids the recurring pain of expired manually-uploaded profiles, which is why many teams migrate to it once they outgrow manual uploads.
However you supply your assets, they must be activated inside the workflow at the right point. In the Workflow Editor, place the Certificate and profile installer Step, or the equivalent managed-signing setup Step, before the Xcode Archive & Export for iOS Step. The archive Step is where signing actually happens, so it needs the certificate installed and the profiles in place before it runs. Configure the archive Step's distribution method input — app-store, ad-hoc, development, or enterprise — to match the provisioning profile you intend to use, because a mismatch between the requested export method and the available profile is a frequent failure. If you are using an API key with automatic signing, set the archive Step to automatic signing and provide the API key connection so it can resolve assets on the fly; if you are using uploaded files, set it to manual and let the installer Step supply them. Confirm the ordering by reading the Step list top to bottom: clone, dependencies, install certificates and profiles, then archive and export. Correct ordering plus a matching export method resolves the vast majority of configuration mistakes.
After configuring signing, run a full archive workflow and read the logs from the installer and archive Steps carefully. A successful run shows the certificate imported, the profiles installed and matched to your bundle identifier, and xcodebuild exporting a signed .ipa without errors. Save that .ipa as an artifact and, ideally, feed it directly into a deploy Step so you validate the entire chain end to end. Signing is not set-and-forget: certificates and provisioning profiles expire — distribution certificates on a multi-year cycle and profiles typically after a year — so a pipeline that works today can fail later purely because an asset lapsed. If you rely on manually uploaded files, calendar a reminder to regenerate and re-upload before expiry. If you use an API key with automatic signing, most of this renewal is handled for you, which is a strong argument for that approach. Also rotate and protect your secrets: treat the .p12 password, the .p8 key, and the API key IDs as sensitive credentials, store them only in Bitrise's secret storage, and never commit them to your repository or print them in logs.
It is worth stepping back to be honest about what this automation does and does not do. Bitrise streamlines the mechanics of getting valid certificates and profiles onto an ephemeral build machine and invoking Apple's signing correctly, which removes real, recurring friction. What it cannot do is grant the underlying authority — that comes exclusively from your Apple Developer Program membership and the assets Apple issues under it. If your team is uneasy about uploading a distribution certificate's private key to a third-party service, the API key path narrows the surface area, but you are still trusting Bitrise's infrastructure with signing capability, which is a real vendor-trust decision worth making consciously. For teams that value keeping signing entirely inside Apple's own ecosystem, Xcode Cloud handles signing without exposing exportable keys at all, and that trade-off is legitimate. Bitrise's value is efficiency and flexibility across providers, not the elimination of Apple's requirements. Whichever route you choose, the fundamentals stay the same: a valid certificate, a matching non-expired profile, the right export method, and secrets kept out of your source tree.
codesigndoc is Bitrise's open-source command-line tool that runs an archive on your Mac to observe exactly which certificate and provisioning profiles your scheme uses, then exports and optionally uploads them to Bitrise. You do not strictly have to use it — you can export files manually from Xcode and Keychain — but it removes guesswork about which of several assets are actually needed, so it prevents a common class of signing mistakes.
An App Store Connect API key is generally more robust: it authenticates without Apple ID passwords or two-factor prompts, enables automatic managed signing, and reduces the manual work of re-uploading expired profiles. Uploaded .p12 and .mobileprovision files still work well and give you explicit control. Many teams start with uploaded files and migrate to an API key as their pipeline matures.
The most common causes are a bundle identifier that does not match the profile, an expired profile, or a distribution method in the archive Step that does not match the profile type. Confirm the profile's bundle ID equals your app's, check the expiry date, and ensure the export method — app-store, ad-hoc, development, or enterprise — matches the profile you uploaded or that the API key resolves.
Place the Certificate and profile installer Step, or the managed-signing setup Step, before the Xcode Archive & Export for iOS Step. Signing happens during the archive, so the certificate must be imported and the profiles installed before that Step runs. A correct order reads top to bottom as clone, install dependencies, install certificates and profiles, then archive and export.
Store the .p12 password, the .p8 API key file, and key identifiers only in Bitrise's secret storage or Code Signing tab, never in your repository or in log output. Treat them as sensitive credentials. Using an App Store Connect API key narrows exposure compared to uploading an exportable private key, and rotating credentials periodically is good hygiene for any CI service.