Skip to content

Build OS firmware and configure RAUC signing #

This guide connects four separate jobs:

  1. build a Linux image and RAUC bundle;
  2. sign the bundle with product-owned keys;
  3. configure the same public trust on the device and Dataplicity Device Class;
  4. provision each physical device into a Dataplicity organisation.

Dataplicity OS is the worked CM5 example. A custom Yocto or Buildroot image uses the same trust model.

Understand the identities #

IdentityPurposeStored where
Dataplicity device identityAuthenticates one physical device to your organisationPersistent /var/lib/dataplicity
RAUC compatiblePrevents a valid bundle for one product or layout from installing on anotherDevice system.conf and bundle manifest
RAUC CA certificateDefines which bundle-signing certificates the device trustsPublic keyring in every rootfs slot
RAUC signing certificate and private keyCreates the CMS signature on a .raucbProtected build system or signing service
Device Class keyringLets Dataplicity verify a bundle before offering it to devicesWrite-only Device Class configuration

Agent provisioning and RAUC signing solve different problems. The Add-device command cannot sign firmware. A RAUC certificate cannot enrol a device into your organisation.

The trust path #

text
product owner creates CA and signing certificate
              |
              +--> public CA baked into every A/B rootfs
              |
              +--> signing key signs each .raucb in the build system
              |
              +--> public CA pasted into the Device Class keyring

signed .raucb
    -> Dataplicity verifies signature, compatible, version, size, and SHA-256
    -> agent downloads the selected bundle
    -> RAUC verifies the signature and compatible again on the device
    -> RAUC installs only the inactive slot

The signing private key must never be copied to a device or pasted into Dataplicity.

1. Choose the compatible value #

Set a stable identifier for the hardware and partition contract, for example:

ini
[system]
compatible=acme-controller-cm5-v1

The value must match the bundle manifest exactly. Change it when a hardware or layout revision must not accept the previous product's bundles.

Dataplicity OS uses dataplicity-os-cm5 for its reference build. Replace that value before building a product fork.

2. Create development certificates #

In the Dataplicity OS build tree, create disposable lab material with:

sh
KEEP_CA_KEY=1 ./scripts/gen-lab-keys.sh

The script creates:

text
keys/lab/ca.key.pem          # CA private key; retain securely if leaf certificates will be renewed
keys/lab/ca.cert.pem         # public CA certificate / verification keyring
keys/lab/signing.key.pem     # bundle-signing private key
keys/lab/signing.cert.pem    # bundle-signing certificate

It also copies ca.cert.pem to the reference layer's image-keyring location. The PEM files are gitignored. The generated keys are for lab testing, not a production fleet.

3. Create production certificates #

Use your organisation's PKI or signing service when one exists. The following OpenSSL sequence illustrates the required CA and leaf-certificate roles:

sh
umask 077

openssl genpkey -algorithm RSA -aes-256-cbc \
  -pkeyopt rsa_keygen_bits:4096 \
  -out ca.key.pem

openssl req -x509 -new -sha256 \
  -key ca.key.pem \
  -days 3650 \
  -subj "/O=Acme Devices/OU=Firmware/CN=Acme RAUC Root CA" \
  -out ca.cert.pem

openssl genpkey -algorithm RSA -aes-256-cbc \
  -pkeyopt rsa_keygen_bits:4096 \
  -out signing.key.pem

openssl req -new -sha256 \
  -key signing.key.pem \
  -subj "/O=Acme Devices/OU=Firmware/CN=Acme RAUC Release Signing" \
  -out signing.csr.pem

openssl x509 -req -sha256 \
  -in signing.csr.pem \
  -CA ca.cert.pem \
  -CAkey ca.key.pem \
  -CAcreateserial \
  -days 825 \
  -out signing.cert.pem

Protect the CA key separately from routine image builds. Keep the release signing key in a secret store or signing system with access limited to the release pipeline. Record expiry and rotation ownership before devices ship.

Never commit private keys. Do not print them in CI logs or upload them as build artefacts.

4. Configure the Yocto build #

For the Dataplicity OS reference layout, point kas/BitBake at:

text
RAUC_KEY_FILE      = path to signing.key.pem
RAUC_CERT_FILE     = path to signing.cert.pem
RAUC_KEYRING_FILE  = path to ca.cert.pem

The public CA must also be installed at the path referenced by the device's RAUC configuration, /etc/rauc/ca.cert.pem in the reference image:

ini
[keyring]
path=/etc/rauc/ca.cert.pem

Build with:

sh
kas build kas.yml

The reference build produces a flashable .wic, a .wic.bmap, and a signed .raucb. See Build and customise Dataplicity OS.

The current CM5 .raucb updates the root filesystem. The initial .wic contains the boot A/B partitions and rootfs A/B layout. Do not assume a rootfs-only bundle also replaces EEPROM or every boot-firmware component.

5. Prove signing locally #

On a non-production device flashed with the matching public CA:

sh
rauc status
dataplicity rauc-ready
rauc install /tmp/acme-controller-1.0.0.raucb
reboot

After reboot:

sh
rauc status
grep rauc.slot /proc/cmdline

Confirm the expected slot booted and the persistent Dataplicity identity, configuration, SSH keys, and application data survived. Complete the failed-boot physical qualification before using managed delivery.

6. Configure signing trust in Dataplicity #

In the Dataplicity app:

  1. open the Device Class;
  2. open OS Images;
  3. configure image management;
  4. choose Manage;
  5. paste ca.cert.pem into the public certificate keyring field;
  6. save the policy.

The field accepts one or more public certificates. It is stored write-only and cannot be read back after saving. Never paste ca.key.pem or signing.key.pem.

Dataplicity requires the keyring before managed image delivery can be enabled. When a .raucb is registered, Dataplicity independently checks:

  • CMS signature against the class keyring;
  • RAUC compatible;
  • RAUC version;
  • actual size and server-computed SHA-256.

A rejected bundle remains unavailable for pinning. This cloud check is in addition to, not instead of, RAUC verification on the device.

7. Upload and stage the firmware #

After the keyring is configured:

  1. upload the signed .raucb under OS Images;
  2. wait for verification and indexing;
  3. use Observe first when you only want image and slot inventory;
  4. choose a canary tag cohort;
  5. create the image pin and staged rollout;
  6. inspect install, boot, validation, mark-good, and rollback outcomes;
  7. expand only after the canary evidence is acceptable.

See:

8. Provision the Dataplicity agent #

Baking /opt/dataplicity/venv into the image installs the software. It does not assign the device to an organisation.

For each physical unit:

  1. boot with /var/lib/dataplicity mounted;
  2. in the Dataplicity app, select Add device and obtain the organisation-scoped command;
  3. run it during bench commissioning or a protected factory first-boot stage;
  4. confirm a unique device identity was written to persistent state;
  5. remove temporary provisioning material;
  6. verify that the same device reconnects after an A/B slot switch.

Do not bake the organisation provisioning command into a public Yocto tree. Do not clone /var/lib/dataplicity after provisioning. See Installing for mass production.

Rotation and recovery #

Plan certificate rotation before the original signing certificate or CA expires. Devices must trust the certificate chain that will sign the next bundle, and the Device Class keyring must verify it too. Test any keyring transition on a canary cohort before removing old trust.

If the CA private key is lost, you cannot mint another signing certificate under that CA. Recovery then requires delivering a new trusted keyring through a path the device already trusts or reflashing the product. Protect CA backup and recovery procedures accordingly.