Skip to content

Verifying a kit

What a release kit contains, where it runs, the public key that signs it, and the commands that check, offline, that the kit in your hands is the one built from a tagged release.

Every release of NexusFabric is built from its tag by the release pipeline, not on anyone’s machine. Each kit is started and checked on its own platform before it is published, and every file of the release carries a signature, a build provenance and a software bill of materials, all signed with the key printed on this page.

What a release holds

For a release <version> (the tag without its v):

File What it is
nexus-<version>-linux-amd64.tar.gz the kit for Linux on x86-64
nexus-<version>-linux-arm64.tar.gz the kit for Linux on 64-bit ARM
<kit>.bundle the signature of the kit
<kit>.provenance.bundle the signed build provenance (SLSA v1.0): repository, tag, commit, pipeline run, runner
<kit>.sbom.bundle the signed software bill of materials, SPDX 2.3: the crates resolved for building nexus; it may name a crate the linker dropped and never omits one the binary holds
SHA256SUMS the SHA-256 of every other file

The container image is ghcr.io/iello/nexusfabric:<version>, one image for both platforms. It is in a private registry. The kits and the image are available only to holders of a licence or a contract with the supplier, who gives the access: see Licence.

What a kit contains

Each archive extracts to one directory:

nexus-<version>-linux-<arch>/
├── nexus
└── ui/
├── locales/
├── templates/
└── static/

ui/ stays beside nexus: the server finds its interface there. Moving the binary without it stops the interface from starting. Installing a server says where the directory goes.

The archives run on Linux with glibc 2.36 or later: Debian 12 and later, Ubuntu 24.04 and later, and other distributions of the same age. On an older system, run the container image.

nexus --version prints the version of the release, without a pre-release suffix.

The public key

Every kit, provenance, bill of materials and image is signed with this key. Take it from this page, not from the release: a key shipped beside a kit proves nothing about the kit.

Save it as nexus-release.pub:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5o7DO35sbQHeoBJZj1dMGkD58sP6
VTCSr7LvB0ICHQaYwgn2pRuw9ZetTuzuFO148NKz8BVvpnDRrR6Zdpg/Dw==
-----END PUBLIC KEY-----

Its fingerprint, the SHA-256 of the key in DER form, is

6223808135e9034aeabd445537c7bc28d75e3eb8c16d783b9cfb6414306fd3e8

and you recompute it with

Terminal window
openssl pkey -pubin -in nexus-release.pub -outform DER | sha256sum
Key fingerprint (SHA-256, DER) Signs State
6223808135e9034aeabd445537c7bc28d75e3eb8c16d783b9cfb6414306fd3e8 every release published so far current

Key rotation

The signing key is replaced every two years, and whenever a person who could use it leaves. A new key is added to the table above with the first release it signs; every earlier key stays in the table with the releases it signed, so an old kit still verifies with the key of its time.

If a key is ever suspected compromised, the table marks it compromised from a date. Every version signed with it after that date is released again under a new version number, signed with the new key. A published kit is never re-signed in place.

Verifying a kit, offline

You need cosign (tested with 3.1.4) and nexus-release.pub. Nothing is fetched from the network: there is no transparency log, the key is the trust root.

In the directory with the downloaded files, for the kit <a> (for example nexus-1.12.0-linux-amd64.tar.gz):

Terminal window
sha256sum -c SHA256SUMS --ignore-missing
cosign verify-blob --key nexus-release.pub --bundle <a>.bundle \
--insecure-ignore-tlog=true <a>
cosign verify-blob-attestation --key nexus-release.pub --bundle <a>.provenance.bundle \
--type slsaprovenance1 --insecure-ignore-tlog=true <a>
cosign verify-blob-attestation --key nexus-release.pub --bundle <a>.sbom.bundle \
--type spdxjson --insecure-ignore-tlog=true <a>

Each command exits non-zero when one byte of the kit differs, when the bundle belongs to another file, or when another key is given. --insecure-ignore-tlog=true is the name of the flag that says there is no public log to consult; it does not weaken the check of the signature.

The bill of materials travels inside <a>.sbom.bundle. Once the last command above exits 0, write it out as a file for a vulnerability scanner, with jq:

Terminal window
jq -r .dsseEnvelope.payload <a>.sbom.bundle | base64 -d | jq .predicate > <a>.spdx.json

Verifying the image

With access to the registry:

Terminal window
cosign verify --key nexus-release.pub --insecure-ignore-tlog=true \
ghcr.io/iello/nexusfabric:<version>
cosign verify-attestation --key nexus-release.pub --insecure-ignore-tlog=true \
--type slsaprovenance1 ghcr.io/iello/nexusfabric:<version>

The same two commands verify each platform’s image, given by its digest (ghcr.io/iello/nexusfabric@sha256:…).

Each platform’s image carries its own bill of materials, SPDX 2.3: the image’s Debian packages and the crates resolved for building nexus. List the platform digests, then verify the bill of materials of one and write it out:

Terminal window
docker buildx imagetools inspect ghcr.io/iello/nexusfabric:<version>
cosign verify-attestation --key nexus-release.pub --insecure-ignore-tlog=true \
--type spdxjson ghcr.io/iello/nexusfabric@<platform digest> \
| jq -r .payload | base64 -d | jq .predicate > image.spdx.json