github LanternOps/breeze v0.113.0

16 hours ago

Breeze RMM v0.113.0 — remote desktop sessions stop dropping every minute, AI can now write and run its own scripts under independent review, and the first wave of service-deliverable tracking for MSP contracts ships.

Lead fix: if remote desktop has been dropping every 30–90 seconds since early August, update now. The orphan-session sweeper was finalizing healthy peer-to-peer viewer sessions because it only recognized a WebSocket-owned session as alive — the default P2P transport never opens that socket. No agent update needed; the fix is server-side (#5624).

⚠️ Self-hosters running a split BREEZE_ROLE deployment, or with M365 actions enabled, must set APP_ENCRYPTION_KEY_ID before upgrading — the API now refuses to boot without it under those configurations. See Self-Hosting below.

Summary

Remote desktop reliability and a per-monitor DPI fix headline this release, alongside two new MSP-facing feature waves — AI-authored, independently reviewed scripts, and service-deliverable / key-date tracking for contract work — plus early foundations for a monitor-definitions rewrite of alerting, an AI Fleet Designer agent, and M365 tenant-sync, and a security hardening pass across billing, alerting, and remote-session start ordering.

Added

  • AI-authored scripts, reviewed and approved on a readable card (#5612 — PRs #5621, #5630, #5636, #5640, #5642, #5644). The assistant and background agents can author a script as an immutable proposal; every proposal is scanned, classified, and independently reviewed by a model that never sees the author's transcript, then approved on a card showing goal, expected effect, reviewer findings/risk tier, target devices, and the code itself. A script-verify job checks the run with an independent device read before the script can be saved to the library. A reviewer-gated unattended lane also ships, off by default (no env flag — partner ceiling + org opt-in only).
  • Service deliverables (#5573 — PRs #5603, #5606, #5627, and template sets from #5578/099f6a973): sweep worker, ticket integration, key-date reminders, auto-evidence, MCP tools, an org document library with blob-storage extraction, and customer-portal Service/Documents surfaces behind new portal_branding flags.
  • Monitors — API and UI complete (#5287 W01/W02 — PRs #5648, #5664, #5693). A monitor is now the single object a technician authors (condition + severity + delivery + responses); the API compiles each definition into the alert-template/alert-rule/automation rows the existing sweep, dispatcher, and automation worker already execute, so nothing downstream needed to learn a new shape. Ships with a Monitors UI, a policy-attachment tab, one-click conversion of legacy alert rules to monitors, and new MCP tools. Automations also moved to a top-level Jobs nav entry (old /automations/* still redirects) and Network Monitor was renamed Monitoring. No env flag — reachable today from the Jobs/Monitoring nav.
  • AI Fleet Designer, wave 1–2 (#5650 W01/W02 — PRs #5691, #5694). A fourth ai_agents kind, designer, assembles a bounded, org-pinned evidence bundle and produces a structured, eight-section fleet report (devices, software, network, posture, health, automation, event-log shape) persisted as a PDF-rendered report artifact — read-only, no fleet mutations in this wave. W02 adds a typed device_function classification (distinct from the billable device_role), with its own GET/PUT /devices/:id/function route, AI-derived or manual, surfaced in the Device Role card and as a catalog filter. No new env var — a designer-kind AI agent must be configured per org before it produces anything, the same as other AI agent kinds.
  • M365 tenant-sync foundation (#5327/#5329 — PRs #5649, #5657). New schema (m365_sync_state, m365_users, m365_intune_devices, m365_ca_policies, m365_license_skus, m365_secure_score_snapshots, m365_posture_rollups) and a third wave of the M365 Graph-read executor adding write-capable sync actions, a route, in-flight/rate limits, and an API client. Infrastructure only in this release — no UI surfaces it yet. Runs only for partners with the M365 Graph executor deployed; new optional executor env vars below.
  • Bare-metal recovery, Linux wave (#5493 — PR #5588, fixes #5632, #5634, #5638): Linux live recovery media built in CI, a guided recovery console, and a real QEMU end-to-end CI gate.
  • Desired-state install arming (#5506/#5662): software policies can now express and authorize "install this" (remediationOptions.autoInstall, verb-aware gate, devices.execute + MFA authorization, install audit actions). Nothing dispatches an install yet — this wave makes it expressible.
  • Devices & Assets navigation (#5605): unified devices/manual/network-asset list renamed "Devices & Assets"; sidebar shows your last 5 devices; Cmd+K is now a "jump back" surface (recent devices → recently visited → quick actions).
  • Reusable Tier-3 step-up grant (#5601/#5608): approving several supervised AI tool-call rows in a row now needs one passkey/TOTP ceremony instead of one per row (120 s window; four-eyes is unaffected).
  • Mobile platform attestation surfacing (#4707 W07/#5647): approver-devices UI splits "Platform-bound" into Hardware-attested vs. Not attested, plus a mobile registration banner.
  • M365 manifest v3 (#5656, tenant-sync foundation W01): customer-graph-read gains four new Graph permissions for the upcoming posture program; existing customers get a non-interrupting re-consent prompt.
  • Backup GC sweep reclaiming retired/orphaned backup-object prefixes, on top of the existing loose-object and manifest-less-prefix grace rules (#5449 W02/#5485).
  • MFA enrolment grace window for role-forced users who have never held a factor — a nonrenewable, database-clock-timed 14-day deadline instead of the old all-or-nothing kill switch (#5306/#5686). Still inert unless MFA_FORCE_FOR_PARTNER_ADMIN (existing, unchanged default off) is turned on.

Fixed

  • Remote desktop peer-to-peer sessions no longer finalized as orphans every 30–90 s (#5624).
  • Secondary-monitor input/cursor on multi-monitor Windows hosts with mixed DPI scaling (#5599) — requires the updated agent/helper.
  • UniFi devices synced via the Network Integration API no longer show as offline (online/connected lowercase status now recognized) (#5661).
  • Partner auto-promotion was fully blocked (billing risk-hold route mismatch, missing IP backfill, a parsing bug, and a hard-deny bypass) — all four fixed (#5619/#5620).
  • AI script proposal runs and promoted versions now stamp the real approval method instead of a hardcoded value, fixing the risk-dashboard's unattended-run metric and library provenance panel (#5645/#5646).
  • Bare-metal recovery: console reboot countdown no longer hangs forever (#5638); re-authenticating during a long recovery download now correctly slides the session window (#5634); the code-exchange response is decoded through the envelope-aware bootstrap decoder (#5632).
  • MCP OAuth clients (Claude.ai connector, Claude Code) no longer get garbage-collected while in active use, which caused invalid_client/re-consent 400 invalid_scope failures (#5558).
  • Partner-wide ("All orgs") deliverable template sets disappeared once any organization page was open (#5675/#5680).
  • Resetting a paused AI unattended script lane failed for TOTP approvers with Invalid code (#5683/#5685).
  • AI chat sessions no longer stay bound to the wrong organization when a device page in a different org is opened while a stale session is persisted (#5684/#5688).
  • AI script proposals now derive their organization from the target device instead of the caller's token, fixing script authoring for every partner-scope technician now that it defaults on (#5682/#5689).

Security — hardening

  • SEC-150 (#5556): a Stripe Checkout session could remain payable by the customer after Breeze reset the invoice link, recorded a manual payment, voided the invoice, or replaced the Stripe key — risking a duplicate charge or payment against a voided invoice. Revocation is now fail-closed (bounded-async only for a Stripe disconnect).
  • SEC-065 (#5560): generic integration settings (Discord webhook URLs, Teams client secrets, Grafana/OpsGenie/PagerDuty keys, monitoring webhook endpoints) were stored and echoed in plaintext to any same-org actor with only read access. Credentials are now sealed at rest and masked on every read/write response.
  • SEC-049 (#5540): the legacy alert-correlation endpoints ignored the site ceiling and the alerts:read permission, letting a site-restricted or permission-stripped reader see the org's full alert-correlation graph; one code path could also widen to every correlation in the org on certain inputs. Both gates are now enforced.
  • SEC-038 W02/W04 (#5659, #5660): remote desktop start/stop commands are now ordered against a monotonic per-session generation on both server and agent, closing a race where a terminal decision could win the database but still lose the wire to a late start.
  • SEC-038 W03 (#5679): one shared terminal-intent contract for every remote_sessions terminal writer, so a start can be linearized against a terminal decision even when the two commands arrive out of order.

Self-Hosting / Upgrade Notes

Upgrade: bump BREEZE_VERSION in .env, then docker compose pull api web portal && docker compose up -d (or pnpm install when running from source).

Migrations: 22 migrations land in this range (2026-10-15-1703002026-10-16-170700). All are idempotent and auto-apply on boot via autoMigrate; all have been dry-run as doadmin (non-superuser) inside BEGIN/ROLLBACK on both production databases and passed. Backfills are small: one head-version row per existing script in script_versions (24 EU / 105 US), scripts.origin set to system on built-in scripts (24), documents:read/documents:write permissions seeded and granted to existing Partner Technician / Org Admin / Org Technician roles, and the Stripe checkout-session-revocation migration marking aged-out pending session mappings revoked and pre-contract ones legacy_unbounded (US: 1 + 1, EU: 0). The new monitor-definitions, M365 tenant-sync, Fleet Designer, and device-function-assessments tables are DDL-only additions — no backfill. No large-table rewrites.

Environment variables:

  • BREEZE_AI_SCRIPT_AUTHORING_ENABLED now defaults to true. Set it to false to keep the AI script-authoring tools and the /api/v1/ai/script-proposals surface dark.
  • BREEZE_AI_SCRIPT_REVIEWER_MODEL — optional, sets the platform-default reviewer model for AI script review.
  • STRIPE_SESSION_REVOCATION_MODE — new, defaults to enforce; set to observe as an incident de-escalation lever.
  • APP_ENCRYPTION_KEY_ID — the API now refuses to boot without it when M365_GRAPH_ACTIONS_TOOLS_ENABLED=true or BREEZE_ROLE is api/worker; integration credential saves return 503 without it in any other configuration (a boot-time warning only, not a refusal, to avoid bricking installs whose guided-setup.sh run predates this key). Must be set in .env and mapped explicitly in the api service's environment: block, or compose interpolation won't pick it up.
  • M365_SYNC_CONTINUATION_KEY — optional, for self-hosters running the separate m365-graph-read-executor service; without it the executor mints an ephemeral per-process key and a continuation simply restarts (self-healing) across a process restart.
  • M365_SYNC_MAX_IN_FLIGHT — optional executor tuning knob; must be ≤ M365_MAX_IN_FLIGHT.
  • LENOVO_WARRANTY_ENABLED (from v0.112.0) remains opt-in.

New infrastructure: a new BullMQ queue, script-verify, consumed by the socket-owner worker — no new service or port.

Behavior changes:

  • Approving a Strict-pattern AI script proposal now requires scripts:write in the proposal's organization plus MFA; four-eyes review requests for such proposals fan out only to holders of scripts:write.
  • The AI unattended script lane ships off: it needs an MSP partner to open the ceiling and the individual organization to opt in. No env flag controls it.
  • The AI Fleet Designer agent kind ships available but inert: it produces nothing until an administrator configures a designer-kind AI agent for an organization, same as any other AI agent kind.
  • M365 tenant-sync foundation lands schema and executor plumbing only — no operator-visible UI change in this release.
  • Backup GC sweep begins reclaiming retired/orphaned backup-object storage prefixes on top of the existing loose-object and manifest-less-prefix grace rules — expect storage usage to drop for organizations with old retirements.
  • Automations moved under a new Jobs nav entry; bookmarked /automations/* links still redirect. Network Monitor is now labeled Monitoring.

No other breaking changes.

Full Changelog: v0.112.0...v0.113.0

What's Changed

  • fix(ai): persist approvalMode on the first ai_budgets save (#5592) by @ToddHebebrand in #5595
  • chore(deps): bump pnpm/action-setup from 6.0.10 to 6.1.0 in the github-actions group by @dependabot[bot] in #5348
  • fix(peripheral): stop reconciling decommissioned devices (#5590) by @ToddHebebrand in #5594
  • fix(ai): AI credit calls must use the /billing/api/internal prefix (#5591) by @ToddHebebrand in #5597
  • fix(ai): bind chat sessions to the page-context device org and use effective approval mode (#5593) by @ToddHebebrand in #5598
  • feat(web): SSR shell translation — tServer + page titles + error pages (Task 2 of #3859) by @fabicarvano in #5274
  • fix(web): render deliverable due dates and key dates as calendar dates (#5573 smoke) by @ToddHebebrand in #5596
  • fix(ci): customer-PII guard ignores systemd unit names by @ToddHebebrand in #5530
  • fix(alerts): scope legacy correlations to visible alerts (SEC-049) by @ToddHebebrand in #5540
  • fix(remote): per-monitor DPI awareness so input and cursor land on secondary monitors by @ToddHebebrand in #5599
  • fix(ai): stop running a passkey ceremony for every supervised self-approve (#5600) by @ToddHebebrand in #5602
  • feat(deliverables): sweep worker, ticket integration, key-date reminders, auto-evidence, MCP tools (#5575) by @ToddHebebrand in #5603
  • fix(oauth): MCP re-authorize fails (DCR GC deletes live clients; re-consent 400s invalid_scope) by @ToddHebebrand in #5558
  • fix(integrations): stabilize webhook credential identity and stop echoing the secret to the web form (SEC-065) by @ToddHebebrand in #5560
  • feat(mobile): Android StrongBox/TEE key attestation + Play Integrity client (#4707 W06) by @ToddHebebrand in #5168
  • docs(ai): AI script authoring, independent review, and reviewer-gated execution design spec by @ToddHebebrand in #5604
  • feat(documents): org document library, blob storage extraction and document evidence (#5576) by @ToddHebebrand in #5606
  • feat(scripts): immutable script versions — every writer cuts one (#5612 W01) by @ToddHebebrand in #5621
  • feat(backup): bare-metal recovery — Linux live media, recovery console, and QEMU e2e (W04b) by @ToddHebebrand in #5588
  • docs(backup): W04a/W04b plans — recovery codes + state machine + check-in; live media + console + QEMU proof (#5493) by @ToddHebebrand in #5527
  • fix(remote): stop the desktop orphan sweeper finalizing peer-to-peer viewer sessions by @ToddHebebrand in #5624
  • feat(approvals): reusable step-up grant so consecutive Tier-3 approvals need one ceremony (#5601) by @ToddHebebrand in #5608
  • feat(portal): customer Service and Documents surfaces (service deliverables W04) by @ToddHebebrand in #5627
  • fix(bmr): decode the exchange response through the envelope-aware bootstrap decoder (#5493) by @ToddHebebrand in #5632
  • feat(ai): script proposals, proposal-backed executions, scanner + classifier, propose_script (#5612 W02) by @ToddHebebrand in #5630
  • docs(ai): re-base AI script authoring migration slots (#5612) by @ToddHebebrand in #5633
  • feat(deliverables): template sets, apply-to-org/contract, settings page, backfill (#5573 W05) (#5578) by @ToddHebebrand in #5628
  • fix(bmr): re-authenticate slides the recovery download session window (#5493) by @ToddHebebrand in #5634
  • feat(ai): script proposal reviewer worker — structured verdict, classifier floors, budget reservation (#5612 W03) by @ToddHebebrand in #5636
  • docs(backup): bare-metal recovery page around the recovery media flow + W04b KIT proof ledger (#5493) by @ToddHebebrand in #5639
  • fix(recovery-console): run stty against the console so the reboot countdown actually times out (#5493) by @ToddHebebrand in #5638
  • feat(ai): script proposal approval cards, STRICT acknowledgement ceremony, request-changes, verification, promote (#5612 W04) by @ToddHebebrand in #5640
  • feat(ai): reviewer-gated unattended lane — script policies, script_reviewer autonomy, lane state, checkpoint (#5612 W05) by @ToddHebebrand in #5642
  • fix(ai): stamp the real approval method on proposal runs and promoted versions (#5645) by @ToddHebebrand in #5646
  • feat(ai): AI-authored script runs in device activity, risk dashboard metrics, docs (#5612 W06) by @ToddHebebrand in #5644
  • fix(partner-trust): unblock auto-promotion — billing route, IP backfill, parser, hard-deny (#5619) by @ToddHebebrand in #5620
  • docs(ai): Fleet Designer implementation plans W01–W05 (feature #5650) by @ToddHebebrand in #5658
  • docs: specs + wave plans for desired-state software install (#5505) and HP CMSL warranty (#5511) by @ToddHebebrand in #5524
  • feat(auth): mobile platform attestation W07 — surfacing, alerting, docs by @ToddHebebrand in #5647
  • feat(m365): manifest v3 + non-interrupting upgrade consent (W01) by @ToddHebebrand in #5656
  • feat(remote): server generation columns + start-intent CAS on all three desktop start sites (SEC-038 W02) by @ToddHebebrand in #5659
  • fix(unifi): treat lowercase "online"/"connected" status as online (#5643) by @ToddHebebrand in #5661
  • feat(api): desired-state install arming — autoInstall, verb-aware gate, devices.execute+MFA authorization, install audit actions (#5506) by @ToddHebebrand in #5662
  • chore(ci): reuse application builds across tests and releases by @ToddHebebrand in #5430
  • fix(billing): fail-closed Stripe Checkout session revocation on reset, payment, void and key replacement; bounded-async disconnect (SEC-150) by @ToddHebebrand in #5556
  • feat(web): Devices & Assets, recent devices, jump-back palette, keyboard shortcuts by @ToddHebebrand in #5605
  • feat(web): Jobs nav + Monitoring hub — W01 discoverability (#5287) by @ToddHebebrand in #5648
  • feat(agent): in-memory desktop start fence — HWM + terminal tombstone (SEC-038 W04) by @ToddHebebrand in #5660
  • D18 W02: GC sweep reclaims retired and orphaned backup prefixes by @ToddHebebrand in #5485
  • fix(api): list partner-wide deliverable template sets when an org is pinned (#5675) by @ToddHebebrand in #5680
  • fix(web): ask a TOTP approver for a code before resetting the AI script lane (#5683) by @ToddHebebrand in #5685
  • release: 0.113.0 What's New entry + pre-release sweep doc by @ToddHebebrand in #5687
  • fix(web): rebind the AI chat session when the device page is in another org (#5684) by @ToddHebebrand in #5688
  • feat(m365): tenant sync wave 3 — executor sync actions, route, limits, API client by @ToddHebebrand in #5657
  • feat(remote): one terminal-intent contract for every remote-session terminal writer (SEC-038 W03) (#5534) by @ToddHebebrand in #5679
  • fix(ai): derive script proposal org from the target device, not the token (#5682) by @ToddHebebrand in #5689
  • feat(monitors): W02 — monitor definitions, compiler, cumulative resolver and policy attachment (#5287) by @ToddHebebrand in #5664
  • feat(auth): MFA enrolment grace window for role-forced users (#5306) by @ToddHebebrand in #5686
  • feat(m365): tenant sync foundation — schema, migration, registrations, retention (W02 #5329) by @ToddHebebrand in #5649
  • feat(ai): Fleet Designer kind — designer lane, evidence bundle, submit_fleet_design, report persistence (W01 #5650) by @ToddHebebrand in #5691
  • feat(web): W02 Monitors UI, policy tab, legacy conversion, MCP tools (#5287) by @ToddHebebrand in #5693
  • feat(devices): device function — assessments table, service, GET/PUT /devices/:id/function, Function field, applyDesignFunctions (W02 #5650) by @ToddHebebrand in #5694

Full Changelog: v0.112.0...v0.113.0

Don't miss a new breeze release

NewReleases is sending notifications on new releases.