In some projects, certificate issues do not surface during early development but suddenly appear during team collaboration, switching computers, or integrating CI.
For example, new colleagues cannot build after pulling code, CI builds fail but work locally, or signatures become invalid after provisioning profile updates. The common point of these problems is that certificates are not managed but remain on a specific device.
This article explains how to make the iOS signing environment reproducible, migratable, and reusable.
First, Clarify That a Certificate Is Not a Single File
iOS signing involves three types of files:
| Type | Purpose |
|---|---|
.cer |
Public key certificate |
| Private key | Generated locally |
.p12 |
Certificate + private key |
The key points are:
.cercannot be used alone.p12is the complete, migratable format
If team members only share .cer, the result is:
- The certificate exists
- But signing is impossible
Avoid Each Person Generating Certificates Individually; Instead, Generate and Distribute Uniformly
Follow these steps:
Step 1: Generate a Certificate (Once)
Create the certificate in a tool, not manually in the keychain.
Using AppUploader (Happy Upload):
- Open certificate management
- Click Add
- Select type (development or distribution)
- Enter certificate name
- Set P12 password
- Generate and download
.p12
The result of this step is:
- A complete P12 file
- No dependency on a specific Mac

Step 2: Save the Certificate
Store .p12 in:
- Private Git repository (encrypted)
- CI Secret
- Internal file service

Step 3: Use Uniformly
Import in various environments:
- macOS → Keychain
- CI → Script import
Synchronization Method for Provisioning Profiles
Certificates are only part of signing; provisioning profiles are also needed.
Provisioning profile binding:
- Bundle ID
- Certificate
Generation process:
- Open AppUploader
- Go to provisioning profile management
- Create new provisioning profile
- Select type (App Store / Development)
- Bind Bundle ID
- Select certificate
- Download
.mobileprovision
Save the provisioning profile together with .p12.

Load Certificates in CI
When integrating CI into a project, the build environment needs to load certificates.
Example (Fastlane):
import_certificate(
certificate_path: "cert.p12",
certificate_password: "password"
)
Provisioning profiles can be handled via:
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/
This allows CI to complete signing directly.
A Detail to Avoid Certificate Invalidation
Certificates themselves have an expiration date (usually one year).
But in a team, what truly matters is:
- Whether provisioning profiles use old certificates
After updating a certificate, you need to:
- Regenerate provisioning profiles
- Replace files in CI
- Rebuild
If you only update the certificate without updating provisioning profiles, signing will fail.
Handling in Cross-Platform Development
In Windows or Linux environments:
- Keychain cannot be used
- But
.p12can be used directly
For example:
- HBuilderX packaging
- CI builds
- Command-line uploads
Certificates exist only as files, without dependency on system tools.
How to Determine If the Current Certificate Is Usable
You can verify via:
Method 1: Xcode
- Check if the certificate includes a private key
Method 2: Command Line
security find-identity -v -p codesigning
Method 3: Build Verification
- Whether IPA can be successfully exported
The complexity of certificate issues is not in the creation steps but in how they are saved and used. If certificates are uniformly managed in .p12 format, many problems will be reduced.
Reference link: https://www.appuploader.net/blog/237