iOS Certificates and Provisioning Profiles Explained¶
If you've ever hit a cryptic code signing error in Xcode and spent hours trying to figure out what went wrong, you're not alone. iOS code signing is one of the most confusing parts of iOS development, especially for developers coming from web or Android backgrounds. The good news is that once you understand the pieces and how they fit together, it all starts to make sense.
In this guide, you'll learn what certificates and provisioning profiles are, how they work together, and which combinations you need for each type of build.
Why iOS Code Signing Exists¶
Every app that runs on a physical iOS device must be code signed. This is Apple's way of ensuring that:
- Identity: The app comes from a known, verified developer.
- Integrity: The app hasn't been tampered with since it was signed.
- Authorization: The app is allowed to run on that specific device or be distributed through a specific channel.
Unlike Android, where you can generate your own signing key without a central authority, Apple acts as the gatekeeper. You need an Apple Developer account, Apple-issued certificates, and Apple-generated provisioning profiles before your app can leave the simulator.
The Building Blocks¶
iOS code signing relies on three key pieces working together: certificates, provisioning profiles, and the private key on your Mac.
Certificates¶
A certificate is a digital document issued by Apple that verifies your identity as a developer. When you create a certificate, your Mac generates a public/private key pair. The private key stays in your Keychain, and the public key is sent to Apple as part of a Certificate Signing Request (CSR). Apple then issues a certificate containing your public key and Apple's own digital signature.
There are two main types of certificates:
- Apple Development — Used for building and running apps on your own test devices during development. This certificate belongs to you as an individual developer. You can have up to two development certificates at a time.
- Apple Distribution — Used for distributing apps via the App Store, TestFlight, or Ad Hoc. This certificate belongs to the team, not an individual. Only Account Holders or Admins can create it.
There's also a third type for companies enrolled in the Apple Developer Enterprise Program:
- iOS Distribution (In-House) — Used exclusively for distributing proprietary apps to employees within a company.
Certificate Naming History
Before Xcode 11, Apple used platform-specific certificate names like "iOS Development" and "iOS Distribution." In 2019, Apple unified these into "Apple Development" and "Apple Distribution," which work across iOS, macOS, tvOS, and watchOS. You might still see the old names in older projects, but new certificates use the unified naming.
Provisioning Profiles¶
A provisioning profile is the glue that ties everything together. It's a file generated by Apple that bundles four pieces of information:
- App ID — The bundle identifier of your app.
- Certificate(s) — Which signing certificates are authorized to sign the app.
- Entitlements — Which capabilities the app is allowed to use (Push Notifications, iCloud, HealthKit, etc.).
- Device UDIDs — Which specific devices can run the app (only for Development and Ad Hoc profiles).
There are four types of provisioning profiles:
- Development — For running the app on registered test devices from Xcode.
- Ad Hoc — For distributing the app to a limited list of registered devices outside the App Store (up to 100 per device type per year).
- App Store — For submitting the app to App Store Connect for TestFlight or public App Store release.
- In-House — For distributing apps internally to employees (Enterprise Program only).
How They Work Together¶
When you build your app, Xcode uses your private key to sign the app bundle and embeds the provisioning profile into it. When an iOS device receives the app, it checks three things:
- Does the signature match a certificate listed in the provisioning profile?
- Does the app's bundle ID match the App ID in the profile?
- Is this device in the allowed list (for Development and Ad Hoc builds)?
If any of these checks fail, the app won't install or run. This is why mismatching a certificate with the wrong profile type causes those frustrating signing errors.
Certificate and Build Type Compatibility Matrix¶
Here's the compatibility matrix that shows exactly which certificate and provisioning profile you need for each build type:
| Build Type | Required Certificate | Required Profile | Used For |
|---|---|---|---|
| Simulator | None | None | Testing on the Xcode Simulator |
| Development | Apple Development | Development | Running on physical test devices via Xcode |
| Ad Hoc | Apple Distribution | Ad Hoc | Distributing to registered devices outside the App Store |
| App Store / TestFlight | Apple Distribution | App Store | Submitting to App Store Connect for TestFlight or public release |
| Enterprise (In-House) | iOS Distribution (In-House) | In-House | Internal distribution to company employees |
The key rule is simple: certificates and profiles must match. A Development certificate only works with a Development profile. An Apple Distribution certificate works with Ad Hoc and App Store profiles. Mixing them will result in a code signing error.
Key Things to Keep in Mind¶
TestFlight Uses App Store Signing¶
This trips up a lot of developers. Even though TestFlight is a testing tool, Apple treats TestFlight builds as App Store builds. You need an Apple Distribution certificate and an App Store provisioning profile to upload to App Store Connect. An Ad Hoc profile will not work — the upload will fail with a "Provisioning profile is not an iOS App Store profile" error.
Certificate Limits¶
Apple enforces limits on how many certificates you can have:
- Development: Up to 2 per individual developer.
- Distribution: Up to 3 active iOS Distribution certificates per team (standard program).
If you hit the limit, you'll need to revoke an existing certificate before creating a new one. Keep in mind that revoking a certificate invalidates all provisioning profiles that reference it.
Enterprise Requires a Separate Program¶
The Apple Developer Enterprise Program ($299/year) is separate from the standard Apple Developer Program ($99/year). It's intended exclusively for distributing proprietary apps to a company's employees. Misusing it to distribute apps to the public can result in Apple revoking your certificate, which immediately breaks all deployed apps.
Since iOS 18, manually installed enterprise apps (not via MDM) require a device restart to establish trust with the provisioning profile. Apple recommends using an MDM solution for enterprise distribution, which bypasses this restart requirement.
Automatic Signing and Cloud-Managed Certificates¶
If managing certificates and profiles manually sounds tedious, Xcode offers an "Automatically manage signing" option that handles most of the work for you. Since Xcode 13, Apple also supports cloud-managed certificates for distribution. These are created and rotated automatically — no need to manually manage a local distribution certificate in your Keychain.
Cloud signing works when you use the Xcode Organizer archive and distribution workflow. If no local distribution certificate is found, Xcode falls back to cloud-managed signing automatically.
Common Mistakes to Avoid¶
Here are the most common code signing pitfalls and how to avoid them:
- Mismatching certificate and profile types — Using a Development certificate with an App Store profile (or vice versa) is the most common cause of signing errors. Always verify that your certificate type matches your profile type.
- Expired or revoked certificates — When a certificate expires or is revoked, all provisioning profiles that reference it become invalid. Builds that worked yesterday will suddenly fail.
- Missing private keys — The private key is generated on a specific Mac and stored only in that Mac's Keychain. If you switch machines without exporting the key as a
.p12file, you won't be able to sign with that certificate anymore. - Wrong team selected in Xcode — If you belong to multiple Apple Developer teams, make sure the correct team is selected in your project's Signing & Capabilities tab. Selecting the wrong team is a surprisingly common and hard-to-spot mistake.
- Bundle ID mismatches — The bundle identifier in your Xcode project must exactly match the App ID in your provisioning profile. Even a small typo will cause a signing failure.
Try Capawesome Cloud¶
If you're building Capacitor apps, Capawesome Cloud can take the pain out of iOS code signing. Upload your certificates and provisioning profiles once, and let cloud builds handle the signing for you — no local Keychain management required.
Conclusion¶
iOS code signing comes down to three things: certificates prove your identity, provisioning profiles define where and how your app can run, and the two must always match. Once you understand the compatibility rules — Development certificates with Development profiles, Distribution certificates with Ad Hoc or App Store profiles — most signing errors become straightforward to diagnose and fix.
If you're setting up a CI/CD pipeline for your Capacitor app and want to avoid common signing issues, check out Common CI/CD Pitfalls for Capacitor Apps for practical tips on automating your builds.
If you have questions, feel free to join the Capawesome Discord server. To stay up to date with the latest news, subscribe to the Capawesome newsletter.