HomeGuidesReferenceLearn
ArchiveExpo SnackDiscord and ForumsNewsletter

EAS Update Code Signing

Learn how code signing and key rotation work in EAS Update.


EAS Update Code Signing is only available to accounts subscribed to the EAS Enterprise plan. Sign up.

Introduction

The expo-updates library supports end-to-end code signing. Code signing allows developers to cryptographically sign their updates with their own keys. The signatures are then verified on the client before the update is applied, which ensures ISPs, CDNs, cloud providers, and even EAS itself cannot tamper with updates run by apps.

Code signing with EAS Update

1

Generate a private key and corresponding code signing certificate for your app:

Terminal
npx expo-updates codesigning:generate \
--key-output-directory keys \ --certificate-output-directory certs \ --certificate-validity-duration-years 10 \ --certificate-common-name "My App"
  • The generated private key must be kept private and secure.
  • The certificate validity duration is a setting that may vary based on the security needs of your app.
    • A shorter validity duration will require key rotation more frequently but is considered better practice since a compromised private key will have a sooner expiration which limits exposure.
    • Shorter validity durations add overhead to your app's release process as the key must be rotated more frequently. Binaries with expired certificates won't apply new updates.
    • For example, Expo sets this value to 20 years for the public Expo Go app, but only 1 year for internal apps with binaries that are distributed more frequently. We plan to rotate our keys every 10 years.

2

Configure your app's builds to use code signing:

Terminal
npx expo-updates codesigning:configure --certificate-input-directory certs --key-input-directory keys

After this step, create a new build with a new runtime version. The code signing certificate will be embedded in this new build.

3

Publish a signed update for your app:

Terminal
eas update --private-key-path keys/private-key.pem

During eas update, the EAS CLI automatically detects that code signing is configured for your app. It then verifies the integrity of the update and creates a digital signature using your private key. This process is performed locally so that your private key never leaves your machine. The generated signature is automatically sent to EAS to store alongside the update.

4

Download the update on the client (this step is done automatically by the library). The build from step (2) that is configured for code signing checks if there is a new update available. The server responds with the update published in step (3) and its generated signature. After being downloaded but before being applied, the update is verified against the embedded certificate and included signature. The update is applied if the certificate and signature are valid, and rejected otherwise.

Key rotation

Key rotation is the process by which the key pair used for signing updates is changed. This is most commonly done in a few cases:

  • Key expiration. In step (1) from the section above, we set certificate-validity-duration-years to 10 years (though it can be configured to any value). This means that after 10 years, updates signed with the private key corresponding to the certificate will no longer be applied after being downloaded by the app. Updates downloaded before the expiration of their signing certificate will continue to function normally. Rotating keys well before the certificate expires helps to preempt any potential key expiration issues and helps to guarantee all users are using the new certificate before the old certificate expires.
  • Private key compromise. If the private key used to sign updates is accidentally exposed to the public, it can no longer be considered secure and therefore can no longer guarantee integrity of updates it signed. For example, a malicious actor could craft a malicious update and sign it with the leaked private key.
  • Key rotation for security best practices. It is best practice to rotate keys periodically to ensure that a system is resilient to manual key rotation in response to one of the other reasons above.

In any of these cases, the procedure is similar:

  1. Backup the old key and certificate that were generated in step (1) above.
  2. Generate a new key by following the steps above. To assist in debugging, you may wish to change the keyid of the new key by modifying the updates.codeSigningMetadata.keyid field in your app config (app.json).
  3. The certificate is part of the app's runtime, so a new runtime version should be set for builds using this certificate to ensure that only updates signed with the new key run in the new build.
  4. Publish signed updates using the new key by following step (3) above.

Removing code signing

The process of removing code signing from an app is similar to key rotation and can be thought of as a key rotation to a null key.

  1. Backup the old key and certificate that were generated in step (1) above.
  2. Remove the updates.codeSigningMetadata field from your app config (app.json).
  3. The new certificate-less app is a new distinct runtime, so a new runtime version should be set for builds to ensure that only unsigned updates run in the new build.