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-verifyjob 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_brandingflags. - 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_agentskind,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 typeddevice_functionclassification (distinct from the billabledevice_role), with its ownGET/PUT /devices/:id/functionroute, 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-readgains 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/connectedlowercase 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-consent400 invalid_scopefailures (#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:readpermission, 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_sessionsterminal 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-170300 … 2026-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_ENABLEDnow defaults totrue. Set it tofalseto keep the AI script-authoring tools and the/api/v1/ai/script-proposalssurface dark.BREEZE_AI_SCRIPT_REVIEWER_MODEL— optional, sets the platform-default reviewer model for AI script review.STRIPE_SESSION_REVOCATION_MODE— new, defaults toenforce; set toobserveas an incident de-escalation lever.APP_ENCRYPTION_KEY_ID— the API now refuses to boot without it whenM365_GRAPH_ACTIONS_TOOLS_ENABLED=trueorBREEZE_ROLEisapi/worker; integration credential saves return503without it in any other configuration (a boot-time warning only, not a refusal, to avoid bricking installs whoseguided-setup.shrun predates this key). Must be set in.envand mapped explicitly in theapiservice'senvironment:block, or compose interpolation won't pick it up.M365_SYNC_CONTINUATION_KEY— optional, for self-hosters running the separatem365-graph-read-executorservice; 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:writein the proposal's organization plus MFA; four-eyes review requests for such proposals fan out only to holders ofscripts: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