Bundle Signing
Note:
Bundle signing requires minimum Stallion CLI version 2.1.0 and minimum React Native Stallion SDK version 2.3.0.
Bundle signing is a security feature in Stallion that ensures your Over-the-Air (OTA) updates are authentic, tamper-proof, and origin-verified before being applied in production environments.
đź§ Why Bundle Signing Matters
In high-stakes environments—like fintech, healthcare, or enterprise apps—code integrity is critical. Without signing, OTA updates are vulnerable to:
-
Tampering in transit
-
Unauthorized deployment
-
Rollback to older, compromised builds
Bundle signing mitigates these risks by cryptographically verifying each update before it's applied.
🔑 How It Works
Now that you understand the core concept of bundle signing, let's walk through the process step by step — from generating your signing keys, to signing your bundle, and finally verifying the signature at runtime.
Step 1: First, you need to generate a key pair using the Stallion CLI:
stallion generate-key-pair
This will create two files in the stallion/secrets/
directory:
stallion/secrets/ ├── private-key.pem 🔒 Keep this secret. Used to sign bundles. └── public-key.pem 🔓 Safe to distribute. Used to verify signatures.
Step 2: Add the public key to your native configuration files
You need to add the public key to your Android strings.xml
and iOS Info.plist
files. The public key should be added as a string resource named StallionPublicSigningKey
. Here's how to do it:
- Copy the contents of your
stallion/secrets/public-key.pem
file - Add it to your native configuration files as shown below:
For Android (strings.xml
):
<resources>
<string name="app_name">StallionExample</string>
<string name="StallionProjectId">680cd3b922e4392b4291eec9</string>
<string name="StallionAppToken">spb_rqEcK-p8u4i8rnEcQYutlcdS7c0IGAQf2P1pSjJV1y</string>
<string name="StallionPublicSigningKey">YOUR_PUBLIC_KEY_HERE</string>
</resources>
For iOS (Info.plist
):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- ... other configurations ... -->
<key>StallionPublicSigningKey</key>
<string>YOUR_PUBLIC_KEY_HERE</string>
<!-- ... other configurations ... -->
</dict>
</plist>
The public key should be a long string that looks something like this:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh9Exmq0slWAXty4RBrGH AKSJDHasdaSADSadW2D/U3IulUD5SbrC8y/bdRcYV6Lrtyh/MsAemdtcAWPSjtM9 R9NME6RZdHqSC8iNPqnx0Fg0Q1nvasdasYJG1HQ/fpeLJplEtgArGNisWX2HAEB1 +NB8djwNhdnr9fPTcuDzni8asKv7aFwcJfMW8EJpXELMxI+wNAQnoa3PMx9NOdeQ zgMcm/GnVwpDtsIsoh9+phh4fS9w7hQzNz9IIP1kJqvev3vFGBB1HEQuWv2w0t5P PBi233rTQBAQRGCZCUu1zTfJRVXcEvylbrcZ+m3LnvKQ4GDHLeZIGtUUbxRANip4 iwIDAQAB -----END PUBLIC KEY-----
Important:
When adding the public key to your native configuration files, only copy the base64-encoded key content (the long string between BEGIN and END lines). Do not include the "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----" lines.
Step 3: Sign the Bundle During Publish
When publishing your bundle, you need to include the --private-key
parameter to sign it. This ensures that your bundle is cryptographically signed before being distributed to users.
stallion publish-bundle --upload-path=orgname/project-name/bucket-name --platform=android/ios --release-note="notes" --private-key="Path to your private key"
Example for Android:
stallion publish-bundle --upload-path=my-org/my-project/my-bucket --platform=android --release-note="my release notes" --private-key=./stallion/secrets/private-key.pem
Example for iOS:
stallion publish-bundle --upload-path=my-org/my-project/my-bucket --platform=ios --release-note="my release notes" --private-key=./stallion/secrets/private-key.pem
Important:
Make sure to use the same private key that corresponds to the public key you added in your native configuration files. Using different key pairs will cause signature verification to fail.
The signing process:
- The CLI reads your private key
- Generates a cryptographic signature of your bundle
- Attaches the signature to the bundle metadata
- Uploads both the bundle and its signature to Stallion servers
This signature will be used by the Stallion SDK to verify the authenticity of the update before installing it on users' devices.
Step 4: Verify Signature on the Device
In the Stallion SDK, before an update is installed, the runtime:
-
Extracts the bundle's signature
-
Validates it using the embedded public key
-
Rejects the update if validation fails
This ensures only trusted updates are applied.
🛡️ Security Best Practices
-
Never expose your private.key — store it securely in CI/CD secrets or a vault
-
Distribute the public.key inside your app or via a secure fetch mechanism
-
Rotate key pairs periodically