Skip to content

TrailMQ v3.1.1 — Public Distribution

Latest

Choose a tag to compare

@RainerGewalt RainerGewalt released this 16 Sep 17:54
faa8d8f

The public evaluation distribution for TrailMQ 3.1.1.

Windows evaluation build — unsigned

This Windows build is provided for local, non-production evaluation. It does
not carry an Authenticode signature, so Windows may display an Unknown
Publisher
or SmartScreen warning. That warning does not by itself mean the
file was modified; it means Windows cannot verify a trusted publisher
identity for this binary.

Verify the downloaded artifact against SHA256SUMS-windows:

certutil -hashfile TrailMQ-Setup-3.1.1.exe SHA256

That comparison establishes that the file matches the artifact published with
this release. It does not establish publisher identity — those are two
different claims, and only a signed Windows distribution answers the second
one.

Asset
TrailMQ-Setup-3.1.1.exe Installer. Needs Docker Desktop; no Git, no WSL.
TrailMQ-3.1.1-windows-x64.zip Portable copy of the same launcher.
SHA256SUMS-windows Checksums for both.

This record exists because the README points at it: it says the release record holds the exact evidence, image digests and validation detail. Everything below was read off the published artifacts and off a run against them, not copied from a build log.

What this release is composed of

From release.yaml, the single place a version is decided:

Component Version
Release 3.1.1
runtime.backend 3.1.1
runtime.frontend 3.1.1
distribution.evaluation_bundle 3.1.1
distribution.launcher 3.1.1
distribution.windows_installer 3.1.1
distribution.windows_trust_mode unsigned_evaluation

The Windows artifacts below were added to this release on 2026-09-19, after the workflow that builds and verifies them was fixed. windows_trust_mode is a separate dimension from the version: distributing an artifact and vouching for who published it are different decisions, and null is reserved for "not distributed" so it can never describe a file you can already download.

Image digests

Image Digest
rainergewalt/trailmq-backend:3.1.1 sha256:56b3ceb39a4fb9097614448091f6c169d74f0306bdc0e47f8ae5ae62af818e4b
rainergewalt/trailmq-frontend:3.1.1 sha256:3ca27c6443b9be49b077a627253f9e5da3f8d394566716d10db49d1e6021436a
ghcr.io/rainergewalt/trailmq-backend:3.1.1 sha256:56b3ceb39a4fb9097614448091f6c169d74f0306bdc0e47f8ae5ae62af818e4b
ghcr.io/rainergewalt/trailmq-frontend:3.1.1 sha256:3ca27c6443b9be49b077a627253f9e5da3f8d394566716d10db49d1e6021436a

Docker Hub and GHCR resolve to the same digest for each image, so the two registries are serving the same bytes rather than two independent builds.

Each index carries an in-index attestation manifest — the unknown/unknown platform entry that buildx uses for the SBOM and mode=max provenance. The published index is linux/amd64 only; an Apple Silicon evaluator runs under emulation.

Signature verification

Verified against the published digests with cosign v3.1.3, using the command the README documents, unchanged:

digest="sha256:$(docker buildx imagetools inspect --raw \
  rainergewalt/trailmq-backend:3.1.1 | sha256sum | cut -d' ' -f1)"

cosign verify \
  --certificate-identity-regexp '^https://github.com/RainerGewalt/MQTrail/\.github/workflows/release\.yml@refs/(tags|heads)/.+$' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  "rainergewalt/trailmq-backend@${digest}"

Both images verified, exit 0:

The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The code-signing certificate was verified using trusted certificate authority certificates

The certificate identity is established by construction: cosign exits 0 only if the certificate SAN matches the regexp above, which pins the signature to the release workflow in the source project. The signature is a Sigstore bundle reachable through the OCI 1.1 referrers API — there is no :sha256-….sig tag, and not finding one says nothing about whether the image is signed. Verifying needs cosign 3.x.

Product verification against these images

./trailmq quickstart and ./trailmq verify from a clean checkout, pulling the published images rather than building locally:

[PASS] Runtime ready
[PASS] MQTT TLS listener accepts authenticated clients
[PASS] Authorized publish reached the subscriber   public/demo/temperature
[PASS] Unauthorized publish was blocked            restricted/ops/config
[PASS] Denial recorded with user, role, action and topic
       DENY user="testuser" roles=[publisher] action=publish
       topic="restricted/ops/config" reason=acl_role_not_in_topic_scope
[PASS] REST API authentication issues a token
[PASS] System/action audit chain intact          2045 entries hash-checked

Backend    3.1.1
Recipe     secure-mqtt-core

7/7 checks passed

The third line is the one worth reading closely: the payload is observed arriving at a subscriber, not merely acknowledged by the broker.

The scenario pack was run against the same stack. unauthorized-machine-command passed both steps: a publish to restricted/line07/control/setpoint by line07-hmi / testuser was refused at the broker, and the refusal was recorded with the same canonical reason. That is what compatibleWith: 3.1.1 in the scenario now declares.

What this record does not establish

Stating the limits is the same standard this product asks of its own evidence.

  • This is a verification of published artifacts, performed from outside. The source project's release pipeline runs its own gate, tests and live allow/deny checks; that run is not visible from this repository and none of its results are reproduced here. If you want the pipeline's own verdict, it is not in this record.
  • The signature proves custody of the build identity, not the quality of what was built. It establishes that the release workflow in the source project signed exactly these digests.
  • The hash-linked audit chain is not externally anchored and not digitally signed. It demonstrates internal consistency, not third-party custody, and it does not cover MQTT message evidence — including publish and subscribe refusals, which the product labels Outside validated scope. See Trust and evidence scope.
  • Evaluation only. The images are licensed for local, non-production technical evaluation. The licence states the intended purpose and excludes safety-related, life-safety and emergency-control use outright.

Distribution changes in this release

The public entry point now leads with one real access decision — principal, role, action, topic, outcome and reason — before asking anyone to install anything, and the licence states an intended purpose rather than only a list of restrictions. Full changes: #16, #17.

Reproduce it

git clone https://github.com/RainerGewalt/TrailMQ.git
cd TrailMQ
./trailmq quickstart
./trailmq verify