Skip to content

TrailMQ v3.1.0 — Public Distribution

Latest

Choose a tag to compare

@RainerGewalt RainerGewalt released this 10 Aug 19:08
· 3 commits to master since this release

TrailMQ 3.1.0

Public distribution for the TrailMQ 3.1.0 runtime.

This release tags the public distribution and deployment configuration — the Compose recipe, the CLI, the environment template and the documentation that start the product. It is not a second runtime build. The backend and frontend images it deploys are the 3.1.0 images that were already published; nothing was rebuilt for this tag.

Start

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

Verified public journey

Validated from a fresh clone of this exact commit, with no inherited runtime state — no database, no certificates and no secrets before the run:

  • fresh-clone startup through ./trailmq quickstart
  • MQTT TLS authentication
  • authorized publish → exact subscriber payload compared byte-for-byte, not a PUBACK
  • denied publish on restricted/ops/config → no subscriber delivery
  • denial visible with identity, role, action and topic context (reason=acl_role_not_in_topic_scope)
  • REST authentication issues a token
  • system/action audit chain verification

./trailmq verify passed 7/7. A restart was re-verified at 7/7 with the audit chain growing from 13 to 26 entries and still validating, so persistence survives a restart.

Distribution hardening

The public Compose defaults were hardened before this distribution tag was created. Only verified changes are listed:

backend frontend reverse proxy
before non-root, no capabilities, no-new-privileges, writable root non-root, writable root, no no-new-privileges root, 14 capabilities, writable root
after unchanged privileges, read-only root cap_drop: ALL, no-new-privileges, read-only root non-root, cap_drop: ALL, no-new-privileges, read-only root
  • The backend was already non-root and already dropped all capabilities. It gains a read-only root filesystem. Its cap_add: NET_BIND_SERVICE was removed: a cap_add grants nothing to an image that starts as a non-root user, so it described a privilege the service never actually held.
  • The frontend and the reverse proxy had their deployment privileges reduced. The reverse proxy previously ran as root with the default Docker capability set; it now runs unprivileged on container port 8080 using a digest-pinned nginx-unprivileged image.
  • Verified in the running containers, not read off YAML: all three now report an empty effective capability set, NoNewPrivs=1, a read-only root filesystem and a non-root user. Writes to / are refused while /tmp and the backend's data mount still work.

The host port mapping did not change. Every documented URL is what it was.

This is a deployment-configuration hardening. It did not change the runtime image identity — the digests below are unchanged.

Runtime images

Already published, and referenced unchanged by this distribution release:

backend   rainergewalt/trailmq-backend:3.1.0
          sha256:f6b1df74c22463e3c159ef590bac82915c59d67485d902967edb6bd7d8e019a9

frontend  rainergewalt/trailmq-frontend:3.1.0
          sha256:1886412c066b8175c5fe2e3e54d5ac277a432d05ac9df3a638cfe6c7a99b0246

Identical on Docker Hub and GHCR. They carry an SBOM and mode=max provenance and are signed keyless with cosign. You can repeat that verification yourself:

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:3.1.0

No runtime image was rebuilt or republished for this distribution release, and the runtime release tag in the source project is unchanged.

Validation status

The automated quality gate refused the runtime commit. It was published on a recorded release-owner decision rather than on a passing gate, and the raw gate result was preserved rather than reclassified.

The refusal was not a product finding: it was caused by end-to-end scenarios that never executed, because a localhost-only test-administration endpoint failed under load, and by a backend test that races its own counters. The audit-immutability contract executed and passed in that same validation run, and no required audit evidence was lost. The remaining load-test findings are capacity limits and test-harness accounting, documented per scenario in the source project and scheduled for 3.1.1.

Stating this is the same standard this product asks of its own evidence: a gate that refused should be reported as having refused, not quietly reclassified as a pass.

Distribution identity

Runtime version            3.1.0
Public distribution tag    v3.1.0
Public distribution SHA    9163f360c4bcf8a9b57423f5ab3df13919f4695f

This git tag is annotated and not cryptographically signed. The cosign signatures above cover the runtime images, which is a separate artifact from this tag.