Section 08

Changing your keys

Five short runbooks. Each is safe to follow start to finish; where a step is irreversible it is marked.

Knowing when

Distribution certificates last three years and provisioning profiles last one. That is long enough that nobody remembers and short enough that everybody is eventually caught — usually on the morning a hotfix needs to ship. leas creds reads the dates back out of the files themselves, so there is nothing to keep in sync by hand.

leas creds                       # what expires, soonest first
leas creds --days 60             # widen the warning window
leas creds --check               # exit non-zero if anything is inside it

The scheduled version is the one that matters. The setup wizard can emit a leas-credentials.yml workflow that runs weekly on a cheap Linux runner, reads the expiry dates out of the same repository secrets your builds use, and opens an issue thirty days before anything lapses — then closes that issue once you have renewed.

Why this is safe to host

A credential record is metadata: a name, a date, and a public certificate fingerprint. No key material and no password is ever read out or sent anywhere. That is what makes it something a dashboard is allowed to hold at all — and it is the reason leas sync can show your expiry dates on a web page without becoming a custodian of your signing identity.

Rotate the App Store Connect API key

Do this when someone with access leaves, on a routine schedule, or after any suspected exposure. It is the safest of all the rotations — no builds break.

  1. App Store Connect → Users and Access → Integrations → generate a new key with the App Manager role. Download the .p8.
  2. Update ascApiKeyId and ascApiKeyPath in leas.json. The Issuer ID does not change.
  3. Push the new secrets:
    base64 -i credentials/ios/AuthKey_NEWKEYID.p8 | gh secret set LEAS_ASC_API_KEY_BASE64
    gh secret set LEAS_ASC_KEY_ID
  4. Prove it works — leas submit --platform ios --path .leas/build/ios/export/YourApp.ipa against a build you have already uploaded is a harmless test.
  5. Only then revoke the old key.

Replace an expired iOS distribution certificate

You will hit this roughly once a year, usually announced by a build failing with "No signing certificate found."

  1. Repeat setup step 3 to generate a new certificate. Do not revoke the old one yet — if you have a free slot, having both alive briefly makes this a zero-downtime change.
  2. Regenerate every provisioning profile that referenced the old certificate (next runbook).
  3. Update LEAS_IOS_DIST_CERT_BASE64, LEAS_IOS_DIST_CERT_PASSWORD, and the profile secret.
  4. Run a full cloud build to confirm.
  5. Revoke the old certificate.
Order matters here

Revoking first is the classic mistake. It invalidates the profiles before their replacements exist, so you cannot build the thing that would prove the new certificate works.

Regenerate a provisioning profile

Needed whenever the certificate changes, the bundle ID changes, or a capability is added.

# developer.apple.com → Profiles → select → Edit → pick the new cert → Generate → Download
base64 -i credentials/ios/profile.mobileprovision | gh secret set LEAS_IOS_PROVISIONING_PROFILE_BASE64

leas reads the profile's real name, UUID, and team ID out of the file at build time, so there is nothing to update in leas.json. Drop in the new file and build.

Rotate the Play service account

  1. Google Cloud → Service Accounts → open the account → Keys → Add key. Adding a key does not disturb the existing one.
  2. Save the JSON over credentials/android/play-service-account.json and update LEAS_PLAY_SERVICE_ACCOUNT_BASE64.
  3. Run a submit to the internal track to confirm.
  4. Delete the old key.

To replace the account entirely rather than just its key, create the new one, invite it in Play Console with the same permissions, verify, then revoke the old account's access.

Reset a compromised Android upload key

Only possible with Play App Signing

Generate a fresh keystore exactly as in setup step 6, then request an upload key reset through Play Console support, providing the new key's certificate. Google swaps which upload key it accepts. Your users are unaffected — the app signing key Google holds never changes, so updates continue to install over existing installs.

Rotate everything at once

After a laptop is lost or someone leaves with local copies, do all five in this order: Play service account key → ASC API key → upload keystore → iOS certificate → provisioning profiles. Credentials that break nothing go first; the certificate, which cascades, goes last.