Cover: certificates, profiles, keys, what expires and what you can't lose. Apple Distribution certificate 1 year, make a new one; ad hoc or dev profile 1 year, regenerate; Developer ID certificate 5 years, 5 per team; Android upload key 25+ years, Google resets it; app signing key you hold 25+ years, lose it and no more updates

A React Native app is signed twice, once for each platform, and the two systems have nothing in common. iOS uses certificates that expire every year and provisioning profiles that tie a certificate to an app and, for test builds, to a list of devices. Android uses keys that are meant to last decades, one of which you must never lose. Most signing pain comes from not knowing which item is which, who holds it, and what breaks when it expires. This is the inventory for both sides, with the numbers from Apple's, Google's and Expo's documentation as they read on 25 October 2026, and what to do when something goes wrong.

iOS: what you hold and how long it lasts

text
item                         belongs to     how many                      lasts
Apple Development cert       a developer    no published limit            1 year
Apple Distribution cert      the team       Apple: one of each type       1 year
                                            per team (Account Holder or
                                            Admin creates it)
development profile          an app ID      as many as you need           1 year (Expo docs:
ad hoc profile               an app ID                                    profiles expire after
App Store profile            an app ID                                    12 months)
devices for dev + ad hoc     the team       100 per product family        membership year
                                            (iPhone, iPad, Mac, ...)
APNs auth key (.p8)          the team       2 (Expo docs)                 doesn't expire
App Store Connect API key    team or user   as needed; .p8 downloads      until revoked
                                            once
Developer ID cert (macOS)    the team       5 Application + 5 Installer   5 years

Since Xcode 11 the certificate types are just Apple Development and Apple Distribution; the old iOS Development and iOS Distribution types are only for Xcode 11 and earlier. A provisioning profile is what makes a certificate usable: it names the app ID, the certificate, the entitlements (push, App Groups, Sign in with Apple) and, for development and ad hoc profiles, the device UDIDs. Change any of those and the profile has to be regenerated.

What breaks when a certificate expires or is revoked

This is the table to read before you click Revoke. Apple's certificates page is explicit about App Store and in-house builds; the ad hoc line follows from the profile, which is only valid with a valid certificate (fastlane's docs say the same: revoking disables ad hoc and enterprise builds, while App Store and TestFlight builds keep working).

text
build already out there       distribution cert expires          cert revoked
App Store / TestFlight         keeps working; you can't upload    keeps working; uploaded builds not
                               new builds signed with it          yet submitted may be marked
                                                                  Invalid Binary
ad hoc test builds             stop installing when the profile   stop installing and launching
                               expires                            (profile is no longer valid)
in-house (Enterprise)          users can no longer run it         users can no longer run it
Developer ID (macOS)           keeps running, can't sign updates  can't be installed any more
push certificate (old style)   no more pushes                     no more pushes

Two practical consequences. First, an expiring App Store distribution certificate is not an emergency: Apple's DTS says it only has to be valid at the moment you upload, so you create a new one, regenerate the App Store profile and carry on. Second, revoking is the dangerous action, not expiry: revoke the certificate your ad hoc testers are on and every tester build stops at once. Use the .p8 APNs key instead of push certificates; it doesn't expire and one key serves every app in the team.

Newer rules for test builds

For teams created after 6 June 2021, development and ad hoc apps check in with Apple (ppq.apple.com) on first launch. A device that will be offline can use an offline profile, valid for 7 days, and apps that must run offline longer need extended offline validity from Apple. If a tester's freshly installed ad hoc build won't open on a locked-down network, that check is the first suspect.

Android: two keys, one of which must never be lost

text
key                  who holds it                 signs                 if it's lost
app signing key      Google (Play App Signing)    the APKs users        with Play App Signing: nothing
                     or you (older apps)          install               to do. Self-managed: you can
                                                                        never update the app again
upload key           you                          the AAB you upload    Google resets it; plan 2-3 days
                                                  to Play

Play App Signing has been required for new apps since August 2021, when app bundles became mandatory: Google keeps the app signing key, which never changes for the life of the app, and you sign uploads with a separate upload key that can be replaced. Google generates RSA 4096-bit app signing keys; an upload key must be RSA of at least 2048 bits, in a Java keystore. Google recommends a validity of at least 25 years, and Play requires a key that is valid until after 22 October 2033.

New in 2026, and worth knowing before you set up a new app: Google's Play App Signing page now says new apps are enrolled in quantum-ready hybrid signing with Google-generated keys, a classical RSA 4096-bit key plus a post-quantum ML-DSA-65 key, which Android 17 (API level 37) and above verify with APK signature scheme v3.2. You can also request an annual key upgrade for installs on Android 17 and above. The practical effect for most teams: more than one app signing certificate fingerprint to register with services such as Firebase.

Make the upload key once, properly

bash
keytool -genkeypair -v -storetype PKCS12 \
  -keystore my-upload-key.keystore -alias upload \
  -keyalg RSA -keysize 2048 -validity 10000

