Firmware signing & fwup
How NervesHub keeps firmware trustworthy: signing keys, fwup, and how both the server and the device verify a signature.
Written By Josh Kalderimis
Last updated About 2 months ago
NervesHub only ships firmware it can prove is authentic. That guarantee comes from cryptographic signing: firmware is signed with a private key, and both the server and the device verify the signature before trusting it. A tampered or unsigned image is rejected.
fwup
fwup is the tool Nerves uses to build, sign, and apply firmware. A firmware image is a .fw archive carrying the payload plus metadata (product, version, platform, architecture, UUID). fwup handles the signing on your build host and the verification and application on the device.
Signing keys
Signing uses a public/private key pair:
The private key signs firmware. Guard it: anyone with it can put firmware on your devices.
The public key verifies signatures. It's uploaded to NervesHub and embedded in your device's firmware, so both sides can check authenticity.
Create a key pair with the CLI (see the CLI reference):
nh key create my-keyThis stores the password-protected private key locally and uploads the public key to your organization. You can also manage keys in the web UI under the organization's Signing Keys, or generate them directly with fwup if you prefer an unprotected key for CI.
Who verifies what
Signing gives you end-to-end authentication with two independent checks:
NervesHub, on upload. When you publish firmware, NervesHub verifies its signature against the public signing keys registered to your organization. Firmware that doesn't match a known key is rejected.
The device, on apply. Your running firmware contains the public key, so
fwupverifies the downloaded image's signature on the device before writing it. Even if a download were tampered with in transit, the device won't apply it.
This is why the same key material lives in three places: the private key on your build host, the public key on NervesHub, and the public key baked into the device.
Signing firmware
Build, then sign with your key:
export FW_PATH="./_build/${MIX_TARGET}_dev/nerves/images/my_project.fw"
mix firmware
nh firmware sign "$FW_PATH" --key my-key
nh firmware publish "$FW_PATH"The Nerves build can also sign automatically during mix firmware when it knows your keys via environment variables. See the Quickstart and CLI reference.
Protecting your keys
Your signing private key and, for certificate auth, your Signer CA key are the most sensitive secrets in your setup. Treat them accordingly:
Store them in real secret management, not a repo.
Limit who can access them.
Keep backups: losing the signing key means you can no longer publish firmware your existing devices will accept.