Code signing with CodePush
Code signing is a security mechanism that adds a digital signature to your CodePush bundles (JavaScript updates). This signature allows the client app to verify that a trusted source created the update and that it has not been tampered with during delivery.
Code signing is a security mechanism that adds a digital signature to your CodePush bundles (JavaScript updates). This signature allows the client app to verify that a trusted source created the update and that it has not been tampered with during delivery.
CodePush code signing is done in three stages:
-
Generating an RSA keypair:
-
The private key is used to sign the CodePush bundles.
-
The public key is embedded into the mobile app to verify signatures.
-
-
When releasing a CodePush update, the Bitrise CodePush CLI signs the bundle using the private key. It creates a JWT (JSON Web Token) containing the bundle's hash, digitally signed with this private key.
-
The mobile app (with the embedded public key) verifies the JWT signature before applying the update. If verification fails, the update is rejected.
Signing your app
iOS
Android
-
Use version 5.1.0 or higher of the CodePushNext React Native SDK. Earlier versions don't support code signing.
You can find the SDK here: CodePushNext repository.
-
Make sure the Bitrise CodePush CLI version is 1.0.0 or higher to take advantage of code signing features.
-
Generate an RSA keypair in PEM format with Open SSL:
openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -pubout -out public_key.pem
You must keep the private key secure and never share it! The public key will be embedded inside the app itself.
-
Add the public key string inside your app’s
Info.plist:<key>CodePushPublicKey</key> <string>-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVJ2k... -----END PUBLIC KEY-----</string>
-
Rebuild your iOS app with the updated
react-native-code-pushSDK (>= 5.1.0) that supports code signing. -
Bundle and sign your updates with the Bitrise CodePush CLI. The output directory must be named CodePush.
bitrise :codepush bundle --platform ios --private-key-path ./private_key.pem
The signed JWT (
.codepushreleasefile) is generated inside the bundle directory and uploaded to the server. The uploaded.zipfile contains both the.codepushreleasefile and the bundled output file. -
Push the already bundled update:
bitrise :codepush push ./CodePush \ --deployment Staging \ --app-version 1.0.0 \ --private-key-path ./private_key.pem
Tip
Optionally, you can bundle, sign, and push in one command:
bitrise :codepush push --bundle --platform ios \ --deployment Staging \ --app-version 1.0.0 \ --private-key-path ./private_key.pem
-
Use version 5.1.0 or higher of the CodePushNext React Native SDK. Earlier versions don't support code signing.
You can find the SDK here: CodePushNext repository.
-
Make sure the Bitrise CodePush CLI version is 1.0.0 or higher to take advantage of code signing features.
-
Generate an RSA keypair in PEM format with Open SSL:
openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -pubout -out public_key.pem
You must keep the private key secure and never share it! The public key will be embedded inside the app itself.
-
Add the public key string in
/android/app/src/main/res/values/strings.xml:<resources> <string name="CodePushPublicKey">-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVJ2k... -----END PUBLIC KEY-----</string> </resources> -
Configure the CodePush client instance.
You can use a constructor:
new CodePush("deployment-key", getApplicationContext(), BuildConfig.DEBUG, R.string.CodePushPublicKey);Or you can use a builder:
new CodePushBuilder("deployment-key", getApplicationContext()) .setIsDebugMode(BuildConfig.DEBUG) .setPublicKeyResourceDescriptor(R.string.CodePushPublicKey) .build(); -
Rebuild your Android app with the updated
react-native-code-pushSDK (>= 5.1.0) that supports code signing. -
Bundle and sign your updates with the Bitrise CodePush CLI. The output directory must be named CodePush.
bitrise :codepush bundle --platform android --private-key-path ./private_key.pem
The signed JWT (
.codepushreleasefile) is generated inside the bundle directory and uploaded to the server. The uploaded.zipfile contains both the.codepushreleasefile and the bundled output file. -
Push the already bundled update:
bitrise :codepush push ./CodePush \ --deployment Staging \ --app-version 1.0.0 \ --private-key-path ./private_key.pem
Tip
Optionally, you can bundle, sign, and push in one command:
bitrise :codepush push --bundle --platform android \ --deployment Staging \ --app-version 1.0.0 \ --private-key-path ./private_key.pem
Code signing support for Expo
CodePushNext and the Bitrise CodePush CLI both support code signing for Expo projects, too. The overall flow is the same as for standard React Native apps: generate an RSA key pair, embed the public key in the app, and sign bundles at release time using the --private-key-path flag.
The main difference for managed Expo workflows is how the public key gets embedded: this typically requires EAS Build and a custom config plugin. When bundling and pushing updates, use the standard bitrise
:codepush commands as usual.
Note
The --sourcemap-output flag is not supported for Expo projects and should be omitted.