Skip to content
Hotrail

Docs

Signing and encryption

How Hotrail signs bundle manifests, how devices verify them, and what encrypted bundles need.

Signing is on by default

The init command creates an Ed25519 key pair in .hotrail/signing-key.json and adds that folder to .gitignore. Keep the private key out of source control. The public key is printed once. Put it in your Capacitor config as hotrailPublicKey.

On the first signed upload the public key is registered for the app. Every later upload is verified against it.

What is signed

Upload hashes every file with SHA-256, builds a manifest of paths and hashes, and signs the manifest. Only files the server does not already have are sent. The plugin verifies the signature, then verifies the hash of every file it downloads.

bash
npx @buffersol/hotrail upload
# for a test only, skips signing:
npx @buffersol/hotrail upload --unsigned

Device checks

With publicKey set in the plugin, only bundles that offer a signed manifest are installed. A bad signature, a wrong key, a changed manifest or a hash mismatch rejects the whole bundle, sends a failure beacon and marks that version as failed so it is not downloaded again. Unsigned bundles are rejected by devices that check signatures.

Encrypted bundles

The update response can carry a session_key, which is AES-CBC key material. The plugin TypeScript layer reads it. Decryption of the zip or files happens in native code, and that native code has not been compiled or tested on devices yet. Do not rely on encrypted bundles in production until the plugin CI is green and you have tested on a device.