# 10,000 days = 27.4 years: made on 2026-10-25, valid until 2054-03-12,
# past Play's 22 October 2033 minimum and Google's 25-year advice

PKCS12 has been the JDK's default keystore type since JDK 9. Keep the passwords out of the repository: the React Native docs put them in ~/.gradle/gradle.properties (your user's Gradle settings, not the project's), and Android's docs use a keystore.properties file that is kept out of source control:

groovy
// android/app/build.gradle
def ks = new Properties()
def ksFile = rootProject.file("keystore.properties")   // in .gitignore
if (ksFile.exists()) ks.load(new FileInputStream(ksFile))

android {
    signingConfigs {
        release {
            storeFile file(ks["storeFile"] ?: "missing.keystore")
            storePassword ks["storePassword"]
            keyAlias ks["keyAlias"]
            keyPassword ks["keyPassword"]
        }
    }
    buildTypes { release { signingConfig signingConfigs.release } }
}

Resetting a lost upload key

bash
1. keytool -genkeypair ... (as above) to make a new upload key
2. keytool -export -rfc -keystore new-upload.keystore -alias upload \
       -file upload_certificate.pem
3. Play Console > your app > Protected with Play > Play Store distribution
   > Go to Play app signing > Request upload key reset; give a reason, attach the .pem, Request
4. wait: Google gives no time; Expo's docs say the new certificate's
   validity starts 72 hours in the future, so don't plan a release that week

The bug everyone hits once: fingerprints

Google Sign-In, Firebase Auth and Maps API keys check the SHA-1 or SHA-256 fingerprint of the certificate that signed the installed app. With Play App Signing that is Google's app signing key, not your upload key. The symptom is a build that signs in fine when you install it from your machine and fails for everyone who installs from Play (DEVELOPER_ERROR or error code 10 from Google Sign-In). Register all of them:

bash
fingerprint                       where to get it
debug keystore                    ./gradlew signingReport   (password 'android')
upload key                        keytool -list -v -keystore my-upload-key.keystore
app signing key(s)                Play Console > Protected with Play > Play Store
                                  distribution > Go to Play app signing
the APK you actually shipped      apksigner verify --print-certs app-release.apk

Signing on CI without tears

On iOS the private key behind a certificate exists only in the keychain where the certificate signing request was made, so a laptop that dies takes it along. Export the certificate with its key as a password-protected .p12 and keep it with the other secrets, or let a tool own it: fastlane match keeps certificates and profiles in an encrypted git repo (or Google Cloud or S3) and its docs recommend readonly mode on CI; fastlane setup_ci creates a temporary keychain for the run. With Expo, EAS stores the distribution certificate, profiles and push key on its servers, so collaborators can build with just their Expo account, and eas build:resign re-signs an existing .ipa with a new ad hoc profile after you add a device, without a rebuild.

bash
# a CI keychain by hand (what setup_ci does for you)
security create-keychain -p "$KC_PASS" build.keychain
security unlock-keychain -p "$KC_PASS" build.keychain
security import dist.p12 -k build.keychain -P "$P12_PASS" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple: -s -k "$KC_PASS" build.keychain
security list-keychains -d user -s build.keychain login.keychain

A yearly signing calendar

text
when                         do
membership renewal           Account Holder: prune the device list (the only time
                             the 100-per-family count resets)
~30 days before cert expiry  make the new Apple Distribution cert, regenerate the
                             ad hoc and App Store profiles, rebuild ad hoc builds
                             for testers, update CI secrets (.p12, profiles)
any time a device is added   regenerate the ad hoc profile; rebuild or re-sign
new Android app              let Play generate the app signing key; back up the
                             upload keystore and its passwords in two places
new Firebase/Google service  register the app signing fingerprints, not just the
                             upload key's

Android developer verification adds one more reason to guard keys: you register each package name with its signing key, and Google's FAQ says that if you lose your signing key you won't be able to register your packages. See developer verification for apps outside Play.

aipps.dev signs your iOS and Android builds on our own machines with your certificates, profiles and upload key, and every build gets a QR install page.

See aipps.dev

Related: installing an ad hoc build from a QR code shows how the profile's device list decides who can install, and TestFlight in practice covers the App Store side of distribution.

Sources, read 25 October 2026: Apple Developer, Certificates support page (one distribution certificate of each type per team; what happens on expiry and revocation), Certificates overview, Devices overview, Create a development provisioning profile, Provisioning profile updates (ppq check-in, 7-day offline profiles), Developer ID (five certificates of each type); Apple DTS forum posts on certificate limits and on upload-time validity; Google Play Console Help, Use Play App Signing (RSA 4096, upload key RSA 2048+, hybrid ML-DSA-65 signing, annual key upgrade) and Reset a lost or compromised upload key; Android Developers, Sign your app (25 years, 22 October 2033, keystore.properties); Google, Authenticating your client (fingerprints); OpenJDK JEP 229 (PKCS12 default); React Native, Publishing to Google Play Store; Expo docs, App credentials and Managed credentials; fastlane match and setup_ci docs; Android developer verification FAQ.