Code Signing
Code signing is required to distribute your apps to real devices, TestFlight, the App Store, or Google Play. BuildMagic stores your signing credentials encrypted and applies them automatically during builds.
Signing material lives at the team level, under Settings → Code Signing. One certificate covers every app in the team, which matches how Apple issues them — you are limited to a small number per account, so they are not per-app.
Two ways to sign, and both always work
You can upload the certificates and profiles you already have, or let BuildMagic obtain them from Apple for you. These are not exclusive: anything you upload yourself takes priority and is never replaced or renewed automatically. Turning automatic management on only fills in what is missing.
Automatic iOS signing (recommended)
Give BuildMagic an App Store Connect API key and it will issue and renew the distribution certificate and the provisioning profiles your apps need, without you visiting Apple's portal. The private key is generated on the server and never leaves it.
- Create an API key at App Store Connect → Users and Access → Integrations. Give it the Admin or App Manager role — a Developer-role key cannot manage certificates and will return a permission error.
- Download the
.p8file. Apple only lets you download it once. Note the Key ID and Issuer ID. - In BuildMagic go to Settings → Code Signing, open App Store Connect API keys and upload it.
- Turn on Manage signing automatically.
From then on, a build that has no valid certificate or profile for its bundle ID gets them created before compiling. Nothing runs in the background — it is resolved at build time and it is idempotent, so a second build creates nothing.
You can also do it ahead of time rather than discovering a permission problem during a build:
- Generate certificate — issues the distribution certificate straight away. If you already have a valid one it says so and creates nothing, rather than spending one of Apple's limited slots.
- Fetch from Apple — lists what already exists in your Apple account and imports the provisioning profiles you pick.
What automatic signing cannot do
- Certificates created outside BuildMagic cannot be reused. Apple never releases a certificate's private key, so one issued elsewhere can be listed but not signed with. Fetch from Apple marks those as unusable and explains why instead of importing something that would fail mid-build.
- Apple limits distribution certificates per account. If you hit the limit, the error names it and points at revoking an unused one.
- The App ID must already be registered in Apple's portal. Registering it automatically is not supported yet; the error tells you which identifier to create.
- Capability changes are not detected. A profile is only regenerated when it nears expiry. If you add a capability (Associated Domains, Push Notifications, HealthKit…), delete the profile in BuildMagic so the next build creates a fresh one.
Manual iOS signing
If you prefer to manage signing yourself, or you have no API key, upload the material directly. This path is unchanged and fully supported.
Signing certificate (.p12)
- On your Mac, open Keychain Access and choose Certificate Assistant → Request a Certificate from a Certificate Authority. Save the request to disk.
- At Apple Developer → Certificates, create an Apple Distribution certificate, upload the request and download the
.cer. - Double-click the
.certo install it, then right-click it in Keychain Access and export it as a.p12with a password. - In Settings → Code Signing, click Upload .p12 and provide the file and its password.
There is also a Generate CSR option, which creates the signing request on the server so the private key never exists on your machine. You take the request to Apple and upload the resulting .cer back. With an API key connected you do not need this — Generate certificate does the whole exchange for you.
Provisioning profile (.mobileprovision)
A profile ties your bundle ID to your certificate. Create one at Apple Developer → Profiles — choose App Store Connect for TestFlight and App Store, or Ad Hoc for direct installs — then upload it under Settings → Code Signing.
Profiles are matched to a build by bundle ID. App extensions are handled too: a profile whose bundle ID extends the app's (for a widget, a Siri intent, a notification service) is installed alongside the main one.
Android code signing
Android release builds are signed with a Java keystore. Create one with keytool if you do not have it already:
keytool -genkey -v -keystore my-release-key.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias my-key-aliasUpload it under Settings → Code Signing with its keystore password, key alias and key password.
Choosing which keystore an app uses
A team can hold several keystores, so each app names the one it signs with: app → Settings → Code Signing. The same applies to the Google Play service account used for publishing.
This is explicit on purpose. Signing an app with the wrong key produces an upload Google Play rejects, and once a package is published under one key it can never be changed — so when an app has no keystore selected, the build stops and says so rather than guessing. For publishing there is no fallback at all: without a Play account chosen, nothing is uploaded.
What the build does
The keystore is placed on the build machine before any step runs, at the path published as CM_KEYSTORE_PATH. Build configurations brought from Codemagic refer to it directly (storeFile=$CM_KEYSTORE_PATH), so they work unchanged. The default pipeline signs and zipaligns APKs and App Bundles, then verifies the result and prints the certificate fingerprint — if signing fails the build fails, rather than reporting success on an unsigned artifact.
Publishing
- TestFlight / App Store — needs an App Store Connect API key. The build number is resolved from App Store Connect automatically, so uploads are not rejected for reusing one. See automatic build numbers.
- Google Play — needs a service account JSON with the Play Developer API enabled, uploaded under Code Signing and selected on the app.
Security
- Certificates, keystores, API keys and their passwords are encrypted at rest with AES-256-GCM. Nothing sensitive is stored in plain text.
- Private keys generated for a certificate signing request never leave the server.
- Signing material is fetched into the build machine for the duration of the build only. Every build runs in a fresh VM or container that is destroyed afterwards.
- Access is scoped to your team and enforced both in the API and in the database queries, so another team cannot reach your credentials even by guessing an identifier.