Releases: intelligentwolf/WolfStack
Release list
WolfStack v25.23.1
v25.23.1: the company is now IntelligentWolf Ltd, and the GitHub org is intelligentwolf
Wolf Software Systems Ltd has been renamed to IntelligentWolf Ltd, and the
GitHub organisation from wolfsoftwaresystemsltd to intelligentwolf. Install
commands, docker pulls, release-download URLs and sponsor links all point at
the new org; copyright headers, the LICENCE, the CLA and the trademark
notices all carry the new company name. No functional change.
Co-Authored-By: CodeWolf paul@wolf.uk.com
Co-Authored-By: Wolf Software Systems Ltd paul@wolf.uk.com
Claude-Session: https://claude.ai/code/session_01PPv1TMWDnyFNXUXzAVUSb1
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/intelligentwolf/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 intelligentwolf/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.
WolfStack v25.23.0
v25.23.0: zfs pool shares publish child datasets, and a wide-links option for symlinked pool layouts
Recursive bind mounts across the whole share pipeline (child datasets
were served as empty folders), reload genuinely re-mounts, a new SMB
follow-symlinks/wide-links share option with the required global
unix-extensions handling, and ZFS auto-detection in the share wizard.
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.
WolfStack v25.22.0
v25.22.0: every node gets its own signing key — a leaked cluster secret can no longer act as a node once signatures are required
Per-node Ed25519 identity on every inter-node request, pinned by peers
from the node's own reports. Default mode changes nothing; the opt-in
"Require node signatures" makes a bare cluster secret worthless and
enforces a per-node manager policy for forwarded operator actions.
Co-Authored-By: CodeWolf paul@wolf.uk.com
Co-Authored-By: Wolf Software Systems Ltd paul@wolf.uk.com
Claude-Session: https://claude.ai/code/session_01Y3XvLuAXChuooji253ujcy
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.
WolfStack v25.21.3
v25.21.3: a bare cluster secret can no longer run commands, open consoles or touch files through any endpoint
25.9.3 fixed GHSA-r3mw-2wmq-j6jg on five endpoints by name; the same
capability was still reachable through /api/wolfflow/exec and ~40 other
exec/console/file handlers with nothing but a valid cluster secret. Every
shell-class handler now takes the operator gate, legitimate forwarding
callers stamp attribution, and the AI action filter catches curl x | bash.
Reported by @baeseungwon1010.
Co-Authored-By: CodeWolf paul@wolf.uk.com
Co-Authored-By: Wolf Software Systems Ltd paul@wolf.uk.com
Claude-Session: https://claude.ai/code/session_01Y3XvLuAXChuooji253ujcy
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.
WolfStack v25.21.2
v25.21.2: DNS-01 certificates can finally renew — the credentials file no longer vanishes after issuance
certbot records the absolute path of the --dns--credentials file
in /etc/letsencrypt/renewal/.conf and re-reads it on every renew.
WolfStack handed it a throwaway file under /run/wolfstack/dns-creds/ that
was unlinked the moment issuance returned, so every provider-issued cert
failed to renew with "File not found" — from our daily task and from the
distro's certbot.timer alike.
Real issuances now write a persistent 0600 /etc/wolfstack/dns-creds/.ini
(refreshed on credential rotation, removed with the provider); dry-runs
keep the ephemeral file. The daily renewal task first repairs any renewal
config still pointing at a dead /run/ path, so existing lineages heal
about a minute after upgrading without being reissued.
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.
WolfStack v25.21.1
v25.21.1: a failed certbot.service now tells you why when you click Repair
The one-click repair for a failed certbot.service ran certbot renew through
run_shell() and unwrapped the result with unwrap_or_default(). run_shell()
returns Err on a non-zero exit, so the renew output was discarded in exactly
the case the operator clicked Repair to read — a failing renewal left the
result panel blank apart from the systemctl restart log. It also located
certbot with a bare which, which runs under systemd's PATH and misses snap
and pipx installs, so a snap host reported "certbot binary not on PATH" and
skipped the renew with certbot sitting at /snap/bin/certbot.
certbot is now resolved through certbot::certbot_path(), the same probe chain
the rest of the certbot module uses, and a genuinely missing binary reports
missing_certbot_error() with its trace and install command. stdout and stderr
are both kept on success and failure alike, along with the exit status and a
pointer to /var/log/letsencrypt/letsencrypt.log. The diagnostic run no longer
passes --quiet: the distro's own certbot.service already runs certbot -q renew, and that silence is what sends operators to this button.
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.
WolfStack v25.21.0
v25.21.0: LXC containers get a Certificates page — certbot for the web server inside the container
A container running its own web server had no certificate lifecycle at all:
the host Cert Manager runs certbot on the node for WolfProxy, and its certs
are invisible inside an LXC container, so anyone serving sites from Apache2
or WolfServe in a container was dropping to the console to run certbot by
hand — and nothing ever attached the result to the vhosts.
Every LXC row now has a Certificates button. The page detects the web
server inside the container (WolfServe, Apache2, or httpd — systemctl with
a pidof/pgrep fallback for containers without systemd) and shows "Nothing
is installed" when there is none. With one present, it reads the shared
Apache-layout vhost configs and lists every site with its domains, enabled
state, and current HTTPS status, then manages the full lifecycle inside the
container over the configurator's ExecTarget transport (lxc-attach / pct
exec / docker exec):
- one-click certbot install via the container's own package manager
(apt/dnf/yum/pacman/apk), verified after the install rather than trusted - issue via webroot HTTP-01 served from the site's DocumentRoot through the
running web server — no downtime, domains and email prefilled from the
vhost and the host Cert Manager settings; wildcards are refused with a
pointer to the host page's DNS-01 flow, since webroot cannot validate them - the new cert is attached to the site automatically, and any cert can be
attached to any site: existing SSL paths are rewritten in place, an
HTTP-only vhost gets its :80 block cloned into a :443 block with SSLEngine
on. Every attach runs configtest (wolfserve --test fallback) and ROLLS THE
FILE BACK on failure, so a bad attach can never leave a config the web
server refuses to load; a missing SSL module produces an a2enmod ssl /
mod_ssl hint instead of a bare parse error - renew and delete per cert, with a warning when a site still references the
cert being deleted; issued certs carry a --deploy-hook that reloads
Apache/WolfServe so certbot's own timer inside the container completes
unattended renewals end to end
Six new /api/containers/{runtime}/{id}/certs/* endpoints (mutating ones
behind the operator gate, certbot runs on the blocking pool). The vhost
parsing, SSL-path rewrite, and :443-clone logic is unit-tested; the live
container flow has not yet been exercised against a real Let's Encrypt
issuance.
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.
WolfStack v25.20.1
v25.20.1: an LXC backup can no longer leave the container frozen
The nightly backup froze legolas on wolfstack-3 for 70+ minutes. backup_lxc
ran lxc-freeze around the snapshot instant; on cgroup2 the freezer sits in
FREEZING forever when a task cannot be frozen — the classic case is a
container running its own FUSE mount, whose client tasks cannot freeze until
the FUSE daemon answers while the daemon is being frozen with them.
lxc-freeze waits for FROZEN with no timeout, so the backup thread blocked at
.output(), the unfreeze on the next line never ran, and a service restart
left both the paused container and the hung lxc-freeze client behind
(systemd's KillMode keeps unit children alive across a restart).
Snapshot backups no longer freeze at all. A ZFS/btrfs snapshot is atomic and
point-in-time without the freeze — taken hot it is crash-consistent, the
same guarantee the hot-tar fallback has always accepted — and the container
is never paused, not even for the snapshot instant. On storage without
snapshot support the freeze was already released before tar started, so it
bought nothing there; the Proxmox path (vzdump) never used this code.
A recovery sweep now runs at boot (immediately — a frozen container is a
live outage) and hourly: any hung lxc-freeze client found in /proc is
killed, and a container left FROZEN/FREEZING is thawed with a bounded,
verified, retried lxc-unfreeze. That self-heals nodes still carrying frozen
state from a pre-25.20.1 binary across the upgrade.
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.
WolfStack v25.20.0
v25.20.0: backup retention actually prunes a PBS datastore, and a failing backup finally tells you
Retention did nothing at all on PBS. delete_backup_file() carried
StorageType::Pbs => {} on the assumption that PBS reclaims space via its own
prune + garbage-collect schedule. That holds for a self-managed PBS where the
operator configured a prune job, and is simply false for a hosted datastore
that has none: retention: 7 trimmed only WolfStack's own index, so the UI
showed 7 while the datastore kept every snapshot ever written. A four-node
fleet on retention 7 was found holding 15-19 snapshots per group across 18
days, having filled a 2 TB datastore to 100% and failed every backup for the
previous 8 days. Retention now prunes the groups a schedule owns.
Retention was also counted per SCHEDULE rather than per target, so a schedule
covering 11 containers with retention 7 kept 7 records in total and could not
hold even one complete night — the surviving set was 3 containers from one
night plus 4 from the night before, the rest already deleted. It is now per
target: keep 7 means seven backups of each thing.
A failing backup was invisible. last_run is stamped even when every target in
the run fails, so backup_stale stayed silent for 8 days while the fleet had no
backups at all. The new backup_failed finding reads the per-target status and
error that backups.json was already recording, and fires Critical when a whole
run failed, High when it partly failed.
Every node wrote its config backup as the literal config-wolfstack-.tar.gz,
which maps to the backup-id "wolfstack" — so every node in a fleet shared the
single PBS group host/wolfstack (67 snapshots from four machines). That makes a
restore ambiguous and per-group retention destructive. The archive path now
scopes the id by hostname, as the file-level path already did. Where two
schedules still share a group, the group keeps the largest retention any of
them asks for rather than letting the stricter one delete the looser one's
snapshots.
Store and restore had drifted on how they derive a PBS backup type: Docker
archives were written as "ct" and looked up as "host", so a Docker PBS backup
could not be restored. Both now use one helper.
Note that PBS prune unlinks snapshot indexes; space returns only when garbage
collection runs, which on a hosted datastore is often the provider's job and
not permitted to a backup token.
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.
WolfStack v25.19.1
v25.19.1: an LXC terminal opens on the node that owns the container
Opening an LXC console in the pop-out terminal could attach to the wrong
host: after a session on a remote node, the next container you opened on the
serving node was proxied to that remote node instead, so pct enter ran
against a container it does not own ("Configuration file
'nodes//lxc/.conf' does not exist"). The pop-out was mounting
with no node list at all, so it could not tell which node was its own. Its
New Tab picker, which listed nothing for the same reason, works again, and a
Proxmox LXC console now names the node that owns the container instead of
leaving you with pct's raw path error.
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.