Skip to content

v0.120.0

Latest

Choose a tag to compare

@github-actions github-actions released this 01 Oct 23:02
· 91 commits to main since this release
3fc5393

Breeze RMM v0.120.0: backups to S3 written only through short-lived storage sessions, integrity-checked restores, consent prompts that report whether they were shown, the remote desktop start fence on by default, and the first two waves of the AI model registry.

⚠️ Backups to S3 now need agent v0.119.0 or later, and HTTPS.

  • What changed. Scheduled, SQL Server and Hyper-V backups to S3 or S3-compatible storage are written only through a short-lived, write-scoped storage session. No backup command carries the storage destination or its keys.
  • Who is refused:
    • A device whose backup component reports it cannot write this way: "Update the Breeze agent on this device, then try again."
    • An http:// storage endpoint.
    • An agent API address over plain http://, or an unset PUBLIC_API_URL.
  • No fallback. Local and NAS destinations are unchanged.
  • Before upgrading, update every device that backs up to S3 and move storage endpoints and the agent API to HTTPS. See HTTPS for Backups (#7566).

⚠️ Behaviour changes that need attention. Details are under Self-Hosting / Upgrade Notes.

  • The remote desktop start fence (REMOTE_DESKTOP_FENCE_REQUIRED) now defaults to on for new installs. Existing installs keep their current setting until they change .env (#7564).
  • The default AI model is now Claude Sonnet 5.5 with adaptive thinking. If you route AI through a gateway alias, update the alias (#7593).
  • Under a Require consent policy, a signed-in user who cannot be shown the prompt is now always refused. Unanswered prompts on macOS and Linux are refused. Update the server before agents; the normal order already does this (#7560, #7562).
  • Breeze Assist on Windows now works in the console session only (#7556).

Security: hardening

This release includes security hardening across:

  • backup storage access;
  • restore integrity;
  • Windows restore file handling;
  • remote desktop session starts and consent;
  • the Breeze Assist credential;
  • customer portal sign-out;
  • device restore limits;
  • enrollment key lookups;
  • dependency updates for upstream advisories.

Self-hosters are encouraged to upgrade the server and let agents and Breeze Assist update to 0.120.0. (#7566, #7565, #7561, #7564, #7575, #7560, #7562, #7556, #7558, #7549, #7548, #7546, #7563)

Summary

  • Backups to S3 use storage sessions only. Every S3 backup is written through a short-lived, write-scoped session (#7566).
    • The Backup policy's Destination section has a new card. It lists the storage keys your S3 destinations used before this release, and keeps each one listed until it has been replaced and disabled with your storage provider.
    • Check old key asks the storage provider. I disabled this key records your confirmation.
  • Restores are checked against the snapshot's integrity record (#7565, #7561, #7568).
    • What is checked. The server sends each snapshot's integrity expectations with every restore, verify, test restore, VM restore and bare-metal recovery. The updated backup helper checks the manifest and every restored file against them before anything is installed.
    • What is refused. A snapshot that failed its integrity check is refused.
    • Snapshots without an attestation. They still restore, and the result is labelled unattested.
  • Windows restores are stricter about what they write (#7561).
    • Reserved names. Path components that Windows reserves (CON, NUL, COM1 and the like), or that contain : or end in . or a space, are refused.
    • Unrecognised security descriptors. A restored security descriptor whose accounts the machine doesn't recognise is replaced with a restrictive one: owner Administrators, access for SYSTEM and Administrators only. The result lists those paths.
    • bmr_recover is files-only on Windows. It restores files only. System state is applied by a bare-metal rebuild.
  • Consent prompts report whether they were shown and answered (consent prompt protocol 2) (#7560, #7562, #7575).
    • What the agent knows. The agent, Breeze Assist and the native dialogs now report whether the prompt was actually on screen, and whether anyone is signed in to the session being viewed.
    • What the technician sees. A specific message for each outcome.
    • What the audit log records. The detail of each outcome.
  • The WebSocket desktop fallback now follows the same start rules as WebRTC (#7564).
    • Starting a session. It honours the session start fence, notify mode and the consent prompt.
    • Ending a session. End stops it immediately.
  • AI model registry, waves 1 and 2 (#7643, #7665).
    • Admin page. A platform model catalog with a new Admin → AI models page (/admin/ai-models) for prices, offered models and the platform default.
    • Discovery. A daily Anthropic model discovery job flags new models for review and never enables, prices or removes anything on its own.
    • Partner-level tables. They are backfilled from each partner's current setup, and a shadow usage ledger is added.
    • Routing and billing are unchanged in this release.
  • AI chat usage is counted correctly on multi-turn chats (#7669). Each turn of a chat was being charged the running total of the conversation so far, which inflated session cost, budgets, AI credit deductions and the Office per-user ledger. Each turn is now charged its own cost. This covers main chat, Office chat, helper chat and the script builder. Earlier records are not rewritten.

Added

  • Storage key card and API (#7566). GET /backup/storage-credentials, POST /backup/storage-credentials/:id/check and POST /backup/storage-credentials/:id/confirm-disabled.
    • Check limits. Checks are limited to 10 per organization per 10 minutes.
    • Audit and access. Both actions are audited, and no AI tool can run them.
  • Admin → AI models (#7643). Platform admins set prices, fast-mode rates, option support, plan gate, prompt profile, offered models and the default. Changes require MFA. Refresh queues a discovery sync.
  • Recovery result codes and restricted-descriptor details in the restore and Recovery views (#7568).
  • Metrics:
    • breeze_backup_restore_integrity_total{type,status,reason} (#7565).
    • breeze_backup_write_dispatch_unexpected_legacy_total now counts any backup delivered with its storage key; none are expected (#7566).
  • Agent heartbeat capability securityCapabilities.desktopWsFenceProtocolVersion (#7564). The server accepts it and does not require it yet.

Improved

  • Default AI model is Claude Sonnet 5.5 with adaptive thinking at effort medium (#7593).

    • Existing chats keep their model.
    • POST /ai/sessions now rejects a model that isn't offered (400 invalid_model).
    • Raw one-shot calls (script reviewer, patch-test analysis, ticket and email drafts) cap thinking so short answers are not truncated.
    • Pricing has rows for Sonnet 5.5, Opus 5.5 and Fable 5.1.
  • Backup helper capability reporting (#7558). When the agent can't ask its backup component which features it supports, it now reports "unknown" instead of "none". Retries run after 1, 2 and 4 minutes, then every 5 minutes. A brief probe failure no longer makes a current helper look outdated. The waiting message now names the backup component.

  • Windows registry hives are flushed before the VSS snapshot, so recent registry changes are in system-state backups and rebuilt machines (#7408).

  • DR plans: a Bare metal rebuild step now waits up to 24 h by default (was 4 h) (#7418).

  • Topology: turning on materialization now imports each site's first snapshot automatically. Sites no longer stay on "Building the topology map" (#7559).

  • Breeze Assist on Windows receives its credential only over the agent's local channel. It is no longer written to agent.yaml. On upgrade the agent moves any token it finds there into its protected secrets file and rotates the credential once (#7556).

  • API error codes (#7435). Five codes from device and agent routes now use the standard uppercase form:

    • SCHEME_NOT_ALLOWED
    • INVALID_CUSTOM_FIELD_VALUE (was invalid-custom-field-value)
    • RACE_LOST
    • RE_ENROLLMENT_REQUIRED
    • SOFTWARE_INVENTORY_LOCK_TIMEOUT

    HTTP statuses and messages are unchanged. Update integrations that match on the old lowercase codes.

Fixed

  • Remote desktop. The WebSocket fallback no longer refuses every start under a notify (default) or consent policy (#7564).
  • Remote desktop. A start result the server could not read now fails the session with a clear message instead of leaving it "connecting" (#7575).
  • Patches. The device Patches tab shows ring-aware approval state, not "Pending approval" on every patch (#7637).
  • Alerts. The built-in Patch job failures and Reboot pending too long rules, and other built-in rules, can be switched off. An inactive rule raises nothing (#7639).
  • Monitoring. Recommended → Attach to policy works on a policy that has no monitors link yet (#7633).
  • Add Device. The CLI command and its copy button appear only once a token exists. The setup wizard's enroll step does the same (#7631).
  • Agent (Windows). breeze-agent service start succeeds when the service is already running, so re-running the install one-liner no longer fails (#7497).
  • Custom fields. Editing a field without options (Text, Number, Boolean, Date) saves (#7496).
  • Restore results. A bare-metal recovery's failedFiles count is accepted. Advisory warnings (unattested snapshot, vault fallback, files-only recovery) are no longer shown as failures (#7568).
  • Customer portal. Sign-out is now recorded durably and holds across cache restarts (#7549).
  • Devices. Restoring a removed device counts against the partner device limit, like enrollment (#7548).
  • Enrollment keys. Key-id routes answer 404 "Enrollment key not found" for a key outside the caller's sites (#7546).
  • Binary downloads. Backup, watchdog, user-helper and recovery-media downloads read the same storage keys that binary sync writes (#7555).
  • Compose. The audit-chain settings now reach the API container (#7641). These are AUDIT_ANCHOR_SIGNING_KEY, AUDIT_CHAIN_ANCHOR_ENABLED, AUDIT_CHAIN_VERIFY_* and AUDIT_ADMIN_DATABASE_URL. The production Compose file also gains the DEVICE_COMMAND_QUEUE_* deadlines.
  • Release. arm64 recovery media builds on a native arm64 runner (#7419).
  • AI models admin. The /admin/ai-models price drawer edits prices in dollars, the same unit the table shows (#7699).
  • Dependencies. axios 1.20.0 and @grpc/grpc-js 1.14.5 (#7563).

Known issues

  • Deleting a backup destination that has job history returns an error. Disable the destination instead for now (#7622).
  • A crash-consistent Hyper-V backup of a VM that is turned off fails; application-consistent backup of the same VM works (#7623).
  • Breeze Assist on Windows does not run in RDP or other non-console sessions (#7542).
  • Windows Quick Support cannot start for a standard (non-admin) user (#7620).
  • Binary sync: if an S3 upload fails at boot, the previous release's object stays in place until the next successful sync (#7574).

Self-Hosting / Upgrade Notes

Upgrade command. Check how your install pins its images: grep '^BREEZE_API_IMAGE_REF=' .env.

  • Digest-pinned (value ends in @sha256:…, every guided-setup.sh install from v0.112.0): fetch the current guided-setup.sh from main, then run bash guided-setup.sh --upgrade 0.120.0. It verifies the signed image inventory, updates BREEZE_VERSION and all four image digests, then pulls and restarts.
  • Tag-form (value ends in :${BREEZE_VERSION}): set BREEZE_VERSION=0.120.0, then run docker compose pull api web portal && docker compose up -d.
  • Do not edit only BREEZE_VERSION on a digest-pinned install. It re-pulls the images you already run.
  • guided-setup.sh --upgrade does not edit your docker-compose.yml. The changes it doesn't pick up are listed below.
  • See the Upgrade Guide.

Breaking changes and required actions.

  1. Backups to S3: agent ≥ 0.119.0 and HTTPS, before you upgrade (#7566).
    • Who is refused:
      • A device whose backup component has reported it cannot write through a storage session is refused (409 helper_update_required on the on-demand SQL Server and Hyper-V routes; scheduled jobs fail with the same message).
      • Devices that have not reported yet are held until their first heartbeat, as before.
      • http:// storage endpoints, a plain-http:// agent API or a missing PUBLIC_API_URL, and providers other than S3 and local are refused, as they already are for restores.
    • What to do:
      • Update every device that backs up to S3.
      • Switch MinIO and other S3-compatible endpoints to HTTPS. Keep the same host and port; only the scheme changes.
      • Make sure agents reach the API over HTTPS.
    • Unaffected: local and NAS destinations.
    • After the upgrade: open each Backup policy's Destination section and work through the storage key card. Replace each listed key with your provider, disable the old one, then use Check old key or I disabled this key.
    • The manage_backup_configs AI tool now accepts only the s3 and local providers.
  2. Remote desktop start fence on by default (#7564).
    • What it does. Remote desktop starts only on agents that report the session start fence, which is v0.114.0 and later. On an older agent the technician sees "Remote desktop needs an agent update on this device …" (503 agent_upgrade_required). Terminal and Files are unaffected.
    • Existing installs keep their current setting. The v0.119.0 .env.example contained REMOTE_DESKTOP_FENCE_REQUIRED=false, and the v0.119.0 docker-compose.yml passes ${REMOTE_DESKTOP_FENCE_REQUIRED:-false}, so an existing install keeps the fence off after the upgrade.
    • To turn it on, set REMOTE_DESKTOP_FENCE_REQUIRED=true in .env once every agent is on v0.114.0 or later, or remove the line and update your Compose file from this release.
    • New installs get it on.
    • Boot check. A value other than true/false, 1/0, yes/no or on/off now refuses boot.
  3. Default AI model changed to claude-sonnet-5-5 with adaptive thinking (#7593).
    • If AI runs through a LiteLLM or other gateway alias: Breeze now requests claude-sonnet-5-5 and sends thinking: {type: "adaptive"} with output_config.effort.
    • To keep working, do one of these:
      • Add an alias for claude-sonnet-5-5 and let the gateway accept or drop those parameters (LiteLLM drop_params).
      • Set ANTHROPIC_MODEL to your backend's model id. An unrecognised id is sent with thinking disabled, as before.
    • BREEZE_AI_SCRIPT_REVIEWER_MODEL defaults to the same model.
    • Existing chats keep their stored model.
  4. Consent prompt protocol 2. Update the server before agents (#7560, #7562).
    • Order. A server older than this release refuses consent- and notify-mode starts on updated agents with "update the agent". Upgrading the server first, then letting agents update, is the normal order.
    • Only devices whose remote access policy uses the consent prompt are affected, in three ways:
      • A signed-in user who cannot be shown the prompt is now always refused, whatever "If no one can respond" says. Causes include Breeze Assist not running and a native dialog failing. That setting still applies when nobody is signed in, and when a prompt the user could see went unanswered.
      • On macOS and Linux an unanswered prompt is refused, because only Windows reports the lock state reliably.
      • Update Breeze Assist along with the agent. An older Assist still handles Allow and Deny, but its unanswered prompts are refused.
    • Audit log. Consent events gain consentOutcome, consentOccupancy and consentProtocol, plus the reasons no_user_session and helper_unreachable.
  5. Breeze Assist on Windows is console-session only (#7556).
    • Credential handling. The agent delivers Assist's credential only over its local channel to the active console session, and no longer stores it in agent.yaml. Assist in an RDP or other non-console session shows that it has not received its credentials (#7542 tracks support).
    • On first start the agent moves any credential it finds in agent.yaml into its protected secrets file and rotates it once.
    • Unaffected: macOS and Linux.

WebSocket desktop fallback.

  • Start handshake. The session stays connecting until the agent confirms the stream started, which comes after the consent prompt when one applies.
  • New viewer error codes: CONSENT_DENIED, AGENT_START_FAILED, START_TIMEOUT, START_REFUSED and SESSION_ENDED.
  • Older agents. Agents v0.114.0–v0.119.x keep working on this transport.

Database.

  • 12 migrations. They are idempotent and apply automatically on boot via autoMigrate (unless AUTO_MIGRATE=false).
  • No large rewrites:
    • New tables: portal session revocations, backup storage key history, and the AI model registry tables (ai_platform_models, partner_ai_connections, partner_ai_models, ai_model_assignments, ai_invocations).
    • Small data writes: a seed of 10 platform models, one registry connection copied per partner AI provider config, and a model pin for partners on a provider-catalog endpoint with no model set.
  • ai_sessions gains three nullable columns. Its constraints are added without a scan, then validated with reads and writes allowed. Its index is built with CREATE INDEX CONCURRENTLY outside a transaction (2026-11-14-100600-ai-sessions-offering-idx.sql).
  • If that index build is interrupted, the next start refuses with "ai_sessions offering index build left INVALID index". Run DROP INDEX CONCURRENTLY public.ai_sessions_offering_idx; and restart the API.
  • First start after the upgrade. The API records the storage key each S3 destination uses, and builds the AI registry from your current AI settings. Both log one [startup] line.

Environment variables.

  • Required: no new required environment variables.
  • Changed default:
    • REMOTE_DESKTOP_FENCE_REQUIRED now defaults to true, and an unrecognised value refuses boot. See above for existing installs.
    • BREEZE_AI_SCRIPT_REVIEWER_MODEL now follows the new default model.
  • New, optional (mapped in both Compose files of this release):
    • AI_INVOCATIONS_RETENTION_DAYS, default 400.
    • AI_INVOCATIONS_RETENTION_BATCH_SIZE.
    • AI_INVOCATIONS_RETENTION_MAX_BATCHES.
  • Now passed to the API by Compose (#7641). These were previously ignored on Compose installs even when set in .env. All are optional; unset keeps today's behaviour.
    • AUDIT_ANCHOR_SIGNING_KEY: a base64 32-byte Ed25519 seed, openssl rand -base64 32. When set, the API logs the key id and public key at boot.
    • AUDIT_CHAIN_ANCHOR_ENABLED.
    • AUDIT_CHAIN_VERIFY_ENABLED, AUDIT_CHAIN_VERIFY_MODE and AUDIT_CHAIN_VERIFY_RESCAN_SLICES.
    • AUDIT_ADMIN_DATABASE_URL.
    • DEVICE_COMMAND_QUEUE_* (production Compose file).
  • If you keep your own docker-compose.yml, copy these api environment entries from this release's file. Setting them in .env alone has no effect unless Compose maps them.
  • HELPER_BINARY_DIR: when unset it now means the agent binaries directory (AGENT_BINARY_DIR). Both shipped Compose files set it explicitly (#7555).

Behaviour changes and flags.

  • Binary downloads (S3-backed binary hosting): backup, watchdog, user-helper and recovery-media downloads are served from the agent/ prefix, and the Breeze Assist installer is synced to helper/ at boot. The backup/, watchdog/, user-helper/ and recovery-iso/ prefixes are no longer read and can be deleted. No manual copy step is needed on upgrade (#7555).
  • AI model registry. It is visible to platform admins at /admin/ai-models. A daily discovery job (06:38 UTC) lists new Anthropic models for review using your platform key, and it is skipped when ANTHROPIC_BASE_URL points at a gateway. Routing, pricing and billing still come from the existing settings in this release.
  • No feature flag changes.

Agent release notes (0.120.0; agents and Breeze Assist update through the normal channel):

  • Backup helper: integrity protocol 2.
    • What it checks. The helper checks restores against the snapshot's integrity record, and installs a file only after it matches.
    • Windows. It refuses reserved Windows names and restricts unrecognised security descriptors. bmr_recover is files-only, with code system_state_requires_rebuild.
    • Linux. Package reinstall during bare-metal recovery validates package names.
  • Helper capability probe failures are reported as unknown, with retries.
  • Consent prompt protocol 2. This covers the agent, Breeze Assist and the native dialogs on Windows, Linux and macOS. One prompt runs at a time per user, and End withdraws a pending prompt.
  • WebSocket desktop stream. It keeps a revocation lease, shows the notify notice and indicator, and stops on stop_desktop.
  • Assist credential (Windows). It is delivered only over local IPC, removed from agent.yaml, and rotated once.
  • Registry hives are flushed before VSS snapshots.
  • service start (Windows) succeeds when the service is already running.

Full Changelog: v0.119.0...v0.120.0

What's Changed

Full Changelog: v0.119.0...v0.120.0