github LanternOps/breeze v0.107.0

latest releases: v0.121.1-hotfix.2, v0.121.1-hotfix.1, v0.121.0...
one month ago

Breeze RMM v0.107.0 — the self-host fork release: BYO-signed agent packages that the server finally accepts, tenant variables, multi-currency billing, and a large correctness and security sweep.

This is the first public release since v0.105.1. v0.106.0 was tagged but never published as a GitHub Release (internal server-image build only), so everything below is the full v0.105.1..v0.107.0 delta for self-hosters.

Summary

  • Self-host binaries work again — v0.105.x shipped unsigned (self-host edition) Windows agent binaries, but the API's trust allowlist only admitted the MSI, so boot-time binary sync aborted and every platform's agent download returned 404 for BINARY_SOURCE=github deployments. Fixed (#3538), guarded against recurrence (#3761), and boot sync now pins to your BREEZE_VERSION instead of /releases/latest (#3808 / #3742).
  • Tenant variables — define a value once (partner-wide or per org), reference it as {{var.*}} in scripts, bind it to sourced script parameters, and have drift pinned into the approval digest. Secret delivery is built but still inert in this release (#3494, #3495, #3533, #3557, #3562, #3588).
  • Multi-currency waves 1–2 — curated 34-currency allowlist, per-org currency_code, currency-aware rounding, and every invoice/quote/contract stamped from the org rather than defaulting to USD (#3794, #3804).
  • Customer self-service billing — public invoice pay link with Stripe checkout, quote accept lands on the invoice, quote decline with reason, and invoice re-send with a composer (#3790, #3805).
  • Package-manager software library — winget and Homebrew install methods in the Software Library, with in-product search (#3587, #3611).
  • Outlook technician persona — work tickets from the Outlook add-in: email context, link/create tickets, time logging, AI drafts (#3596).
  • Breeze Workspace merged into the monorepo as a built-in extension under ee/, off by default (#3455, #3479).
  • Security — two High fixes needing attention: the global patch catalog was writable by any enrolled agent, which could silently suppress patching in other tenants (#3556, #3645), and restricted partner users could mint partner-wide credentials or rotate another admin's API key (#3647). Plus Medium hardening across CIS scan authorization and inbound-email ticket matching (#3643), alert-template visibility (#3642), Go 1.26.6 and dependency CVE bumps. See Security below — all of it is live in v0.105.1.
  • Fixed — SSO login could never complete in the web app (#3702), agent uninstall reported success without removing anything (#3670), EXE installers hung for 30 minutes (#3584), a deadlock on re-enrollment (#3739), /sessions/live pool starvation (#3764), and Prometheus HTTP/heartbeat metrics that were never emitted (#3763).

Added

  • Tenant variables (Settings → Variables) — partner-wide or org-scoped values, encrypted at rest, with variables:read/variables:manage permissions; org > partner precedence (#3494).
  • {{var.*}} in scripts — resolved per device at dispatch (#3495); sourced script parameters bound to tenant variables (#3533).
  • Secret delivery machinery for script variables — server-side sealing and a per-device secretEnv capability flag (#3557), agent-side decode/gate/redact (#3562). Secrets are still refused at script save and at dispatch in this release; activation is a follow-up.
  • Approval digest pins tenant-variable and parameter drift — an approved run_script action-intent now fails closed if a parameter is rebound or a referenced variable changes between approval and release (#3588).
  • Multi-currency foundations — supported_currencies allowlist, organizations.currency_code, shared minor-unit/rounding helpers, JPY/CLP-correct totals (#3794).
  • Document currency correctness — invoices, quotes and contracts stamp currency from the org; cross-org clone/retarget blocked on mismatch; POST /{quotes,invoices,contracts}/:id/currency to change a draft's currency; double-issue and over-payment races closed (#3804).
  • Public invoice pay link — opaque, hashed token; portal-hosted customer page with PDF and deposit-aware Stripe checkout; MSP copy/reset-link actions; "Pay online" CTA in email and PDF (#3805).
  • Quote accept → invoice, quote decline with reason — accept lands on the durable invoice page and optionally auto-emails it (new partner toggle, default on); decline notifies the MSP and offers a revise path (#3805).
  • Invoice re-send with composer — POST /invoices/:id/resend plus a To/CC/subject/note/attach-PDF dialog mirroring the quote composer (#3790). Quote re-send, share-link copy, and "sent to" visibility (#3501).
  • Package-manager software library — winget / Homebrew install methods, import-package one-shot, manager-aware deployment wizard (Latest/Exact, OS-coverage split), agent ensure-present (#3587); winget index freshness signal and partner-erasure FK fixes (#3611).
  • Software deploy UX — explicit customer context in the wizard, partner-wide packages, version editing, MSI arg auto-fill, upload greyed out without S3 (#3575); installer type recorded for URL-created packages (#3571).
  • Per-user winget updates — the agent runs a second best-effort winget upgrade --scope user pass in the interactive user's session so Chrome/Zoom/Slack-style per-user installs finally show up; new device_patches.scope (#3558).
  • Outlook technician persona — email context card, link/create ticket from an email with AI prefill, time widget, technician bind flow; new ticket_email_links and office_addin_user_bindings tables (#3596).
  • Proposal presentation system — partner document themes and fonts, themed PDF renderer, table and callout blocks with edit-in-place, MCP contract (#3526, #3535, #3539, #3545, #3631).
  • Script editor test loop — pin a test device, Save & Test Run, read output in the editor; new tier-1 get_script_execution AI tool (#3582).
  • Analytics page rebuilt on the dashboard design system with honest load failures (#3513).
  • Regional setup-wizard step for language, currency and time zone (#3628).
  • Turkish (tr-TR) localization (#3497).
  • showTrayIcon setting for Breeze Assist in the helper policy tab (#3629).
  • Breeze Workspace as a built-in ee/ extension, enabled with BREEZE_WORKSPACE_ENABLED=true (#3455, #3479); the two dead runtime-bundle delivery paths are retired (#3488).
  • Recidivist-endpoint abuse signal (rmm.recidivist_endpoint) correlating ScreenConnect GUIDs, hostnames and egress IPs against a persistent corpus (#3567).
  • Pending-account booking link — optional PENDING_ACCOUNT_MEETING_URL / PENDING_ACCOUNT_MEETING_LABEL so the payment wall isn't a dead end (#3771).
  • Mobile — Tickets tab (queue, detail, comments, status changes) (#3716); browsable devices list (#3720); self-hosted builds can add their own associated domain for passkey/autofill (#3732); iOS app lock survives process death (#3746).
  • Docs — macOS permissions (PPPC) page, fleet-hygiene page, self-hosted inbound email-to-ticket setup (#3586), switchable Windows signing documented (#3781).

Improved

  • Boot-time binary sync pinned to the server's own version — BINARY_SOURCE=github no longer fetches /releases/latest, so a self-hoster's fleet moves when they upgrade, not when we publish (#3808, closes #3742).
  • Release trust allowlist guarded against pipeline drift — CI fails when the release workflow and the API's asset allowlist disagree (#3761).
  • Agent-version registration fails loudly — POST /agent-versions returns 422 and promote returns 409 for releases missing a signed manifest, instead of thousands of downstream 409s (#3661).
  • Prometheus metrics actually emitted — metricsMiddleware was never mounted; http_requests_total, http_request_duration_seconds and agent_heartbeat_total now populate (#3763).
  • Inbound email-to-ticket toggle enforced server-side — the switch was display-only; it now gates ingestion, with a one-time repair for partners whose flag was falsely false but who rely on inbound mail (#3606); TICKETS_INBOUND_DOMAIN named in the settings hint (#3627).
  • Manual software remediation backed by a durable single-use authorization rather than a forgeable job flag (#3585); remediation authorization rows pruned (#3630).
  • Agent inventory/heartbeat ingest body limit carved out at 5 MB (#3527); quote/catalog/avatar/contract uploads get their own limits (#3511); body-limit rejections now have server-side telemetry (#3660).
  • HP/Lenovo warranty lookups rate-limited at the request boundary (#3576).
  • Offset pagination gets a unique tiebreaker so rows written in one transaction no longer duplicate or vanish across pages (#3664).
  • MCP output — truncated arrays marked in-band (#3580), get_quote blocks paginated (#3568).
  • Maintenance-window inert notify fields retired (#3668); avProducts persisted on security_status (#3669).
  • Partner admins can create and manage org-scoped roles (#3577); fleet (All-orgs) view can create DNS integrations and device groups (#3563).
  • Web polish — static device-group membership editable again (#3626), device-group edit 404 (#3564), notification-channel test verdict in text (#3733), per-org device count on the org card (#3734), locale change no longer drops a live VNC session (#3736), bulk vulnerability actions batched to the server cap (#3709), What's New splash shows on the upgrade that introduces it (#3650), plus two pre-release polish batches (#3633, #3635).
  • Dashboards stop claiming "all clear" with zero devices (#3536, #3651) and show "—" instead of fabricated zeros on a 500 (#3566).
  • Self-host first-boot — .env.example no longer pins a version whose images were never published, TURN_SECRET no longer blocks startup for deployments that don't use TURN (now a file-backed Compose secret that fails closed only when the turn profile is on), placeholder key detection (#3717); .env.example no longer ships a localhost DATABASE_URL_APP that crashed the initial seed (#3728).
  • Viewer AppImage names libfuse2t64 for Debian 13 / Ubuntu 24.04+ (#3512). MSI always writes an install log (#3634).
  • Go toolchain 1.26.6 (#3523); macOS TCC self-heal writes retired in favour of MDM PPPC guidance (#3463); Full Disk Access probed in-process (#3460).

Fixed

  • SSO login could not complete — the web app never consumed the #ssoCode fragment; also fixes the enforce-SSO lockout arrival state and a bootstrap hang on non-JSON /me responses (#3702).
  • Agent uninstall reported success without removing anything (#3670). EXE installers hung until the 30-minute timeout — missing WaitDelay (#3584).
  • Deadlock (40P01) between agent network inventory and re-enrollment — inverted lock ordering (#3739).
  • /sessions/live held a pooled connection across a 10 s agent round-trip, starving the pool (#3764).
  • Breeze Agent inventory version tracked the MSI, not the running agent (#3663). Defender claimed a third-party AV's real-time protection (#3662).
  • AI-generated PowerShell failed with Unicode parse errors — status glyphs normalized (#3574, #3583).
  • Script result arriving after the 60 s wait no longer loses the agent's real output (#3655); script executions page showed no output (#3582); script test-run recovery and stale device pin (#3605).
  • Partner-wide config policies were invisible to org-scoped effective-config resolution (#3665).
  • Patch version read through device_patches.available_version, so per-device version pins and block rules use the tenant's own observation (#3656); winget-prefixed patch ids matched against the bare catalog id (#3565); "Installed (date unknown)" for null installedAt (#3590).
  • z.coerce.boolean() query-param footgun — ?flag=false was read as true at 8 sites / 9 params (#3528). Nullable monitoring watch fields accept null (#3509).
  • Rich text — <table> survives the sanitizer (#3671); stripped markup is reported instead of a silent 200 (#3667).
  • Quote/proposal PDFs — {{client.name}} on drafts and full-bleed cover background (#3489), table row-height measurement and header inline marks (#3555), send_email_reason persisted on the direct send path (#3507), new quotes default to the partner's currency rather than USD (#3572), "/ea" unit translated in tr-TR and es-419 (#3625).
  • Remediation target timeout cancels the queued command (#3570); fleet_remediation_runs roll-up counts fresh at chunk end (#3657).
  • Network payload — one bad VPN entry no longer drops the whole payload (#3573); VPN on/off state and macOS multi-VPN attribution (#3549); SNMP octet strings that aren't safe text are hex-encoded (#3765); gopsutil darwin netstat panic survived (#3514).
  • Inbound email reported as unconfigured on the M365-only path (#3652). Bundle import treats partner-wide name matches as conflicts (#3659).
  • Backup — swallowed vault failures surfaced with real status (#3579); SSRF guard adopted on backup probes (#3645).
  • Mobile — CSRF token echoed so the session can refresh (#3726); device walk uses a page size the server honours (#3757); Systems and Tickets no longer present partial state as complete (#3769, #3719); Expo SDK 57 dependency range (#3747).
  • Workspace rejects local_profile sources that carry a crawl device (#3686).
  • OneDrive Helper polish batch (#3636); billing punch-list a11y, toast anchor and PDF wordmark (#3638); i18n no longer ships API route paths as translatable values (#3666); device picker page cap and silent fleet-load failure (#3610); confirm-gated single-device reboot from the devices list (#3703, #3706).

Security

Every issue below was already present in v0.105.1, the last published release — so self-hosters running that version are affected until they upgrade. Severities are stated as verified against the shipped code, not as originally triaged.

Security — action required

Two High-severity authorization defects. Both cross a tenant boundary; neither is remotely exploitable without either an enrolled agent or an authenticated partner account.

  • Any enrolled agent could overwrite the shared patch catalog that every tenant's approval logic reads (#3556, #3645). The patches table is global with no tenant column, and agent-reported severity, package_id, version and display fields were written straight onto the shared row. Downgrading a critical patch's severity pushes it outside other tenants' auto-approval and ring policies, so it is silently never installed; overwriting package_id corrupts the CVE-enrichment join and mis-attributes vulnerability findings. Reachable by anyone controlling one managed endpoint in any tenant — on hosted deployments with self-service signup, that includes a newly created trial tenant. This is the one issue here that crosses the partner boundary. We could not establish a path to arbitrary package installation: install_patches carries only {id, source, externalId, title} and does not dispatch on package_id, so this is an integrity issue, not RCE.
  • Partner users with restricted org access could mint partner-wide credentials and rotate other admins' API keys (#3647). Six write sites gated on the caller's scope but never on the partner-wide capability. The severe case is partner-wide service principals: a durable machine credential with access to every org under the MSP, including orgs created later — a lasting privilege escalation for a user explicitly limited to selected orgs. Separately, POST /api-keys/:id/rotate resolved the key by id alone and returned the new plaintext, letting a lesser admin take over a more-privileged user's key. Org-boundary crossing within one partner; no cross-partner path.

Both are fixed in 0.107.0 with no workaround; upgrading is the remediation. Advisories will be published once hosted rollout completes, per our disclosure policy.

Security — hardening

  • CIS scan fan-out and ticket-email injection (#3643) — Medium. Every authorization predicate on POST /cis/scan sat inside an if (deviceIds) branch, so omitting deviceIds let an org user with devices:write dispatch a scan across sibling orgs under the same partner; scan results are stamped with the device's own org, so no data returned to the caller. Separately, the inbound-email subject token [T-YYYY-NNNN] was matched on partner + ticket number with no org or sender binding, so anyone emailing the MSP's support address could append a public comment to another org's ticket and reopen it — a write with no read-back, but a convincing phishing channel since the technician sees it as a genuine customer reply. Requires email-to-ticket to be configured.
  • Partner-wide alert-template predicate leaked cross-org templates to partner users with restricted org access (#3642) — Low/Medium. MSP-authored template names, descriptions and conditions only; the auto-created is_built_in rows carry constant text, so no customer data is exposed. alert_templates now carry a one-owner constraint and partner index.
  • Enforcement-arming AI policy tools gated behind Tier 3 approval (#3561); AI software-policy writes audited and remediation gated on policy arming (#3548). Intra-tenant containment and audit, not a boundary break.
  • SSRF guard adopted on backup storage probes (#3645) — an authenticated org admin could point an S3 endpoint at link-local or RFC1918 addresses.
  • AI agent-version pins resolved in a real system context (#3532). http/https allowlist for partner website URLs (#3518).
  • Dependencies — Go 1.26.6 clears six stdlib advisories (#3523); nanoid >= 3.3.18 for CVE-2026-67213 (#3510); deepmerge-ts 8.0.1 for CVE-2026-40345 (#3718); Go x/net, x/text, x/mod, AWS SDK and google.golang.org/api bumps.
  • Security policy — advisory publication and self-hoster disclosure guidance are now enforced in the release process (#3644).
  • Windows signing provider is now switchable (Azure | SSL.com) with a shared verification step that validates signer, timestamp and publisher subject regardless of CA (#3762, #3781, #3807).

Self-Hosting / Upgrade Notes

Upgrade: bump BREEZE_VERSION to 0.107.0 in .env, then docker compose pull api web portal && docker compose up -d. Include portal — the public invoice page and quote accept/decline flows live there and an un-rolled portal will serve the old code while /health reports 0.107.0.

Database — 26 migrations, all idempotent and applied automatically by the API's autoMigrate at boot. None rewrite a hot table. Worth knowing:

  • 2026-08-27-b-org-currency-and-fks.sql backfills organizations.currency_code from the partner (logged with RAISE WARNING counts) and upper-cases existing currency_code values on partners/invoices/quotes/contracts; 2026-08-28-… then drops the 'USD' column default on those three tables. Normal-sized billing tables — seconds, not minutes.
  • 2026-08-14-device-patch-install-scope.sql adds a nullable scope column and a small partial index (WHERE scope = 'user') to device_patches. Plain CREATE INDEX, so it takes a brief share lock on the table; the partial predicate matches zero existing rows, so it is fast even on large fleets.
  • 2026-08-24-inbound-enabled-backfill.sql repairs ticketing.inbound.enabled from a spurious false to true only for partners who have actually received inbound mail — see the behaviour note below.
  • 2026-08-25-alert-templates-one-owner.sql backfills owner columns on alert_templates and adds the XOR constraint. 2026-08-22-drop-extension-org-installs.sql drops the extension_org_installs table (its only readers/writers were the retired delivery paths).
  • 2026-08-11-variables-permissions.sql grants variables:read and variables:manage to every existing system Org Admin role.
  • The rest create new tables (tenant_variables, supported_currencies, software_install_methods, winget_package_index, software_remediation_requests, ticket_email_links, office_addin_user_bindings, abuse_endpoint_fingerprints) or add nullable columns.

No new required environment variables. New optional ones:

  • BREEZE_WORKSPACE_ENABLED (default false) — loads the built-in Workspace extension (ee/, Breeze Commercial License).
  • PENDING_ACCOUNT_MEETING_URL / PENDING_ACCOUNT_MEETING_LABEL — booking link on the pending-account screen. Map them explicitly in the api service environment: block; .env alone is not interpolated (#3771).
  • TICKETS_INBOUND_DOMAIN and MAILGUN_INBOUND_SIGNING_KEY now appear in .env.example — both existed before; only needed for inbound email-to-ticket.
  • TRUST_CF_CONNECTING_IP, M365_GRAPH_ACTIONS_TOOLS_ENABLED and APP_ENCRYPTION_KEY_ID are now schema-declared and format-checked (a typo refuses boot instead of silently reading as off). APP_ENCRYPTION_KEY_ID is required only when M365_GRAPH_ACTIONS_TOOLS_ENABLED=true, as before (#3515).

⚠️ Windows agent packages are unsigned in the public release — bring your own certificate. Since v0.105.0 the public pipeline builds the self-host edition of the agent family and does not Authenticode-sign breeze-agent-windows-amd64.exe, breeze-agent.msi, or the backup/watchdog/user-helper exes (the -unsigned assets are byte-for-byte copies published as signing inputs). Sign them with your own certificate using the breeze-selfhost-signing template — guide: https://docs.breezermm.com/deploy/sign-your-own-packages/ — and point BINARY_GITHUB_REPOSITORY at your signed re-release. Unsigned binaries install and run, but Windows will show SmartScreen warnings until you sign them. What is new in 0.107.0 for this path:

  • The API now accepts the unsigned self-host exes. On v0.105.x the trust allowlist only admitted the MSI, so boot sync aborted and agent downloads returned 404 on every platform for BINARY_SOURCE=github deployments (#3538). The allowlist is exact-filename and edition-gated: an unsigned asset labeled hosted, or with no edition claim, is still refused. A once-per-asset warning is logged when an unsigned binary is served.
  • A CI guard keeps the allowlist in lockstep with the release workflow (#3761), and registering a release that lacks a signed artifact manifest now fails with a clear 422/409 instead of a silent no-op (#3661).
  • Boot-time binary sync is pinned to releases/tags/v<BREEZE_VERSION> (or BINARY_VERSION if set). With AGENT_AUTO_PROMOTE left at its default true, restarting the API after a newer GitHub release no longer promotes your fleet to a version the download redirect cannot serve (the #3742 checksum-mismatch loop). If your pinned release is not published on GitHub, boot sync logs a loud [binarySync] error telling you to set BINARY_VERSION to the last published release — it does not fall back to /releases/latest, and in github mode the API still starts (#3808).
  • Viewer and Helper installers are still signed by LanternOps, now with an SSL.com OV certificate (O=LANTERNOPS LLC) rather than Azure Artifact Signing (#3762, #3781). A new certificate means SmartScreen reputation starts from zero — expect "unrecognized app" prompts on the Viewer/Helper MSIs for a while after this release.
  • macOS agent .pkgs and Linux binaries are unchanged.

Agent fleet: the agent binaries changed materially in this release (uninstall, EXE installer hang, per-user winget, VPN state, SNMP, PowerShell encoding, secret-variable gating). With AGENT_AUTO_PROMOTE=true (default) the server registers 0.107.0 as latest at boot and agents self-update; with it off, promote the version from the agent-versions admin UI once you have signed and re-released the Windows packages.

Behaviour and default changes:

  • Inbound email-to-ticket toggle is now enforced. Previously display-only. The migration flips a stored false to true only for partners who have actually received inbound mail; a partner with false and no observed mail keeps it and inbound mail is now ignored (status ignored). Check Settings → Ticketing if you rely on inbound mail (#3606).
  • Approved-but-unreleased run_script action-intents must be re-approved. The approval digest moved to a v:2 envelope that pins tenant-variable and parameter references; v1 digests fail content_changed at release by design. Count them before upgrading: SELECT count(*) FROM action_intents WHERE status='approved' AND action_name='run_script'; (#3588).
  • Billing documents stamp currency from the organization, not the partner, and a draft's currency cannot be edited via PATCH — use the new /currency endpoint. Existing documents keep their (now upper-cased) currency (#3804). New quotes default to the partner currency, not USD (#3572).
  • Secret tenant variables are not delivered yet. Variables marked secret are refused at script save/import (400) and at dispatch; activation lands in a follow-up release (#3557, #3562, #3588).
  • Boolean query params are now honoured — ?x=false used to be parsed as true at 8 endpoints (#3528). GET /software/catalog versionCount was silently 0 and now reports real counts (#3587).
  • Global patch-catalog rows are no longer writable by agent scans; severity/version observations live on the tenant row (#3645). Prometheus HTTP and heartbeat series start populating — alert rules that assumed their absence will now evaluate (#3763).
  • coturn (turn profile only) reads TURN_SECRET from a Compose secret and refuses to start when it is empty; deployments without the profile are no longer blocked by the missing variable (#3717).
  • Workspace is compiled into the API image but dormant unless BREEZE_WORKSPACE_ENABLED=true; the runtime-bundle and source-directory extension loaders are removed (#3455, #3488).

No breaking changes beyond the items above: no API routes removed, no required env vars added, no manual SQL. The one thing that requires action from a self-hoster with Windows endpoints is the BYO-signing step, and that has been the case since v0.105.0 — 0.107.0 is the release where it actually works end to end.

Full Changelog: v0.105.1...v0.107.0


What's Changed

  • fix(deps): override deepmerge-ts to 8.0.1 for CVE-2026-40345 by @ToddHebebrand in #3718
  • fix(selfhost): unbreak first-boot — stale image pin, TURN_SECRET gate, placeholder key by @ToddHebebrand in #3717
  • ci: dispatch-only hosted server-image builds (hosted-images.yml) by @ToddHebebrand in #3741
  • fix(mobile): make the iOS app lock survive process death by @ToddHebebrand in #3746
  • fix(mobile): pull dependencies back into the Expo SDK 57 supported range by @ToddHebebrand in #3747
  • chore(deps): bump golang.org/x/mod from 0.38.0 to 0.40.0 in /agent by @dependabot[bot] in #3714
  • chore(deps): bump the aws-sdk group in /agent with 5 updates by @dependabot[bot] in #3711
  • chore(deps): bump golang.org/x/text from 0.40.0 to 0.41.0 in /agent by @dependabot[bot] in #3712
  • chore(deps): bump google.golang.org/api from 0.292.0 to 0.293.0 in /agent by @dependabot[bot] in #3715
  • chore(deps): bump futures-util from 0.3.33 to 0.3.34 in /apps/helper/src-tauri by @dependabot[bot] in #3737
  • chore(deps): bump whoami from 2.1.2 to 2.1.3 in /apps/helper/src-tauri by @dependabot[bot] in #3738
  • chore(deps): bump swatinem/rust-cache from a45951ff880207c249adf57334cf2e9bd81d6e1e to f0d9c3887740aee45f6153b24b3a6b815192ec16 by @dependabot[bot] in #3722
  • chore(deps): bump golang.org/x/net from 0.57.0 to 0.58.0 in /agent by @dependabot[bot] in #3713
  • ci: build the validated commit in hosted-images, not the tag again by @bdunncompany in #3743
  • refactor(web): hoist the #3698 confirm constants and cover the grid-card path by @bdunncompany in #3706
  • fix(ci): stop main-red-alert turning a green CI run red on a transient API error by @bdunncompany in #3735
  • fix(ci): give the Tauri apt step per-command deadlines so a stall can retry by @bdunncompany in #3731
  • fix(web): state the notification channel test verdict in text, not just an icon by @bdunncompany in #3733
  • fix(api,web): return a per-org device count so the org card stops rendering " devices" by @bdunncompany in #3734
  • fix(web): a locale change no longer drops a live VNC session by @bdunncompany in #3736
  • feat(mobile): Tickets tab — queue, detail, comment and status change (#3206) by @bdunncompany in #3716
  • fix(mobile): surface real issues on Systems — active page, partial-failure tolerance, empty state by @bdunncompany in #3719
  • feat(mobile): browsable devices list, and stop a slow acknowledge reading as failure by @bdunncompany in #3720
  • fix(web): batch bulk vulnerability actions to the server's 200-id cap (#3694) by @bdunncompany in #3709
  • feat(mobile): let a self-hosted build add its own associated domain by @bdunncompany in #3732
  • docs(mobile): correct the associated-domains "returned verbatim" claim by @bdunncompany in #3751
  • fix(ci): bound the Tauri apt step so it cannot relocate the job timeout by @bdunncompany in #3756
  • fix(mobile): the device walk asks for a page size the server honours by @bdunncompany in #3757
  • docs: v0.106.0 release sweep + 2026-08-17 UI QA log by @ToddHebebrand in #3707
  • docs: retire the plans-folder work queue; wire feature-lifecycle tracking by @ToddHebebrand in #3745
  • fix(api): deadlock on agent network inventory vs re-enrollment (40P01) by @ToddHebebrand in #3739
  • fix(selfhost): stop .env.example shipping a localhost DATABASE_URL_APP by @ToddHebebrand in #3728
  • fix(api): mount metricsMiddleware — http_requests_total and agent_heartbeat_total emit nothing in production by @ToddHebebrand in #3763
  • fix(api): stop /sessions/live holding a pooled connection across a 10s agent round-trip by @ToddHebebrand in #3764
  • ci: guard the release trust allowlist against pipeline drift (#3504) by @ToddHebebrand in #3761
  • ci(release): make the Windows signing CA switchable (Azure | SSL.com) by @ToddHebebrand in #3762
  • feat(web,api): booking link on the pending-account screen so the payment wall isn't a dead end by @ToddHebebrand in #3771
  • docs(agents): fix AGENTS.md saying Codex orchestrates work Codex handles (#3498) by @ToddHebebrand in #3766
  • docs: rescue 18 plan/spec docs that existed only in local worktrees by @ToddHebebrand in #3767
  • fix(agent): hex-encode SNMP octet strings that aren't safe text; stop trim-order data loss by @ToddHebebrand in #3765
  • fix(mobile): echo the server's CSRF token so the session can actually refresh (#3723) by @bdunncompany in #3726
  • fix(mobile): stop Systems and Tickets presenting partial state as complete (#3753) by @bdunncompany in #3769
  • feat: multi-currency wave 1 — currency foundations by @ToddHebebrand in #3794
  • ci(release): add switchable SSL.com Windows signing by @ToddHebebrand in #3781
  • feat: invoice re-send with customer-email composer (quote parity) by @ToddHebebrand in #3790
  • feat(api,portal,web): public invoice pay link + quote accept/decline completion (waves 2-5 of #3784) by @ToddHebebrand in #3805
  • ci(release): keep package-windows-updater alive when the non-selected signing provider job is skipped by @ToddHebebrand in #3807
  • feat: multi-currency wave 2 — document correctness (#3774) by @ToddHebebrand in #3804
  • fix(api): pin boot-time binary sync to the server's own release, not /releases/latest by @ToddHebebrand in #3808

Full Changelog: v0.106.0...v0.107.0

Don't miss a new breeze release

NewReleases is sending notifications on new releases.