DeployPulse

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

  1. The CLI computes a SHA-256 hash of the bundle manifest (the .codepushrelease file is excluded from the hash)
  2. The hash is embedded in a signed JWT (packageSignature) using your RSA private key
  3. The JWT is uploaded alongside the bundle
  4. 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>

Step 4 - Release with signing

Pass --private-key to any release command:

dpctl release-react <appName> ios --private-key ./private.pem -d Production

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.