Code Signing
Code signing verifies that OTA updates were produced by your team and have not been tampered with. DeployPulse uses RS256 JWT signing.
How it works
- The CLI computes a SHA-256 hash of the bundle manifest (the
.codepushreleasefile is excluded from the hash) - The hash is embedded in a signed JWT (
packageSignature) using your RSA private key - The JWT is uploaded alongside the bundle
- The server verifies the JWT against your app's registered public key before accepting the release - unsigned releases are rejected if a public key is set
Setup
Step 1 - Generate an RSA key pair
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
Step 2 - Register the public key with the server
dpctl app set-public-key <appName> public.pem
Alternatively, paste the contents of public.pem into the Public Key field under App Settings in the dashboard.
Step 3 - Embed the public key in your app
The SDK reads the public key at runtime to verify downloaded bundles. Add it to your native config files using the CodePushPublicKey key.
iOS - add to Info.plist:
<key>CodePushPublicKey</key>
<string>-----BEGIN PUBLIC KEY-----
YOUR_PUBLIC_KEY_CONTENT_HERE
-----END PUBLIC KEY-----</string>
Android - add to strings.xml:
<resources>
<string name="app_name">AppName</string>
<string moduleConfig="true" name="CodePushDeploymentKey">{{DEPLOYMENT_KEY_HERE}}</string>
<string moduleConfig="true" name="CodePushServerUrl">https://apps.deploypulse.io/</string>
<string moduleConfig="true" name="CodePushPublicKey">-----BEGIN PUBLIC KEY-----
YOUR_PUBLIC_KEY_CONTENT_HERE
-----END PUBLIC KEY-----</string>
</resources>
The public key must match the private key used to sign releases. If they don't match, the SDK will refuse to apply the update.
Step 4 - Release with signing
Pass --private-key to any release command:
dpctl release-react <appName> ios --private-key ./private.pem -d Production
Keep private.pem out of source control. Add it to .gitignore and store it as a secret in your CI/CD environment.
GitHub Actions example
The --private-key flag accepts either a file path or inline PEM content, so you can pass your private key secret directly from a GitHub Actions secret — no temp file needed:
- Local development:
--private-key ./private.pem - CI (inline PEM from secret):
--private-key "${{ secrets.CODE_SIGNING_PRIVATE_KEY }}"
Store your private key as a repository secret (CODE_SIGNING_PRIVATE_KEY) and pass it inline:
- name: Release to Production
run: |
dpctl release-react MyApp-iOS ios \
--private-key "${{ secrets.CODE_SIGNING_PRIVATE_KEY }}" \
-d Production
env:
DPCTL_TOKEN: ${{ secrets.DPCTL_TOKEN }}
Removing a public key
Clear the Public Key field in App Settings in the dashboard. New releases will no longer require a signature. Existing signed releases remain valid.
