Skip to content

Code signing

With code signing, the CLI signs each package with your RSA private key, and the SDK verifies the signature with the public key built into your app. Once a public key is configured, the SDK rejects unsigned packages and packages whose signature doesn’t match — even if your server or storage is compromised.

Terminal window
openssl genrsa -out private.pem 2048
openssl rsa -pubout -in private.pem -out public.pem

Keep private.pem secret: store it in your CI secret store and never commit it.

Platform Where Key
React Native — Android res/values/strings.xml PatchkitePublicKey
React Native — iOS Info.plist PatchkitePublicKey
Flutter — Android AndroidManifest.xml <meta-data> PatchkitePublicKey

In strings.xml and <meta-data>, put the PEM on one line with \n between lines. In Info.plist, the PEM can span multiple lines.

The public key is native configuration, so adding or changing it requires a store release.

Pass the private key to any release command:

Terminal window
patchkite release-react MyApp-Android android -k private.pem
patchkite release-flutter MyApp-Android android -k private.pem
patchkite release MyApp-Android ./build 1.0.0 -k private.pem

promote and rollback reuse the already signed package, so they don’t need the key.

The signature is a JWT signed with RS256 and stored in the package as .patchkiterelease. Its contentHash claim is the package hash. On the device, the SDK recomputes the hash from the extracted files and accepts the package only if the JWT verifies against the public key and its contentHash matches. Other algorithms, including none, are rejected.