# Release signing and SBOM

URL: /security/release-signing

Every Foxborne release is a signed bundle with an SPDX bill of materials. Foxborne checks the signature against the Foxborne release key before anything installs, and nothing installs if it does not match.



An update reaches a Foxborne deployment only as a file your administrator brings in. Each release is a signed `.fxb` bundle with a software bill of materials, and Foxborne checks both before it installs anything. Nothing is downloaded, so the same check works in an air-gapped enclave.

## What a release carries [#what-a-release-carries]

| Part               | Example                                    | What Foxborne does with it               |
| ------------------ | ------------------------------------------ | ---------------------------------------- |
| Bundle             | `foxborne-1.4.3.fxb`, 412 MB               | Reads it                                 |
| Signature          | Foxborne release key `7C1E 4B90 3A2F 9A42` | Checks it before anything installs       |
| Bill of materials  | SPDX 2.3, 418 components                   | Checks it and stores it with the release |
| Database migration | Two additive migrations, no data rewritten | Checks it before anything installs       |

The examples come from the console's sample bundle. Licenses are checked offline too, with no call home.

## The bill of materials [#the-bill-of-materials]

Each release carries an SPDX 2.3 bill of materials. The **Updates** panel reports the one for the running release, such as **SPDX 2.3, 412 components, stored with the release**.

Before an install, the check line reports the new release's component count and whether any component has a known critical vulnerability. In the example, the sample bundle lists 418 components and **no known critical vulnerabilities**.

## Before you start [#before-you-start]

* You need the **Admin** role. Only admins hold **Manage hosting, keys and access**.
* The `.fxb` bundle is inside your network, brought in under your own transfer process. For an air-gapped install, see [Air-gapped installation and updates](/deploy/air-gapped).

## Check a bundle and install it [#check-a-bundle-and-install-it]

<Steps>
  <Step title="Record the release key">
    Go to **Hosting**. The **Updates** panel shows what runs now and who signed it.

    <Fields>
      <Field name="Installed">
        1.4.2, 12 Sep 2026
      </Field>

      <Field name="Signed by">
        Foxborne release key 7C1E 4B90 3A2F 9A42
      </Field>

      <Field name="Bill of materials">
        SPDX 2.3, 412 components, stored with the release
      </Field>
    </Fields>

    Record the key's fingerprint, `7C1E 4B90 3A2F 9A42`, in your change record.
  </Step>

  <Step title="Open Install an update">
    Select **Install an update** in the page header, or **Install** on the **Updates** panel.

    The **Install an update** dialog notes &#x2A;*Updates are signed bundles. Nothing is downloaded; your administrator brings the file in.** It shows the bundle as a file card with its name.
  </Step>

  <Step title="Read the four checks">
    Foxborne runs four checks in turn, and the install button stays disabled until they finish.

    ```text title="Install an update" caption="Example checks for the sample bundle foxborne-1.4.3.fxb"
    Read bundle. foxborne-1.4.3.fxb, 412 MB.
    Check signature. Signed by the Foxborne release key 7C1E 4B90 3A2F 9A42.
    Check the bill of materials. SPDX 2.3, 418 components, no known critical vulnerabilities.
    Check the database migration. Two additive migrations, no data rewritten.
    ```

    Compare the fingerprint on the signature line with the one you recorded.
  </Step>

  <Step title="Install">
    The dialog notes &#x2A;*Downtime: none. Workers restart one at a time.** Select the install button, which names the version, such as **Install 1.4.3**.

    The console confirms when the update will run, such as **1.4.3 will install in the maintenance window tonight at 02:00 UTC**. The audit log records **Scheduled update** on `1.4.3`, with the detail **Signature and SBOM verified**.
  </Step>
</Steps>

## Check the result [#check-the-result]

* The audit log records **Installed update** once the release is in, such as on `1.4.2` with **Signature verified, SBOM stored**.
* The **Updates** panel shows the new version under **Installed** and adds it to the history, with who installed it and when.
* **Version** in the **Hosting** summary carries the chip **Signature verified**, and the status bar names the running version.

In the example dataset, the **Updates** history reads:

| Version | Change                                          | Installed   |
| ------- | ----------------------------------------------- | ----------- |
| 1.4.2   | Parser fixes for PX4 v1.16 rover topics         | 12 Sep 2026 |
| 1.4.1   | Receive log latency estimates from SYSTEM\_TIME | 1 Sep 2026  |
| 1.4.0   | Manual clock alignment from matching events     | 15 Aug 2026 |

## Troubleshoot [#troubleshoot]

**The install button stays disabled.** The checks have not finished. The button turns on once the fourth check completes.

**The signature does not match.** Nothing installs. Set the bundle aside and bring in a fresh copy through your transfer process.

**The fingerprint differs from your record.** Stop before installing, and raise it through your own security process.

## The collector package [#the-collector-package]

The collector's Debian package is signed with the same Foxborne release key. Vehicles install it from your internal package mirror, as [Install and enroll the collector](/collect/collector/install) shows.

## Next [#next]

* [Install an update](/deploy/upgrades) walks through the update itself.
* [Air-gapped installation and updates](/deploy/air-gapped) covers carrying bundles into an enclave.
* [Encryption and keys](/security/keys) covers the other key a deployment depends on.
