Skip to content

WolfStack v25.9.3

Choose a tag to compare

@github-actions github-actions released this 01 Aug 09:04
· 397 commits to master since this release

v25.9.3: SECURITY hardening — a cluster secret alone no longer opens a shell, and the default-secret warning can no longer be dismissed

Completes recommendations 2 and 3 of the 2026-08-01 report by
Dostxodjayev Abdullox (@squeeze440). Recommendation 1 shipped in v25.9.2.

REC 3 — decouple command execution from the cluster-secret credential.
'A peer node legitimately proxying dashboard/API calls does not need
blanket authority to run arbitrary shell commands inside every
container.' New require_operator_auth() gates every endpoint that runs
caller-supplied commands or opens an interactive PTY:

  • POST /api/containers/{runtime}/{id}/exec (the reported sink)
  • POST /api/containers/{runtime}/{id}/updates/apply
  • /ws/console/* and /ws/remote-console/* (interactive root shell)
  • /api/vr-terminal/* (real PTY)

It accepts a genuine operator (session or API key), or a peer forwarding
an operator action — cluster secret PLUS X-WolfStack-Proxied and
X-WolfStack-Actor. It refuses the built-in default secret outright, even
from a recorded peer and even with WOLFSTACK_ACCEPT_DEFAULT_SECRET=1: the
published constant never reaches a shell, which is defence in depth on
top of the v25.9.2 peer gate. It also refuses a bare cluster secret with
no attribution — node-to-node state sync has no business opening a shell.

Attribution cannot be chained. node_proxy and remote_console_bridge stamp
the actor only when their OWN caller was a real operator, never when it
was another peer, so a secret-holder cannot bounce through a node's proxy
to manufacture operator identity. The receiving end independently
rejects an actor of 'cluster-node' as well.

Scope boundary, stated deliberately: read-only file listings that shell
out with an escaped path (files_lxc_browse, files_docker_browse) were NOT
moved onto this gate. They are file operations, not command execution;
gating them is scope creep with real breakage risk for cluster file
browsing.

REC 2 — a real rotation prompt instead of a soft warning. The credential
banner could be dismissed per session and only linked to Settings, which
is how a node runs for months on the published constant. The
cluster-secret-default finding is now non-dismissible and carries a
'Rotate now' button that runs the existing coordinated cluster-wide
rotation. Note the report's literal suggestion — retroactively auto-
generating a secret for existing installs — is unsafe as stated: an
un-migrated install is by definition multi-node, and rotating behind the
operator's back severs every peer. The forced prompt plus one-click
coordinated rotation achieves the intent without that.

remote_console_bridge's parameters are grouped into RemoteConsoleTarget
rather than growing to eight positional arguments.

Four new tests on the attribution rule. 1709 pass; clippy at baseline.

Co-Authored-By: CodeWolf paul@wolf.uk.com
Co-Authored-By: Wolf Software Systems Ltd paul@wolf.uk.com


Verifying this release

Each binary is signed via cosign keyless OIDC (no key distribution — signing identity is the GitHub Actions workflow itself, anchored to the Sigstore Fulcio CA and the Rekor transparency log) and ships with a SLSA build provenance attestation.

Verify the cosign signature:

cosign verify-blob \
  --bundle wolfstack-x86_64.cosign.bundle \
  --certificate-identity-regexp 'https://github.com/wolfsoftwaresystemsltd/WolfStack/\.github/workflows/release\.yml@.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  wolfstack-x86_64

Verify the build provenance:

gh attestation verify wolfstack-x86_64 --repo wolfsoftwaresystemsltd/WolfStack

Verify the SHA-256 checksum:

sha256sum -c SHA256SUMS

Artifacts

  • wolfstack-x86_64 / wolfstack-aarch64 / wolfstack-armv7 — static musl binaries (Linux x86_64, ARM64 / Raspberry Pi 4+, and 32-bit ARM).
  • wolfstack-<arch>.cosign.bundle — cosign signature bundle (cert + signature + Rekor entry).
  • SHA256SUMS — checksums for both binaries.

For per-version history see CHANGELOG.md.