Skip to main content

Changelog

Release history for Belay. Every version below has published installers on GitHub Releases; the install one-liner and the download buttons on this site always resolve to the newest one, so you never have to pick a version by hand.

When this matters

Two questions bring people here. What am I running?belay --version answers that, and this page says what that version contains. Has the thing that bit me been fixed? — a limitation listed under a release is still true unless a later release says otherwise.

Version numbers are not marketing here. The bump to 0.2.0 means a new command surface and a change to what every audit row records, not a redesign.

v0.2.0 — 2026-09-08

First release since v0.1.14, 123 commits. The version moved to 0.2.0 rather than 0.1.15 because this window adds a new command surface (agent-surface sweeps), a new user surface (the enterprise console), and changes what every audit row contains.

Agent-surface sweeps

Belay can now enumerate and re-check what an agent can reach, on demand and on a schedule, and tell you what changed between runs. See Agent-Surface Sweeps for the feature and CLI Commands for the flags.

  • belay sweep-now for an on-demand sweep; belay sweep-history and belay sweep-compare to see drift over time.
  • Findings are classified across sweeps, so a new finding is distinguishable from one that was already there.
  • Each sweep records what enumeration could not reach, so incomplete coverage is visible instead of silently reading as "nothing found."
  • Evidence packs carry sweep history.

Standards mappings recorded in the audit log

Every rule in the catalog carries OWASP ASI/LLM Top 10 and MITRE ATLAS mappings, but the audit log never recorded them — they existed only in the rule catalog, and anything downstream had to join a row back against rules/catalog.yaml to learn what it mapped to.

Both are now written at write time, on the hook path and the MCP proxy, so every row is self-describing and the mapping stays pinned to the ruleset that actually fired rather than to today's catalog. The approval card shows them as a compact Standards line. See Standards Alignment.

Detection

  • Script-file resolution follows source directives, nested script execution, and inline bodies inside resolved scripts, so a command that hides its real work one file away is still scanned.
  • Unicode Tags-block folding, so ASCII smuggled through that block is visible to every rule rather than only to a dedicated one.
  • MCP tool-poisoning rules now run over tools/list metadata, not just calls.
  • Runtime-computed writes to the rules source are detected, closing a gap where the target path was assembled at runtime rather than written literally.

Fewer false positives

A sustained pass over self-tamper, which was the noisiest rule family:

  • A redirection counts as a write only when its own target is protected.
  • A duplicated file descriptor is not a file write.
  • A quoted angle bracket is not a redirect.
  • Prose that merely mentions a protected file is not a write to it.
  • Ordinary reads of Belay's own files are no longer denied.

Self-disabling subcommands are denied more thoroughly in the same pass, anchored on every boundary rather than a single prefix.

note

Write verbs deliberately keep the looser co-occurrence test. Tying a verb to its operand needs a real parser, so that family stays broad on purpose rather than quietly wrong.

Enterprise console and server hardening

  • Admin console: sign-in view and console shell, embedded in and served by the server binary.
  • Fail-closed CSRF guard for cookie-authenticated writes, covering GET, with IPv6 and wildcard host matching fixed.
  • Host allowlist across the API surface, warning on non-loopback binds when no BELAY_CONSOLE_HOSTS is configured.
  • Session cookie issued alongside the login token and accepted in AuthClaims.

Desktop app

Twelve fixes, most of one kind: controls that failed silently. Egress allowlist removal, batch approve and deny, host quarantine, skill and ban controls, mute, tray and findings controls all reported success on a failed daemon call. The sidebar claimed "Protected" when it had no idea, the tray popover guessed at protection state instead of reading it, and the Overview and fleet views loaded forever instead of saying why they had failed.

Adds a deny-mute button with a mute notice, and a revoke panel on Overview.

Reliability

  • install-service can upgrade a running install. It staged with fs::copy, which fails with ETXTBSY against a live executable — the normal case, since it replaces the binary the resident daemon is executing — and the error told you to re-run under sudo, which could never help. It now stages to a sibling and renames, which is atomic and cannot leave a truncated binary at the path your protection depends on.
  • The post-install hook self-test no longer fork-bombs under cargo test. It resolved the binary via current_exe(), which under a test run is the libtest harness; shelling out to it re-ran the suite, which self-tested again. Roughly 2000 live processes were spawning at ~220/sec before it was caught.
  • belay protect verifies the installed hook can actually run, catching the failure where a hook installs perfectly and cannot execute — which otherwise looks identical to a quiet day.

AI (optional, BYOK, off by default)

  • Daily call budget for the optional BYOK explainer layer.

Upgrading to v0.2.0

The install one-liner is unchanged — see Installation. To upgrade an existing service install in place:

sudo belay install-service --enable

v0.2.0 is the release where that works against a running daemon.

Known limitations
  • aarch64 Linux is not built. x86_64 Linux (musl) and both macOS architectures are. Build from source in the meantime.
  • The Windows installer is unsigned. SmartScreen warns on it until a code-signing certificate is in place; the companion .sha256 confirms the download is intact. macOS .dmg builds are unnotarized for the same reason.
  • R2 mirrors latest only, and only for the platforms uploaded to it. macOS and aarch64 Linux install from GitHub Releases through the automatic fallback in install.sh.

Earlier releases

These tags predate written release notes. What follows is what each one actually published — the artifact list, not a reconstruction of what changed inside it.

v0.1.14 — 2026-07-22

First release to ship prebuilt desktop installers for all three platforms: .dmg for both macOS architectures, .deb and .AppImage for Linux, and the Windows .exe, alongside the CLI binaries.

v0.1.13 — 2026-07-22

CLI binaries for Linux x86_64 (musl) and both macOS architectures, plus the Windows installer. No macOS or Linux desktop packages yet.

v0.1.0 — 2026-07-12

First public release. CLI binaries only — Linux x86_64 (musl) and both macOS architectures.

  • Installation — the one-command install and the direct installer downloads.
  • Platform Support — what works on which OS, including what is still in-tree only.
  • CLI Commands — every command and flag, including the sweep commands added in v0.2.0.