Breeze RMM v0.123.0: agents that get past ISP security filters, ticket types, and customer work approval. Also in this release: a remote viewer keyboard mode, EDR detections and response actions for framework vendors, workload host inventory, observed-location suggestions on the network map, Run Script on device groups, and Windows System Restore policy (server side).
⚠️ The Update Ring backfill can add rings, and it stops the upgrade on two conditions. 2026-12-26-230000-ring-app-rules-backfill.sql moves per-app block/pin rules from configuration-policy patch links onto Update Rings. To keep each policy's effective rules it may create rings named <policy> — app rules and clone rings named <ring> — <policy>. It aborts the migration if a rule it would move has a non-ASCII package id, or if a ring already carries different non-empty rules. Details under Database (#8186, #8655).
⚠️ Treat AGENT_ECH_ENABLED=false as a last resort. It is the server-wide off switch for the new agent Encrypted Client Hello. A device that can only reach the API over ECH (one behind an SNI-filtering ISP gateway) goes offline when it is set to false, and it cannot receive the setting back until it is on an unfiltered network (#8869, #8882, follow-up #8881).
⚠️ Compose now passes about 25 more variables to the API. A value already in your .env that Compose used to ignore now takes effect, including CF_ACCESS_TRUST_ENABLED, M365_ENABLED and the MCP_LLM_* group. A stale CF_ACCESS_TRUST_ENABLED=true without its team domain and AUD, or a malformed MCP_LLM_* value, refuses boot. Check .env for stale entries before upgrading (#8468, #8402).
Security — hardening
This release includes security hardening across:
- credential headers and credential query parameters, now redacted in every Caddy log (
docker/Caddyfile.prod); - Windows MSI downloads, verified against the signed release manifest on both
BINARY_SOURCE=githubandBINARY_SOURCE=local; - Network Proxy session revocation: closing a tunnel cancels its in-flight requests, and a ticket exchange that races Close gets no cookie;
- automation and script targets: unknown target types, foreign group ids and partner-wide group targets are refused instead of reaching every device in the org, and device filters refuse values outside an enum instead of widening the match;
- MCP device resolution and the trashed-ticket subject in ticket links;
- PAM elevation chains across device org moves and merges, and recovery of ledger entries after a failed apply;
- EDR credential changes that would move a connection to a different vendor console;
- OAuth token-endpoint error attribution, SSO re-auth failure logging (a nonce mismatch is now logged on its own), and the audit event for redeemed installer bootstrap tokens;
- recovery console codes, which must be re-entered after a refusal;
- dependency updates in the helper and viewer (
rustls,quinn-proto,serde_yaml).
Self-hosters are encouraged to upgrade. (#8826, #8527, #8458, #8632, #8981, #8802, #8749, #8514, #8552, #8554, #8646, #8753, #8676, #8902, #8652, #8830, #8974, #8454, #8470, #8824, #8559, #8494, #8899)
Summary
- Agents behind ISP security filters can connect (#8869, #8882, #8949). Some ISP gateway filters, CUJO-based ones such as Comcast xFi Advanced Security and Spectrum Security Shield, match the Breeze hostname in the TLS SNI and answer with a plaintext redirect. The agent then logs
tls: first record does not look like a TLS handshakeand never connects. With this release's agent, a device dials plain TLS as before. Only after it sees that filter twice in 10 minutes does it retry with the hostname encrypted (Encrypted Client Hello). Needs this release's agent, and a server whose DNS publishes an ECH config (see Upgrade Notes). - Ticket types and related tickets (#8654, #8682, #8708, #8675). Tickets are Incident, Service Request, Problem or Change, and each type has its own Service Desk entry. A Related tickets panel links tickets to each other, for example incidents to the problem behind them. The portal shows the type, and the AI ticket tool can set it and manage links.
- Customer work approval (#8537, #8555, #8562, #8574). Optional and off by default. Over-budget or after-hours time is held until the customer approves it in the portal, or a technician records their decision. Held time is never invoiced, drawn from a block or reported as billed.
- Remote viewer (#8635, #8553, #8543, #8523, #8547). Keyboard mode: Type what I see (default) or Physical keys (needs this release's agent), with IME and dead-key typing. Also view-only, block local input, screenshots, Fit or 100% scaling, a connection stats overlay, and per-device preferences.
- EDR provider framework (#8653, #8666, #8757). Detections from framework vendors appear in the incidents feed, on the Security page and on the device page, with coverage reporting so a partial sync never reads as "no threats". Response actions (isolate, release, scan) for GravityZone-managed endpoints are in the API and approval-gated AI, off per connection by default.
- Workload host inventory (#8417, #8545, #8519, #8548, #8558). With policy turned on, agents report Docker, Podman, Hyper-V and Proxmox workloads (containerd is detect-only). A container image that falls behind its public registry counts toward patch compliance and has its own monitor kind.
- Where a device actually is (#8433, #8589, #8659). The network map tells a device's assigned site apart from the network it is seen on, shows cross-site visitors, and suggests a site move when a device lives somewhere else. Breeze never moves a device by itself.
- Windows System Restore policy (#4609, #4751). A new System Protection policy tab sets when Breeze requests a restore point, and patch history, scripts and software deployments show the outcome. The agent side is not in this release; until it ships, every attempt reads Awaiting the device.
- Run Script on device groups (#8632, #8670, #8683). Run a script on saved device groups from the Run Script modal, from org-owned automations and from the AI
run_scripttool. Membership is resolved before approval and never truncated. - Trust Center, first release (#8776, #8780, #8783). Each organization gets a Trust Center tab that publishes a public, customer-authorized security-posture page built from Breeze telemetry, refreshed hourly, with documents and an embeddable badge. Publishing needs MFA. This release is the publishable page and editor; declared controls, gated documents, framework views and distribution options follow in later releases.
- Steadier under load (#8456, #8578, #8850, #8851, #8842). Agent admission control, observe-only by default. Cross-instance cache invalidation, agent request bodies received before a database connection is held, agent sockets that stay open when the database can't answer, and Prometheus alerts for API saturation.
Added
- Encrypted Client Hello for agent control-plane TLS. Any ECH failure falls back to plain TLS inside the same dial, and repeated failures put the host in a one-hour cooldown.
enroll,bootstrapandsupportretry with ECH on the first filter signature, so installs work on a filtered network. A device opts out withech: falseinagent.yaml. The device'scontrol_planehealth component reports the filter (#8869, #8882, #8949). - Ticket types:
tickets.ticket_type(defaultincident; planned work defaults toservice_request), a?ticketType=list filter, a type chip and selector in the queue and workbench, Service Desk nav entries per type, and the field on the Partner API and Office add-in (additive) (#8654, #8682). Ticket links with link types, cycle and duplicate rules, and a per-ticket cap (#8675, #8682). The portal shows the type as a label; customers cannot choose it (#8708). - Customer work approval: ticket budgets, after-hours work types, an approvals panel and Record decision dialog for staff, a portal Approvals page for billing contacts with a pending-count badge, customer emails through three new partner-editable templates, and
APPROVAL_REQUIREDhandling in the Outlook add-in, mobile app and AI tool (#8537, #8555, #8562, #8574). - Remote viewer W05/W06: keyboard mode and IME composition, Keyboard Lock in fullscreen, view-only, block local input, screenshot copy/save, Fit / 100% scaling, stats overlay, per-device preferences. On macOS, Cmd+H/M/W reach the remote, and Cmd+Q asks first while sessions are open (#8635, #8553). The agent gains a reliable input channel and wider key and pointer coverage: scancodes, extended keys, back/forward, horizontal wheel and lock-key sync (#8543, #8523, #8547).
- EDR provider framework: an EDR providers sub-tab under Integrations → Security for connections, tenant mapping and unlinked endpoints. A third Security tab lists detections, with "Promote to incident". A read-only device section, read-only AI tools (
get_edr_status,list_edr_detections), alerts for linked detections, and 180-day retention for closed detections. Customer portal toggleenableEdrVisibility(#8653, #8666). Response actions throughdispatchEdrActionand approval-gated AI action tools (#8757). - Workload host inventory: a Workloads device tab, a
workload_inventorypolicy tab, fleet filtershostsWorkloadsandworkloadRuntimes, and the AI toolquery_device_workloads. Image currency is checked against public registries every 30 minutes. A newcontainer_image_currencymonitor kind and a built-incontainer_image_out_of_datemonitor are added to each partner, not attached to any policy (#8417, #8545, #8519, #8548, #8558). - Topology site location: declared vs undeclared networks, an "Other / unidentified networks" roster, visitor tiles, daily presence summaries, wrong-site move suggestions, and Keep at confirmation. Moves are guarded against concurrent edits (409
device_site_changed) and audited asdevice.site_move(#8433, #8589, #8659). - System Protection policy tab (also on partner-wide "All orgs" policies), a per-device restore-point attempts ledger, outcome badges, and a System Restore tab on Windows devices (#4609, #4751, #8546, #8551, #8557, #8561, #8572).
- Device-group targets for Run Script (
target: { type: 'groups', groupIds }, 1–100 groups, at most 500 resolved devices), org-owned automations, and the AIrun_scripttool (groupId; at most 10 devices) (#8632, #8670, #8683). - Trust Center (#8776, #8780, #8783). An organization's Trust Center tab publishes a public, customer-authorized security posture page at
/portal/trust/<partner>/<org>, built from Breeze telemetry, with an hourly refresh, documents and a badge snippet. Publishing needs MFA. - Invoice labor detail: a partner setting under Billing settings → Documents for per-entry or per-day itemization, work date, note and worked time, with a per-draft override that is frozen at issue. Refresh from time entries on draft invoices, the work date sent to accounting sync, and an AI
update_time_entryaction (#8627, #8650, #8669, #8684, #8709). - Block hours:
hour_blockcontract lines with a live period balance and period history. A customer portal Support hours card sits behind its own toggle, which Enable all does not turn on. Threshold alerts (#8438, #8517). - Watchdog install retry: an agent whose watchdog could not be installed now installs it itself, with bounded, persisted retries.
breeze-agent service installgains--watchdog(clear the opt-out) and--strict-watchdog(exit78on a watchdog failure), and printsBREEZE_WATCHDOG_INSTALL=deferred reason=<class>when it defers. The device Info tab shows a banner when the agent gives up (#8647, #8667, #8685). - Log-shipping health: a log-shipping line on device detail, the
logShippingFailingfleet filter and quick-filter chip, a stats count, and a "No logs received since the log level was raised" check (#8628, #8644, #8662, #8681, #8707). - Connection health: when Breeze auto-revokes an OAuth grant after refresh-token reuse and the app never re-authorizes, the grant's owner and the partner's connected-app admins get an in-app notice within about 15 minutes. The notice clears itself once the app is re-authorized (#8871).
- Heartbeat retain-state: agents that support it keep their current PAM, helper and remote-management state on a beat where the server could not decide that feature, instead of being sent "off" (#8645, #8660).
- Customer portal read APIs behind new sensitive toggles, off by default and not set by Enable all: patch detail (
enablePatchDetail) and vulnerability detail (enableVulnerabilityDetail). There are no portal pages for them yet (#8544, #8550). - Patching: custom restart-prompt title, message (with
{{countdown}}) and button label per patch policy (#8440). Per-app approval rules now live on the Update Ring: the ring form gains an Application rules section, and the policy Patch tab points to the ring (#8655, #8674). - Discovery: pin a profile's scans to one agent; unpinned selection prefers agents on the profile's subnets (#8422).
- Vulnerabilities: the By-software table shows the version to update to (#8481).
- Operator recipe library: one four-eyes approval authorizes an ordered, digest-pinned set of provider effects (#8542).
- Smaller additions: acknowledge, resolve and suppress from a device's alert history (#8452); a per-script latest-result view on the device Scripts tab (#8424); a staff-invite email template with partner overrides (#8426); responsible contacts on site and device pages (#8785); service principal scope presets with per-scope descriptions (#8524); an AI fleet device stats tool (#8525); Information-level
MsiInstallerevents collected on Windows, matchable byevent_logrules at levelinfo(#8431); DNS servers per adapter in IP history (#8425); native ZFS encryption detection on Linux (#8419); more RMM and remote-access signatures in Management Posture (OpenFrame, SimpleHelp, MeshCentral, TightVNC, RealVNC, UltraVNC, Splashtop) (#8513); typed error codes on agent command results (#8473); the session clipboard policy on VNC tunnel responses (#8414). - Mobile app: arrival suggestions to start a timer at a pinned client site, foreground only. Off unless the partner enables Location suggestions and the technician opts in. Ships with the next mobile app build (#8416).
- Groundwork, not yet usable from the UI: ticket migration windows and the import writer for the coming ticket importers (#8486, #8782, #8884, #8779); caller verification, dark behind
CALLER_VERIFICATION_ENABLED(#8560, #8576, #8657); one-way endpoint messages, hidden behindPUBLIC_ENABLE_ENDPOINT_MESSAGING(#8752, #8983); the security agents policy type, with nothing enableable yet (#8754); Network Proxy dedicated tunnel origin, off by default (#8458); the service catalog tables (#8784); the backup destination key root, with no change to existing data (#8756).
Improved
- Database work under load: agent request bodies are received in full before the org database context opens, so a stalled upload no longer holds a pooled connection; it gets 408 (#8850). Agent WebSocket credential re-checks keep the socket open for up to 120 s when the database cannot answer, instead of closing hundreds of healthy sockets with
4001at once (#8851). - Agent admission control in observe mode: under event-loop or database pressure it counts the low-priority agent telemetry and WebSocket upgrades it would refuse (
breeze_admission_*metrics) (#8456). - Several API instances: a write on one instance now drops the matching hot-path cache entry on every instance within about a second through Redis pub/sub, instead of waiting out the 60 s / 5 min TTL (#8578).
- Monitoring: Prometheus alert rules for database pool waiters, acquire timeouts, event-loop lag and admission shedding in
monitoring/rules/breeze-rules.yml(#8842); a capacity KPI dashboard and perf-gate tooling (#8588). - Nightly audit-chain verification uses the org indexes; on large installs it ran for hours (#8536). Metric anomaly detection no longer times out on stale partition statistics (#8539).
- Backup: snapshot browsing loads one directory at a time with paging (#8245), and snapshot files upload through a bounded worker pool (#8421). Bare-metal recovery readiness now uses real rebuild results (#8516).
- PAM ownership epochs: elevation requests and actuations are anchored to the device's ownership epoch. Device org moves and merges keep the PAM chain correct (#8514, #8552, #8554, #8646, #8753).
- LLM egress audit: raw rows older than 90 days fold into per-org daily rollups (#8664).
- Topology: unbound stub nodes (LLDP/CDP/MAC endpoints) age out after 30 days without activity (#8465). Decommissioned devices are hidden (#8450).
- Session Timeout goes up to 12 hours at partner and org level, with a pointer from the Users page (#8497).
- Tier-1 indexes for discovery jobs, organization users and the automation sweep (#8476). UniFi collectors are no longer polled every 30 s when none are assigned (#8412).
Fixed
- Remote desktop stuck on "Connecting" after a double offer between the viewer and the API (#8948).
- Dynamic groups re-evaluate when a device's tags or custom fields change; before, they stayed stale until someone re-saved the group. The rule builder now offers custom fields (#8903, #8887).
- Device filters: the device-group filter, tag "has any / has all" and one-item selections no longer return 500 (#8773). Tag-targeted compliance policies evaluate again, observe-only (#8895).
- Agents on Windows: a fallback when Windows cannot rename
agent.state(including pre-1607 builds) (#8859, #8886, #8717); UTF-16 PowerShell stderr in time sync errors decodes (#8829); self-written.ps1temp files get a BOM (#8460). - Agents on Linux and macOS: the Linux legacy-helper cleanup no longer deletes the current helper (#8556). The macOS
.pkgenrolls and updates with the agent it installed (#8781). Breeze Assist on macOS is menu-bar only, and Cmd+Q hides it instead of quitting (#8564). Assist keeps supplementary groups when spawned (#8563). - Agent logs with NUL bytes no longer fail the whole insert (#8825). A failed identity restart-marker write is retried (#8777, #8384).
- SSO re-auth with Microsoft Entra accepts Entra's already-expired re-auth id_token (within 5 minutes), and failures stay on the profile page (#8974).
- Patching: scheduled patch runs honour the assignment's role filter (#8461); the compliance view counts failed installs as failed, not pending approval (#8480).
- DNS filtering: domains left unsynced by an earlier release reach the provider on that policy's next sync (#8447).
- Microsoft 365: the actions manifest uses application permission IDs (#8651); Retest keeps the stored manifest version (#8750); mailbox poll failures are surfaced (#8400).
- Devices: the search box matches the last logged-in user (#8720); a held reboot is shown, and an operator can mark a stuck command failed (#8508); at most one secondary status pill per row (#8521).
- AI:
network_discoverysends the subnets and methods the agent reads (#8801); agent runs on the fallback provider record failover provenance (#8463); action-intent delivery retries with backoff (#8459); a hand-added model can be removed (#8515). - Billing: catalog items can be recurring, so quotes price monthly services correctly (#8722).
- Policies: partner users with several orgs can create org-owned peripheral policies (#8721); a value typed into a policy number field before it mounts is kept (#8892); a partner-owned policy's Monitors tab lists only attachable monitors (#8435).
- Automations: the on-failure notification is sent once across replays (#8462);
script.completed/script.failedfire after commit (#8420). - Smaller fixes: clearing all exit-code severity rows persists (#8626); monitor conversion preview and refresh (#8531, #8477); a failed security collection stores provider
unknown(#8565); one filesystem analysis scan at a time per device, and auto scans honour the remote-tools policy (#8518, #8522); human alert resolves recordmanual(#8530); the audit log export honours the list filters (#8436); the org switcher refreshes after a rename or archive (#8428, #8439); settings search uses the settings registry (#8437); vault commands reach the backup helper (#8413);ticket.status_changedfires when assignment moves a ticket new→open (#8430); sync workers' final-attempt check (#8427); org moves re-point time entry sites (#8444); device placement conflicts return 409 (#8453); Network Proxy "Open In New Tab" (#8408); the watchdog-install banner survives restarts (#8686); the Breeze User-Agent on software installer downloads (#8712);pnpm devon Linux/WSL (#8723); missing device idle translations (#8395). - From the pre-release sweep (#8981): the sidebar ticket-type entries re-filter the queue in place; "Verify caller" in the split view; portal approvals show the customer-facing ticket number, and the after-hours window in the viewer's time zone; Run Script keeps a partial-admission result on screen; Workloads policy-tab copy; the watchdog banner command renders as code; the block-hours period history loads; EDR sync interval bounds match the database (5–1440) instead of returning 500; the service principal create dialog scrolls.
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:…, everyguided-setup.shinstall from v0.112.0): fetch the currentguided-setup.shfrommain, then runbash guided-setup.sh --upgrade 0.123.0. It verifies the signed image inventory, updatesBREEZE_VERSIONand all four image digests, then pulls and restarts. - Tag-form (value ends in
:${BREEZE_VERSION}): setBREEZE_VERSION=0.123.0, then rundocker compose pull api web portal && docker compose up -d(andpnpm installif you build from source). - Do not edit only
BREEZE_VERSIONon a digest-pinned install. It re-pulls the images you already run. --upgradedoes not change yourdocker-compose.yml. To set any of this release's new optional variables, add their lines to theapiservice'senvironment:block (or take the v0.123.0docker-compose.yml/deploy/docker-compose.prod.yml, which already map them). A value only in.envdoes not reach the API.- See the Upgrade Guide.
No breaking changes for a stock install. No default was flipped for existing installs. Four changes are stricter than before and can surface on an install with pre-existing bad data or a custom setup, so read them before upgrading:
- The Update Ring app-rules backfill stops the API from booting if a rule it would move has a non-ASCII package id or a ring already carries different non-empty rules (details under Database).
- A patch policy linked to an invalid or cross-partner Update Ring now denies every patch instead of falling through (#8655).
- Windows MSI downloads on
BINARY_SOURCE=localwithout a staged signed manifest, or on any install withoutRELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS, now return 503 instead of an unverified file (#8527). - A device filter value outside its enum (for example
osType notEquals "Windows") now fails with 400 instead of being dropped, so a stored script target or dynamic group rule with a bad value fails visibly rather than widening to every device (#8981).
Behaviour changes and feature flags.
- Agent admission control ships observe-only (#8147, #8456).
BREEZE_ADMISSION_MODE(off | observe | enforce) defaults toobserve; an empty value meansobserve, and an invalid one falls back to it with a startup warning. Both Compose files pass it as${BREEZE_ADMISSION_MODE:-}, so a stock deploy only measures and counts. Nothing is refused until you setenforce. Then low-priority agent telemetry gets 503 +Retry-Afterand agent WebSocket upgrades are paced. Heartbeats and recovery traffic are never refused. The tuning knobs are documented, commented out, in.env.example. - Agent Encrypted Client Hello (#8869, #8882).
AGENT_ECH_ENABLEDdefaults totrueand reaches agents asconfigUpdate.ech_enabled. Setting it tofalseis a last resort, never a casual flip: live connections stay up, but the next dial is plain, so every device that can only connect over ECH goes offline and cannot receive the restore until it is on an unfiltered network (#8881 tracks an expiring off switch). ECH engages only when your API hostname's DNS publishes anech=HTTPS record (for example a Cloudflare-proxied hostname). A self-hosted edge without one never engages ECH; the agent stays plain and the device'scontrol_planehealth component reports the filter. Not covered: HTTP-proxied agent connections, and theinstall.sh/ PowerShell installer downloads (#8874). - Heartbeat retain-state (#8616).
HEARTBEAT_RETAIN_STATE_ENABLEDdefaults totrue.falsesends every agent the legacy heartbeat payload, as an older API would. - Endpoint messaging is hidden (#8752, #8983). The three Send message entry points (Devices bulk action, organization header, site header) sit behind the web build-time flag
PUBLIC_ENABLE_ENDPOINT_MESSAGING, default off. The published web image is built with it off. The server side also needs a per-device rollout flag (endpointMessaging.enabled, default off). Theendpoint_messages:sendandendpoint_messages:readpermissions are granted on upgrade to Org Admin, Org Technician and Partner Technician. - Caller verification is dark (#6356, #6357, #6358). Every route answers 404 and every web surface is hidden unless
CALLER_VERIFICATION_ENABLED=true(defaultfalse, already mapped in both Compose files). Enforcement is not in this release. - EDR response actions (#8757).
edr_connections.actions_enableddefaults to off for every connection, and only a partner admin with MFA can turn it on (API only in this release).BREEZE_EDR_ACTIONS_ENABLED(defaulttrue) is the server-wide off switch. - Off by default: customer work approval, workload inventory enumeration (
workload_inventory.enabled, plushyperv_enabled/proxmox_enabled), the portal togglesenableEdrVisibility,enableHourBlock,enablePatchDetailandenableVulnerabilityDetail(onlyenableEdrVisibilityis included in Enable all), the Network Proxy dedicated tunnel origin (TUNNEL_ORIGIN_TEMPLATEunset = path mode), and mobile Location suggestions. - Update Ring approval rules (#8186, #8655, #8674). Per-app rules now come from the linked Update Ring only. A policy that links an invalid or cross-partner ring now fails closed: every patch candidate is denied with
ring_reference_invalid, and the Patch tab offers a repair prompt. A policy with no ring and a manual approval stays approved. Saving a changedappslist, or a newly setautoApprove: true, on a policy patch link returns 400APPROVAL_RULES_MOVED_TO_RING; reload a stale tab. - Device filters refuse out-of-enum values (#8981). A filter value outside a database enum now returns 400, naming the allowed set, instead of being dropped. Before,
notEquals "Windows"could widen a target to every device. A stored deployment target or dynamic group with such a value now fails visibly. - Automation targets are validated (#8632). Create and update reject an unknown target
type, empty group or device lists, and ids from another org. Partner-wide automations rejectgroupsanddevicestargets. A stored broken target makes the runfailedwith the reason in its log, instead of falling through to every device in the org. - Windows MSI downloads are verified on every binary source (#8527). With
BINARY_SOURCE=local, the MSI is checked against the signed manifest pair at the binaries volume root andRELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS. A volume with no staged manifest pair, a manifest older than v0.105.0, or noRELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYSnow gets503 MSI not availableon Windows installer downloads.BINARY_SOURCE=githubwithout a manifest key also refuses instead of serving an unverified MSI. - Patch compliance counts out-of-date container images (#8558). This applies only on devices with workload inventory on: a stale image counts as pending, a current one as installed, and unchecked images never count. Severity, source and ring views exclude the term.
- Tag-targeted compliance policies evaluate, observe-only (#8895). They write compliance rows but dispatch no remediation and publish no
policy.*events, and their stale alerts close. - DNS filtering (#8447). Domains left unsynced by an earlier release now reach the provider on that policy's next sync; you no longer need to remove and re-add them. Duplicate-add behaviour is verified only for AdGuard Home.
- Security & Compliance Posture report (#8776). Coverage percentages now use assessed devices as the denominator, decommissioned devices are excluded, the PDF prints
· N not assessed, and a control shows grey when more than 20% of the fleet was not assessed. Expect larger not-assessed counts on fleets with offline devices. - Breeze Viewer (#8635). In the default Type what I see mode the viewer no longer sends physical key codes; the remote resolves keys through its own layout. Choose Physical keys for numpad and right-modifier distinctions. The choice is saved per device and becomes the default for devices without one.
- Session Timeout (#8497). Writes above 720 minutes (12 h) are rejected, and a stored value above 720 reads as 720.
- API contract changes:
GET /backup/snapshots/:id/browsereturns one directory level per request (dir,limit,cursor; entries no longer carrychildren) (#8245).POST /tunnels/:id/http-ticketreturns{ ticket, url, mode }and rejects amodeother thanframeortab. A request carryingx-breeze-tunnel-sitegets 421 unless it is for a tunnel host with the dedicated origin on (#8458). Agent request bodies that stall get 408 (#8850). breeze-agent enroll --site-idis deprecated and ignored; the site comes from the enrollment key. Scripts that pass it keep working and print a warning (#8492).- Self-hosted
docker/Caddyfile.prodcopies: a new globallog default { format filter { … } }block redacts credential headers and query parameters in every Caddy log. Carry it over if you maintain your own copy (#8826). - Trust Center needs no configuration and no ingress change: pages use the existing
/portalrule. If your proxy stripsX-Forwarded-Proto/X-Forwarded-Host(Caddy forwards them by default), canonical URLs fall back to the internal origin (#8783). - Built-in monitors: each partner gains
container_image_out_of_date(low severity, not attached to any policy). A deleted copy is not recreated (#8558).
Database.
- 51 migrations (idempotent; applied automatically on boot via
autoMigrateunlessAUTO_MIGRATE=false). Expect[auto-migrate] Applied 51 migration(s). None modified or removed. - Update Ring backfill (
2026-12-26-230000-ring-app-rules-backfill.sql, #8186). A data migration, not just a normalisation. It moves per-app rules fromconfig_policy_feature_links.inline_settings->'apps'ontopatch_policies.app_rules, normalised the way the runtime does.- A ring-less link that carries rules gets a new ring named
<policy> — app rules, which approves nothing. - Where the policies sharing one ring disagree, the ring keeps one set, and each other set gets a clone named
<ring> — <policy>with that ring's patch approvals copied. These rings appear in the Update Rings list. - Links to an invalid ring are skipped and counted; those policies now fail closed (
ring_reference_invalid). - It aborts the migration, and the API does not boot, if a rule it would move has a non-ASCII package id, or if a ring already carries different non-empty rules. Check the API start log for
ring_app_rules_backfill <metric>=<n>lines. - Policy-level auto-approve is not converted. When it relinks links, it briefly locks the affected partners and their orgs.
- A ring-less link that carries rules gets a new ring named
- PAM org-move trigger (
2026-12-27-170000, #8746). Adds aSECURITY DEFINERfunction and anAFTER UPDATE OF org_id ON devicestrigger that restamps only un-actuated elevation requests, and removeselevation_requestsfrom the generic device-child cascade. Fixes org moves that aborted with 42501. - Other backfills over existing rows:
2026-12-23-150000-pam-chain-epoch-anchor.sql(#8514) setsdevice_epochon existingelevation_requestsandpam_actuations, then validates three foreign keys (a scan of those tables).2026-12-27-070000-invoice-line-description-edited.sql(#8606) addsinvoice_lines.description_editedand, on first application, marks every time-entry line on a draft invoice as edited, so Refresh from time entries never overwrites a description that existed before the upgrade. Issued and void invoices are untouched.2026-12-27-190000-endpoint-messaging-permissions.sql(#8741) seedsendpoint_messages:send/:readand grants them to Org Admin, Org Technician and Partner Technician.
- Concurrent index builds on
discovery_jobsandorganization_users(#8476),tickets,ticket_commentsandticket_external_refs(#8486, #8654), anddevice_commands(#8707). Each waits for long-running transactions and does not block writes. If one of thediscovery_jobs,organization_usersor ticket builds is interrupted, the next start refuses with an "INVALID index" message naming the index: runDROP INDEX CONCURRENTLY <name>;and restart. Thedevice_commandsbuild has no such check: after an interrupted start, checkidx_device_commands_set_log_level_device_completedforindisvalid = falseand drop it if so. metric_rollupspartitions get tighter autovacuum-analyze settings (ALTER TABLE … SET, SHARE UPDATE EXCLUSIVE, does not block reads or writes) (#8539). The audit-chain verify functions are replaced in place (#8536).- Mostly additive DDL: new tables for restore-point attempts, operator plan approvals, caller verification links, migration windows, topology presence and presence days, ticket links, LLM egress rollups, connection health incidents, EDR actions, trust pages, the service catalog and org evidence holds. New columns on
devices,tickets,invoice_lines,invoices,partners,portal_branding,discovery_profiles,software_policiesand backup tables. No migration adds aNOT NULLcolumn without a constant default or runsSET NOT NULLon an existing column. - One-way enum additions (Postgres cannot drop an enum value):
config_feature_typesystem_protectionandsecurity_agents,security_providerunknown,monitor_kindcontainer_image_currency,notification_typeintegration, and thetickets.ticket_typeenum.
Environment variables.
- Required: none. No new required environment variables. Two new variables are validated strictly:
AGENT_ECH_ENABLEDandHEARTBEAT_RETAIN_STATE_ENABLEDaccept onlytrueorfalse, and any other value refuses boot. A malformedTUNNEL_ORIGIN_TEMPLATE, or one that shares a registrable domain with an app origin, also refuses boot. - New, optional (mapped in the
apienvironment of both shipped Compose files unless noted; with a custom Compose file, add them to theapiservice'senvironment:block):AGENT_ECH_ENABLED(defaulttrue) (#8869).HEARTBEAT_RETAIN_STATE_ENABLED(defaulttrue) (#8616).BREEZE_ADMISSION_MODE(defaultobserve), plusBREEZE_ADMISSION_LAG_MS,_DB_WAIT_MS,_EMERGENCY_MS,_BULK_MAX_IN_FLIGHT,_WS_RATE_PER_SEC,_WS_BURST,_WS_MAX_SETUPS(#8456).AGENT_BODY_RECEIVE_TIMEOUT_MS(default 15000) andAGENT_BODY_RECEIVE_TOTAL_TIMEOUT_MS(default 60000) (#8850).BREEZE_EDR_ACTIONS_ENABLED(defaulttrue) (#8757).LLM_EGRESS_EVENTS_RETENTION_DAYS(default 90, max 3650),LLM_EGRESS_EVENTS_RETENTION_BATCH_SIZE(5000),LLM_EGRESS_EVENTS_RETENTION_MAX_BATCHES(200) (#8664).TUNNEL_ORIGIN_TEMPLATEandTUNNEL_FRAME_ANCESTOR(unset = path mode) (#8458).MIGRATION_WINDOW_MAX_DAYS(14),MIGRATION_WINDOW_DEFAULT_WRITES_PER_HOUR(6000),MIGRATION_WINDOW_MAX_WRITES_PER_HOUR(20000) (#8486). Mapped in the rootdocker-compose.ymlonly, not yet indeploy/docker-compose.prod.yml; add them there if you need them.- Web, build time:
PUBLIC_ENABLE_ENDPOINT_MESSAGING(default off). It only takes effect in a web image you build yourself (#8983).
- Newly passed to the API by Compose (#8468), each as
${VAR:-}, so unset keeps the built-in default:CF_ACCESS_TRUST_ENABLED,CF_ACCESS_TEAM_DOMAIN,CF_ACCESS_AUD,CF_ACCESS_TRUSTS_MFA,CSP_REPORT_URI,EMAIL_SUPPORT_ADDRESS,GOOGLE_WORKSPACE_ENABLED,M365_ENABLED,HP_WARRANTY_ENABLED,IP_CLASSIFY_PROVIDER,IP_CLASSIFY_API_KEY,MCP_LLM_PROVIDER,MCP_LLM_BASE_URL,MCP_LLM_MODEL,MCP_LLM_API_KEY,MCP_LLM_PRICE_INPUT_PER_M_USD,MCP_LLM_PRICE_OUTPUT_PER_M_USD,NVD_API_KEY,PARTNER_MEETING_URL,PARTNER_TRUST_MODE,SENTRY_PROFILES_SAMPLE_RATE,STRIPE_ACCOUNT_CACHE_REFRESH_ENABLED. The rootdocker-compose.ymlalso gainsAPPLE_APP_ATTEST_APP_ID,APPLE_APP_ATTEST_ENVIRONMENTandPARTNER_HOOKS_URL(deploy/docker-compose.prod.ymlalready mapped them). Both files gainMETRIC_ANOMALY_EPISODE_MIN_BUCKETS, anddeploy/docker-compose.prod.ymlgains the fourPARTNER_API_*variables from v0.122.1 (#8402). A value already in your.envthat Compose used to ignore now takes effect. Check.envfor stale entries, especiallyCF_ACCESS_*andMCP_LLM_*, before upgrading. (PARTNER_TRUST_MODEhas no effect unlessIS_HOSTED=true.)
Agents. Agents, Breeze Assist and Breeze Viewer update to 0.123.0 through your normal update channel. Agent-side changes: Encrypted Client Hello (#8882, #8949); heartbeat retain-state (#8645); watchdog install retry and the new service install flags (#8647, #8685); workload inventory collectors, off until policy enables them (#8417, #8545); reliable remote input and wider key coverage (#8523, #8547); caller verification and endpoint message cards, dark (#8657, #8752); Information-level MsiInstaller events (#8431); DNS servers per adapter (#8425); ZFS encryption (#8419); more Management Posture signatures (#8513); typed command error codes (#8473); and the Windows, Linux and macOS fixes above. System Protection checkpoint creation is not in this agent; it ships with a later agent release.
Known gaps in this release
- Workload inventory: a locally built image is misclassified on Docker 29 with the containerd image store (#8993). The store gives a local build a repo digest, so the collector records one, the image-currency worker asks Docker Hub about it (401), and the Workloads tab shows "Not checked / private registry" instead of "Local build". The effect is a wrong status, an inflated "not checked" compliance count, and a lookup of the local image name against Docker Hub. Docker with the classic overlay2 image store is unaffected. Fix in the next release.
- PAM, pre-existing, confirmed on the Windows Server 2022 lab rig: after a server-approved elevation launches the app, the user's original UAC credential prompt stays open (#8995); on an RDS session host the on-demand helper lifecycle leaves no SYSTEM helper, so elevation never completes unless
helper_lifecycle_mode: always-onis set inagent.yaml(#8996). Both predate this release. - Heartbeat, pre-existing: a failed remote-access policy read inside the heartbeat transaction returns 500 for every agent until the read succeeds again (#8997, since #8053). It needs a database fault to trigger; it also blocks the remote-management part of the retain-state signal from being exercised.
- Caller verification, behind
CALLER_VERIFICATION_ENABLED: on a deployment with no email transport, a rejected workstation verification is retried every 5 s indefinitely (#8998). Leave the flag off, as shipped, or configure email before enabling it. - Not verified on real hardware before the tag: the viewer keyboard-mode and reliable-input rows (#8635, #8553, #8543, #8523, #8547), the Assist tray rows (#8563, #8564), and the installer rows (#8781 macOS pkg, #8527 MSI manifest), which need this release's signed artifacts. They are checked during rollout.
- System Restore outcomes stay at "Awaiting the device" until an agent release that supports System Protection ships. Only Windows 11 25H2 and Server 2022 are verified so far; Windows 10 and Server 2025 are tracked in #8265.
- ECH on the real ISP gateways (Comcast xFi, Spectrum Security Shield) can only be confirmed on a blocked PC after release. ECH does not cover HTTP-proxied connections or the installer script downloads (#8874).
- EDR response actions have no web switch yet. A connection's
actions_enabledis set through the API.
Full Changelog: v0.122.1...v0.123.0
What's Changed
- docs(release): clear the next-release draft after v0.122.1 by @ToddHebebrand in #8401
- fix(web): What's New 0.122 entry says the portal hardware/performance toggles are API-only by @ToddHebebrand in #8403
- docs(plan): network proxy tunnel origin — per-partner opt-in, local W00 (#8155) by @ToddHebebrand in #8409
- fix(web): network proxy "Open In New Tab" mints its own ticket by @ToddHebebrand in #8408
- fix(ai): suggested-fixes research honours ?orgId and shows an explicit error state (#7940, #7941) by @ToddHebebrand in #8410
- docs(spec): network proxy tunnel origin — W00 spike results (#8156) by @ToddHebebrand in #8418
- perf(agent): stop polling unifi-collectors every 30s when none are assigned (#7970) by @ToddHebebrand in #8412
- ci(security): fail closed when Go pin check or govulncheck wrapper checks nothing (#8283) by @ToddHebebrand in #8411
- feat(api): return the session clipboard policy with VNC tunnel responses (#8269) by @ToddHebebrand in #8414
- feat(agent): detect native ZFS encryption on Linux (#7460) by @ToddHebebrand in #8419
- fix(automations): emit script.completed/script.failed after commit (#7277) by @ToddHebebrand in #8420
- feat(web): per-script latest-result view on the device Scripts tab (#7413) by @ToddHebebrand in #8424
- fix(ai): fix-memory erasure and retry follow-ups (#7278) by @ToddHebebrand in #8423
- feat(agent): report DNS servers per adapter in IP history (#5803) by @ToddHebebrand in #8425
- feat(email): staff-invite email template with partner overrides and branding (#7468) by @ToddHebebrand in #8426
- fix(jobs): correct the final-attempt check in three sync workers (#8351) by @ToddHebebrand in #8427
- fix(web): refresh the header org switcher after org rename or archive (#8371) by @ToddHebebrand in #8428
- fix(tickets): write ticket.status_changed when assignment moves a ticket new→open (#8367) by @ToddHebebrand in #8430
- feat(agent): collect Information-level Application events from an allowlisted provider set (#8174) by @ToddHebebrand in #8431
- fix(backup): route vault_* commands to the backup helper; fix Vault tab UI (#8385) by @ToddHebebrand in #8413
- fix(web): partner-owned policy Monitors tab lists only attachable monitors (#8372) by @ToddHebebrand in #8435
- ci: run the packages/shared vitest suite and gate CI Success on it (#8373) by @ToddHebebrand in #8432
- fix(search): settings search results come from the settings page registry (#8365) by @ToddHebebrand in #8437
- fix(audit): audit log export honours the list filters (#8366) by @ToddHebebrand in #8436
- fix(web): keep history.state on replaceState so org switch no longer throws (#8331) by @ToddHebebrand in #8439
- test(ai): fix-memory coverage follow-ups (#7280) by @ToddHebebrand in #8441
- fix(tenancy): org moves re-point time_entries.site_id (#8356) by @ToddHebebrand in #8444
- test(web): make TopologyExplorer tests reliable under CI load (#8360) by @ToddHebebrand in #8446
- test(agent): sessionbroker lifecycle test bound derives from grace period (#8353) by @ToddHebebrand in #8448
- feat(patching): custom restart-prompt text per patch policy (#8030) by @ToddHebebrand in #8440
- fix(service-principals): show owner and gate owner-only actions in the UI (#8368) by @ToddHebebrand in #8445
- perf(backup): upload snapshot files through a bounded worker pool (#8381) by @ToddHebebrand in #8421
- fix(dns): reconcile policies left pending before #8337 (#8404) by @ToddHebebrand in #8447
- feat(web): ack/resolve/suppress from device alert history (#8137) by @ToddHebebrand in #8452
- test(migrations): widen the deferred-trigger/DDL guard (#8397) by @ToddHebebrand in #8451
- fix(api): device placement follow-ups — 409 on conflict, audit rows, integration tests (#8359) by @ToddHebebrand in #8453
- fix(installer): audit installer.bootstrap_redeemed (#7973) by @ToddHebebrand in #8454
- test(web): make DeviceReliabilityPanel tests deterministic in CI (#8429) by @ToddHebebrand in #8455
- fix(topology): hide decommissioned devices, distinguishable rows, POST the health poll ids (#8307) by @ToddHebebrand in #8450
- fix(agent): self-written .ps1 temp files get a BOM; strip a leading BOM for bash/python (#3581) by @ToddHebebrand in #8460
- fix(ai): action-intent outbox delivery retries with backoff (#4156) by @ToddHebebrand in #8459
- fix(ci): migration immutability check tolerates registry rows for not-yet-created tags (#8132) by @ToddHebebrand in #8457
- fix(ai): agent runs started on the fallback record failover provenance (#7787) by @ToddHebebrand in #8463
- docs: fix agent install flags, config file name, enrollment key siteId note (#7578) by @ToddHebebrand in #8471
- feat(discovery): pin scheduled discovery to an agent; subnet-aware agent selection (#7969) by @ToddHebebrand in #8422
- fix(monitoring): device summary ignores results for watches removed from the policy (#8287) by @ToddHebebrand in #8443
- refactor(helper): one shared error-string helper with tests (#2638) by @ToddHebebrand in #8479
- fix(agent): recovery console requires a new code after a refusal (#7927) by @ToddHebebrand in #8470
- perf(db): Tier-1 indexes for discovery_jobs, organization_users, automation sweep (#5020) by @ToddHebebrand in #8476
- feat(topology): retention job for unbound topology stub nodes (#7267) by @ToddHebebrand in #8465
- feat(agent): typed error codes on command results (#4026) by @ToddHebebrand in #8473
- fix(automations): on-failure notification is sent exactly once across replays (#7188) by @ToddHebebrand in #8462
- fix(web): refresh monitors after conversion; fix the empty legacy-rules message (#6888) by @ToddHebebrand in #8477
- refactor(ai): one shared source for AI connection kinds and env-state DTOs (#7779) by @ToddHebebrand in #8466
- fix(patching): compliance view counts failed installs as failed, not pending approval (#7214) by @ToddHebebrand in #8480
- fix(workspace): DLP cleanup batch (#3474) by @ToddHebebrand in #8472
- feat(vulns): show the version to update to per vulnerable software (#7071) by @ToddHebebrand in #8481
- test(ai): live-Redis integration test for script-review concurrency slots (#5637) by @ToddHebebrand in #8464
- fix(helper): remove dead styles/deps; keyboard navigation for SegmentedControl (#2632) by @ToddHebebrand in #8478
- fix(patching): scheduled patch runs honour the assignment's role filter (#8442) by @ToddHebebrand in #8461
- chore(compose): map the next batch of unmapped API env vars (#7640) by @ToddHebebrand in #8468
- test(workspace): self-provisioning integration DB for ee/workspace (#3475) by @ToddHebebrand in #8483
- ci(e2e): run the two webauthn approval specs in CI (#5786) by @ToddHebebrand in #8469
- feat(api): admission control — priority shedding with 503 + Retry-After, WS upgrade token bucket (W08, #8147) by @ToddHebebrand in #8456
- docs: how to verify a Breeze installer (#7975) by @ToddHebebrand in #8475
- fix(helper): replace serde_yaml to drop unsafe-libyaml (#8487) by @ToddHebebrand in #8494
- fix(agent): deprecate the ignored
enroll --site-idflag (#8474) by @ToddHebebrand in #8492 - docs(edr): W02 surfacing plan (#8166) by @ToddHebebrand in #8415
- feat(mobile): location time suggestions W02 — foreground arrival prompt (#8211) by @ToddHebebrand in #8416
- ci: lint-agent and the Windows manifest guard gate CI Success (#4261) by @ToddHebebrand in #8467
- test(backup): deflake ParentCancelIsNotABudgetFailure via injectable watchdog clock (#8489) by @ToddHebebrand in #8495
- fix(settings): Session Timeout ceiling 12h, clamp on read, link from Users (#6111) by @ToddHebebrand in #8497
- fix(backup): stop admitting uploads after a run-ending outcome; deflake pool abort tests (#8490) by @ToddHebebrand in #8499
- docs(plan): network proxy tunnel origin — W02 amendments from W00 results and W01 review (#8155) by @ToddHebebrand in #8502
- feat(billing): block hours W03 — hour_block lines + contract UI (#8182) by @ToddHebebrand in #8438
- feat(network-proxy): tunnel origin W01 — config, shared core, revocation fixes, per-partner opt-in, fail-closed host dispatch by @ToddHebebrand in #8458
- test(backup): deflake storage stall tests with the fake idle clock (#8488) by @ToddHebebrand in #8498
- feat(agent): workload inventory W02 — collector core + Docker/Podman drivers (#8191) by @ToddHebebrand in #8417
- fix(api): format AI price guidance with shared money formatter (#3200) by @ToddHebebrand in #8503
- test(backup): drive the write-path stall test with the fake idle clock (#8500) by @ToddHebebrand in #8501
- docs(security): security agents config-policy spec (#6960) by @ToddHebebrand in #8504
- docs(helper): endpoint messaging + live chat spec (#8293, #8292) by @ToddHebebrand in #8505
- feat(topology): site location W01 — declared vs undeclared networks, unidentified roster, site-move guard + audit (#7885) by @ToddHebebrand in #8433
- fix(devices): show a held reboot and let an operator mark a stuck command failed (#8296) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8508
- docs(scripts): device-group targets plan (#5237) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8520
- feat(backup): bare-metal W08 — docs, UI polish, recovery readiness from real results (#5501) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8516
- docs(ticketing): ticket types + ticket links plan (#7900) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8512
- fix(ai-models): allow removing a hand-added model (#8510) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8515
- fix(agent,api): one filesystem_analysis scan at a time per device (#8509) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8518
- fix(devices): at most one secondary status pill per row, by severity (#8407) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8521
- docs(billing): invoice labor line detail plan (#8078) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8526
- feat(service-principals): task-named scope presets + per-scope descriptions (#8173) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8524
- fix(api): auto filesystem scans honour the remote-tools policy (#8509) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8522
- feat(agent): mgmtdetect — additional RMM and remote-access signatures (#8014, #8013) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8513
- feat(ai): fleet device stats tool — close the devices/stats coverage gap (#6797) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8525
- docs(agent): log-shipping health in heartbeat plan (#8406) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8532
- docs(agent): heartbeat retain-current-state signal plan (#8258) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8533
- feat(billing): block hours W04 — portal support-hours card, threshold alerts, docs (#8183) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8517
- feat(agent): remote viewer W07 — reliable input channel, seq/after barrier, epochs, input_reset (#8246) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8523
- feat(web): workload inventory W04 — Workloads tab, policy tab, fleet filters, AI tool, docs (#8193) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8519
- docs(agent): first-install watchdog retry plan (#7583) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8535
- fix(alerts): resolution_reason 'manual' on human resolves + lazy outcome columns (#7281) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8530
- feat(portal): advanced visibility W05 — patch detail flag (#7735) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8544
- feat(pam): ownership epoch W2 — epoch-anchor the PAM chain (#8204) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8514
- feat(viewer): remote viewer W03 — adopt the reliable input protocol (#8239) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8543
- feat(agent): workload inventory W03 — Hyper-V and Proxmox drivers (#8192) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8545
- feat(tickets): customer work approval W02 — gate + decisions engine (#8198) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8537
- chore(security): enrol Breeze in Anthropic's OSS Scanner (.oss-scanner/ build image + threat model) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8540
- feat(policies): restore checkpoint W03 — system_protection feature type, validator, resolver, editor tab (#4754) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8546
- feat(portal): advanced visibility W06 — vulnerability detail flag (#7736) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8550
- feat(agent): remote viewer W08 — key/pointer coverage: scancodes, extended keys, back/forward, horizontal wheel, lock-key sync (#8247) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8547
- feat(api): restore checkpoint W04 — device_restore_point_attempts ledger (#4755) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8551
- feat(api): workload inventory W05 — image currency cache, registry client, worker (#8194) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8548
- feat(pam): ownership epoch W3 — lineage binding and result path (#8205) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8552
- feat(tickets): customer work approval W03 — staff API + web UI (#8199) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8555
- feat(pam): ownership epoch W5 — merge evidence holds and survivor read access (#8207) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8554
- feat(api): restore checkpoint W05 — stamp the request at all three creation sites, requested ledger row (#4756) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8557
- feat(api): restore checkpoint W06 — ingest the restore-point outcome at all four result touch points (#4757) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8561
- feat(portal): customer work approval W04 — portal approvals + notifications (#8200) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8562
- feat(security): caller verification W03 — link tier deliverers, public verify routes, rate limits (#6357) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8560
- docs(plan): scaling W05 cluster cache — Redis pub/sub invalidation for hot-path caches (#8144) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8566
- fix(agent): keep supplementary groups when spawning Assist on macOS/Linux (#8398) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8563
- fix(helper): macOS Assist is menu-bar only; Cmd+Q hides instead of quitting (#8399) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8564
- docs(agents): integration-test has 16 shards, not 8 by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8569
- fix(security): store provider 'unknown' for a failed security collection (#8538) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8565
- fix(installer): verify the MSI against the release manifest on every binary source (#7976) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8527
- fix(monitors): deterministic conversion preview order; no raw converter id in ledger (#6888) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8531
- test(agent): deflake FallbackProvider DownloadContext under -race (#8534) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8567
- docs(plan): scaling W07 — KPI dashboard + nightly perf regression gate (#8146) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8571
- docs(plan): scaling W06 storm scenarios — reconnect curve, pool recovery, error budget (#8145) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8573
- feat(web): restore checkpoint W08 — console read route, badges, device attempts list (#4759) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8572
- feat(tickets): customer work approval W05 — AI tool text, add-in/mobile 409 handling, docs (#8201) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8574
- docs(agent): restore checkpoint W09 — docs, support matrix, release notes (#4760) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8577
- docs(gh-queue): triage security advisories in /pr by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8570
- feat(api): cluster cache — Redis pub/sub invalidation for the hot-path caches (#8144) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8578
- test: agent fuzz targets, browser tenant-isolation suite, and /release dynamic security gates by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8575
- feat(recipes): operator recipe library W04 — four-eyes plan approval over a digest-pinned effect set (#6169) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8542
- feat(web): caller verification W04 — modal, entry points, ticket badge, policy forms, AI refusal render (#6358) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8576
- feat(viewer): remote viewer W05 — keyboard lock, view-only, block-input UI, screenshot, scaling, stats overlay, per-device prefs (#8241) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8553
- docs(contributing): state the test policy by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8591
- fix(helper): bump quinn-proto to 0.11.18 (RUSTSEC-2026-0338..0342) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8559
- fix(agent,api): identity sync follow-ups — no new work during the restart, yield to rollbacks, stop re-signing refused assertions (#8382) by @lennonflima in https://github.com/LanternOps/breeze/pull/8384
- docs(plans): add tracking_issue frontmatter for six newly registered features by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8622
- feat(load-tests): storm scenarios on the agent simulator — reconnect curve, pool recovery (W06, #8145) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8587
- docs(plan): scaling W09 — agent jittered reconnect, drain handling, loop-level Retry-After (#8148) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8625
- feat(api): ticket migration windows — tables, open/close routes, sweep (#8313 wave 1a) by @lennonflima in https://github.com/LanternOps/breeze/pull/8486
- test(agent): deflake workspaceindex watch debounce test (#8568) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8624
- fix(scripts): clearing all exit-code severity rows now persists (#8590) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8626
- feat(api,monitoring): scaling W07 PR A — capacity KPI series, dashboard, perf gate tooling (#8146) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8588
- feat(api): log-shipping health W01 — devices columns, zod, classifier, dormant ingest (#8608) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8628
- feat(topology): site location W02 — declared-network anchors, site fingerprints, bounded site-gated presence read, visitor rendering with badges (#7886) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8589
- feat(ai): invoice labor detail W01 — time-entry description docs + update_time_entry action (#8602) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8627
- docs(security): security agents config-policy plan (#6960) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8631
- docs(helper): endpoint messaging + live chat plan (#8293, #8292) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8633
- feat(viewer): remote viewer W06 — keyboard mode (type-what-I-see vs physical keys) and IME composition (#8242) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8635
- feat(web): log-shipping health W02 — device-detail line (#8609) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8644
- feat(agent): heartbeat retain-state W01 — honour retainState, advertise protocol v1 (#8615) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8645
- chore(ai): mark the 2026-09 MCP coverage gap markers as reviewed exemptions (#6792–#6807) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8649
- feat(billing): invoice labor detail W02 — capture work_date on invoice lines (#8603) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8650
- feat(pam): ownership epoch W4 — signed identity assertion v2 with ownershipEpoch, Store.Retire, v2 reconciliation retirement (#8206) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8646
- fix(m365): customer-graph-actions manifest uses application permission IDs (#8648) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8651
- feat(monitoring): workload inventory W06 — image-currency compliance term, monitor, built-in template, docs (#8195) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8558
- feat(agent): watchdog install retry W01 — Ensure core with bounded backoff and persisted state (#8619) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8647
- feat(tickets): ticket types W01 — ticket_type column, validators, API plumbing (#8593) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8654
- fix(edr): refuse credential changes that move vendorRootId (#8352) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8652
- feat(edr): provider framework W02 PR-A — incidents feed, detections API, read-only AI tools, alerts, portal read model (#8166) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8653
- feat(scripts): device-group targets W01 — API resolver, validators, fail-visible runtime (#8598) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8632
- feat(patching): ring-owned approval rules W02 — Backfill + cutover (#8186) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8655
- feat(api): heartbeat retain-state W02 — emit retainState to v1 agents, hierarchy gate, kill switch (#8616) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8660
- docs(backup): plan — destination prefix applied at API S3 I/O layer (#7081) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8663
- feat(topology): site location W03 — daily presence summaries, wrong-site suggestions, confirmation (#7887) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8659
- feat(agent): log-shipping health W03 — shipper health record in the heartbeat, canary line (#8610) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8662
- feat(edr): W02 PR-B — web surfacing (detections feed, status panel, portal flag, device tab) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8666
- feat(web): device-group targets W02 — Run Script group picker and automation groups mode (#8599) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8670
- feat(patching): ring-owned approval rules W03 — Web (#8187) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8674
- feat(tickets): ticket links W02 — ticket_links table, service, routes, registrations (#8594) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8675
- feat(billing): invoice labor detail W03 — itemization setting and date/per-day rendering (#8604) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8669
- feat(ai): fold expired llm_egress_events into daily rollups (#4120) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8664
- docs(edr): plan — W03 response actions + AI + push hints (#8167) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8680
- feat(api): watchdog install retry W02 — devices columns, zod field, Info-tab banner (#8620) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8667
- feat(web): ticket types, nav and related tickets (#8595) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8682
- feat(api,web): log-shipping health W04 — fleet filter, stats count, saved view (#8611) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8681
- feat(billing): invoice labor detail W04 — accounting sync date, description caps (#8605) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8684
- feat(agent): caller verification W02 — workstation tier (agent caller_verify, helper window, deliverer, reconciliation) (#6356) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8657
- feat(agent): watchdog install retry W03 — install-lane signalling, install-script warnings, docs (#8621) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8685
- feat(ai): device-group targets W03 — group arg for AI run_script, resolved before approval (#8600) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8683
- fix(agent): seed watchdog-install report at startup so restarts don't clear the banner (#8672) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8686
- feat(api,web): log-shipping health W05 — logs-not-arriving check after a level raise (#8612) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8707
- feat(tickets): portal type badge + AI ticket type/link tools (#8596) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8708
- feat(billing): invoice labor detail W05 — refresh drafts from time entries (#8606) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8709
- fix(tickets): surface M365 mailbox poll failures, bound Graph time per sweep, narrow TypeError by @bdunncompany in https://github.com/LanternOps/breeze/pull/8400
- fix(agent): send a Breeze User-Agent on software installer downloads (#8711) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8712
- chore(deps): Bump react-native-reanimated from 4.7.0 to 4.7.1 in the react-native-animation group by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8688
- chore(deps): Bump react-native-screens from 4.28.0 to 4.29.0 in the mobile group by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8689
- chore(deps): Bump @types/node from 26.6.4 to 26.6.5 in /e2e-tests by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8690
- chore(deps): Bump werift from 0.24.4 to 0.25.0 in /e2e-tests by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8692
- chore(deps): Bump pixelmatch from 7.2.0 to 8.0.0 in /e2e-tests by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8693
- chore(deps): Bump @types/node from 26.6.4 to 26.6.5 in the typescript-tooling group by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8695
- chore(deps): Bump postcss from 8.5.28 to 8.5.29 in the tailwind group by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8697
- chore(deps): Bump eslint from 10.11.0 to 10.12.0 in the linting group by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8700
- chore(deps): Bump the tauri group with 2 updates by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8702
- chore(deps): Bump @hookform/resolvers from 5.4.0 to 5.9.1 by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8704
- chore(deps): Bump @reduxjs/toolkit from 2.12.0 to 2.13.0 by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8705
- chore(deps): Bump @googleapis/licensing from 9.0.0 to 10.0.1 by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8706
- test(api): give the partner-owned visibility repo scan a 30 s timeout (#8629) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8715
- fix(agent): excuse a Windows by-name miss spanned by an in-flight rename syscall (#8491) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8717
- fix(wt-stack,load-tests): pin caddy port for storm scenarios that restart it (#8718) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8719
- ci: Test Agent (race) — 20-minute Go package timeout, 35-minute job budget (#8726) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8727
- docs(plans): tracking_issue frontmatter for #8730 #8734 #8740 by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8748
- test(api): 60 s timeout for the sending-domains composition-root tests (#8724) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8725
- docs(plans): YARA W02 + W03 plans (#6263) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8751
- fix(tickets): hide trashed-ticket subject from non-manager readers in links (#8747) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8749
- fix(m365): actions Retest keeps stored manifest version on missing; add actions upgrade-consent route (#8745) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8750
- fix(pam): evidence hold scoped to chain tables; org-move epoch rewrite carry-forward (#8746) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8753
- feat(security-agents): W01 — feature type, managed_by_link_id, vendor registry, guards (#8735) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8754
- feat(backup): destination key root W01 — layout + key_prefix, readers resolve from recorded root (#8731) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8756
- chore(deps): Bump drizzle-orm from 0.45.3 to 0.45.4 in the drizzle group by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8699
- chore(deps): Bump monaco-editor from 0.56.0 to 0.57.0 by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8703
- feat(messaging): W01 — one-way endpoint message + ack via notify_user (#8741) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8752
- fix: add missing device idle translations by @jay23606 in https://github.com/LanternOps/breeze/pull/8395
- fix(web,api): partner users with several orgs can create org-owned peripheral policies (#8338) by @Bbomby in https://github.com/LanternOps/breeze/pull/8721
- fix(web): catalog items can be set to recurring, so quotes price monthly services correctly (#8339) by @Bbomby in https://github.com/LanternOps/breeze/pull/8722
- fix(dev): pnpm dev starts on Linux/WSL, and dev:app runs api + web + portal (#8375) by @Bbomby in https://github.com/LanternOps/breeze/pull/8723
- fix(filters): device group, tags and one-item filters no longer 500 (#8760) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8773
- fix(installer): macOS enrolls and updates with the agent the .pkg installed (#8778) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8781
- fix(api): migration window opener checks and key-route helper (#8486 follow-ups, #8313) by @lennonflima in https://github.com/LanternOps/breeze/pull/8779
- feat(api): ticket import mode and the import writer (#8313 wave 1b) by @lennonflima in https://github.com/LanternOps/breeze/pull/8782
- feat(api): adopt ERROR_CODES for settings routes (E4d) by @fabicarvano in https://github.com/LanternOps/breeze/pull/8772
- feat(api): add service catalog ownership foundation (R1) by @fabicarvano in https://github.com/LanternOps/breeze/pull/8784
- chore(deps): Bump the anthropic group with 2 updates by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8701
- chore(deps): hold Expo SDK majors out of dependabot; extend expo/tsconfig.base.json by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8766
- fix(devices): match the last logged-in user in the Devices search box (#8716) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8720
- fix(agent,api): retry a failed identity restart-marker write; limit the device-mismatch warning per device (#8623) by @lennonflima in https://github.com/LanternOps/breeze/pull/8777
- fix(agent): stop the Linux legacy-helper cleanup from deleting the current helper (#8541) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8556
- feat(web): show responsible contacts on site and device pages by @fabicarvano in https://github.com/LanternOps/breeze/pull/8785
- fix(ai): network_discovery sends the subnets and methods the agent reads (#8799) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8801
- fix(mcp): resolve a device's org inside the caller's DB context (#8798) by @bdunncompany in https://github.com/LanternOps/breeze/pull/8802
- fix(deps): bump rustls to 0.23.46 in the helper and viewer lockfiles (RUSTSEC-2026-0346..0349) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8824
- fix(pam): provision policy-enabled accounts and verify recovery by @PJF16 in https://github.com/LanternOps/breeze/pull/8676
- feat(api): adopt ERROR_CODES for partner-wide settings denials (E4e) by @fabicarvano in https://github.com/LanternOps/breeze/pull/8791
- fix(anomalies): keep metric_rollups leaf stats fresh; bound the open-episode set by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8539
- fix(agent): fall back when Windows cannot rename agent.state with FileRenameInfoEx by @bgatestmg in https://github.com/LanternOps/breeze/pull/8859
- fix(agent-ws): keep sockets open on an indeterminate credential re-check (#8838) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8851
- fix(backup): browse snapshots one directory at a time (#8230) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8245
- chore(deps): Bump the aws-sdk group across 1 directory with 5 updates by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8788
- chore(deps): Bump the tauri group across 1 directory with 3 updates by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8803
- chore(deps): Bump serde_json from 1.0.151 to 1.0.154 in /apps/viewer/src-tauri by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8806
- chore(deps): Bump @playwright/test from 1.63.0 to 1.64.0 in /e2e-tests by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8691
- fix(api): strip NUL from agent log entries and isolate log insert chunks by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8825
- fix(agent): decode UTF-16 PowerShell stderr in time sync event errors by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8829
- chore(caddy): redact credential headers and query params in all Caddy logs by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8826
- fix(oauth): attribute and rate-limit token endpoint grant errors by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8830
- feat(connection-health): W1 incident core and OAuth grant source (#8845) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8871
- test(agent): busy-process CPU sample holds under -race (#8361) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8449
- fix(api): receive agent request bodies before the org DB context opens (#8839) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8850
- chore(deps): Bump the github-actions group across 1 directory with 7 updates by @dependabot[bot] in https://github.com/LanternOps/breeze/pull/8792
- chore(deps): batch dependabot bumps (hono, nanoid, firebase-admin, mailparser, react-query, cytoscape, react-i18next, react-hook-form, astro, turbo) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8863
- feat(edr): W03 PR-A — response actions, dispatch, AI action tools (#8167) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8757
- fix(viewer): resolve Cargo Audit failure for yanked zip 4.6.1 (no RUSTSEC id) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8899
- feat(trust-center): W1 A1 — control catalog, tables, posture evidence loader (#8769) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8776
- fix(audit): make audit-chain verify org predicates index-friendly by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8536
- fix(web): offer custom fields in the dynamic group rule builder (#8843) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8887
- fix(api): tag-targeted compliance policies evaluate, observe-only (#8857) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8895
- fix(api): ticket import — status on resume, chunk byte bound, window lookup (#8782 follow-ups, #8313) by @lennonflima in https://github.com/LanternOps/breeze/pull/8884
- fix(agent): share the pre-1607 rename fallback with the PAM lifetime ledger (#8860) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8886
- fix(web): keep a value typed into a policy number field before its mount effect runs (#8879) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8892
- docs: v0.122.1 sweep — upgrade notes, env vars, feature docs by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8402
- feat(monitoring): Prometheus alerts for API saturation (#8840 G) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8842
- docs(security): CVE promise applies from 2026-10-16 onward by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8938
- fix(api): re-evaluate dynamic groups when tags or custom fields change (#8832) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8903
- feat(trust-center): W1 A2 — publication, public API, hourly refresh (#8769) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8780
- docs(ticketing): email-first queue notice and full reply (#8758) by @bgatestmg in https://github.com/LanternOps/breeze/pull/8827
- feat(agent): Encrypted Client Hello for control-plane TLS behind SNI-hijacking ISP filters (#8869) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8882
- fix(pam): recover ledger entries left by applies that failed before launch (#8867) by @Jay-Starlux in https://github.com/LanternOps/breeze/pull/8902
- docs(release): What's New 0.123.0 entry + next-release draft notes (ECH, admission mode, migrations) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8951
- fix(viewer,api): stop the double offer that leaves the viewer stuck on Connecting (#8947) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8948
- fix(agent/ech): review fixes — ECH-accepted from the connection, watchdog switches, failure causes at info level (#8869) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8949
- feat(trust-center): W1 B — public portal page, editor tab, i18n, docs (#8769) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8783
- fix(sso): tolerate Entra's already-expired re-auth id_token, keep failures on the profile page (#8862) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8974
- docs: UI flow improvements spec + W01–W04 wave plans (#8985) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8990
- fix: v0.123.0 sweep fixes by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8981
- fix(web): hide Send message entry points until the build enables endpoint messaging (#8968) by @ToddHebebrand in https://github.com/LanternOps/breeze/pull/8983
New Contributors
- @jay23606 made their first contribution in https://github.com/LanternOps/breeze/pull/8395
- @PJF16 made their first contribution in https://github.com/LanternOps/breeze/pull/8676
- @bgatestmg made their first contribution in https://github.com/LanternOps/breeze/pull/8859
- @Jay-Starlux made their first contribution in https://github.com/LanternOps/breeze/pull/8902
Full Changelog: v0.122.1...v0.123.0