Breeze RMM v0.82.0 — the Quotes & Proposals suite with accept-to-pay, Pax8 + TD SYNNEX distributor integrations, AI/ML anomaly detection on rollup-backed metrics, email-to-ticket customer routing, a sharper remote-desktop experience, and a sweeping multi-tenant security hardening wave.
Upgrading from v0.81.0? Migrations auto-apply, but v0.82.0 adds a new required
portalcontainer for the customer Quotes/Invoices experience — if you adopt the v0.82.0 compose you must setBREEZE_PORTAL_IMAGE_REFordocker compose upaborts. See Self-Hosting / Upgrade Notes at the bottom for full details, new config, and behavior changes.
What's New
Billing & Quotes
- Quotes & Proposals: build proposal documents from content blocks (headings, rich text, pricing tables) with one-time/monthly/annual recurring totals, PDF export, and a block editor. (#1455)
- Sent quotes are now acceptable end-to-end — customers view in the portal or via a public link, e-sign with a typed signature or decline with a reason, and an accepted quote converts into an invoice automatically. (#1468)
- Quotes now expire (and are blocked from acceptance past their expiry date), and accepting a quote immediately issues a payable invoice with a "Pay now" link on the public page and customer portal. (#1483)
- Invoice payments moved to a per-partner Stripe API-key model (replacing Stripe Connect/OAuth): each MSP pastes their own Stripe key, charges run directly on their account, and customers are marked paid instantly on return from Checkout. (#1610)
- Quotes and invoices now show a seller/MSP "From" contact block and combined Terms & Conditions, frozen at issue time, across PDFs, emails, the web app, and portal views. (#1651)
- Completed the billing-catalog UI: per-organization pricing, ticket-part linking via typeahead, and an archive confirmation prompt. (#1467)
- Dedicated "Partner Billing" and "Partner Billing Viewer" roles, with billing access removed from the broad Technician role and permission-aware UI that hides controls users can't access. Existing Technicians who handle billing must be reassigned to a billing role. (#1454)
- Partner-wide alert templates with a full management UI — share templates across all organizations or scope to one, with scope badges and filters. (#1466)
- Quote totals now show the "Due on acceptance" amount rather than the larger first-period total. (#1628)
- Issuing an invoice now shows an "Issuing…" in-flight state instead of looking like a draft until the save completed. (#1460)
AI & Machine Learning
- New anomaly-detection model (v1) runs in shadow mode alongside the existing model, with a side-by-side v0-vs-v1 comparison on the device anomaly view (gated behind a feature flag). (#1638)
- AI metric analysis and device metric history charts now read from pre-aggregated hourly/daily rollups for faster loads, falling back to raw data when rollups aren't ready. (#1600, #1598)
- Self-hosted operators can point the AI Agent at any Anthropic-compatible backend (locked off on hosted SaaS). (#1473)
- Script-builder AI assistant can again search and reference the script library, and generated code is correctly inserted into the script editor. (#1457, #1453)
- Hardened ML roadmap controls and fixed a batch of correctness issues: silently-failed alert acknowledgements no longer poison AI training data, rollups no longer corrupt on non-UTC servers, trend/anomaly detection covers the full time range, duplicate anomalies no longer create two incidents, and ML panels now surface errors and empty states. (#1595, #1607)
- ML feature pages (User Risk, Anomalies, Alert Correlations, Capacity Forecast) load without console errors and correctly show per-org disabled states. (#1631)
Integrations
- Pax8: syncs clients and subscription/license data, with a full connect/test/sync UI and company-to-org mapping, plus the ability to link synced license quantities to recurring contract lines. (#1594, #1635)
- TD SYNNEX: connect your account, search products, and import them into the catalog. (#1596)
- New Distributors tab on the Integrations page houses Pax8 and TD SYNNEX. (#1635)
- Consolidated the legacy per-category integration pages into the tabbed
/integrationshub with deep-linkable tabs and a new Notifications tab (Slack/Teams/Discord); old standalone routes (PSA, Security, Huntress, Monitoring, etc.) now redirect into the hub. (#1716)
Tickets
- Email-to-ticket now routes mail from any customer, not just registered portal users: map a customer's sender domain to an organization (with optional password-less contact onboarding), or send unmatched mail to an opt-in triage org instead of quarantine. (#1715)
Monitoring & Alerts
- Acknowledging or resolving an alert from the detail page now shows a clear success/failure message instead of failing silently. (#1660)
- The Notification Channels page loads cleanly for partner users with no organization selected. (#1643)
- Network Monitoring and Discovery tabs are now preserved in the URL (hash-based) for consistent, bookmarkable navigation. (#1645)
- Executive summary and OS-distribution analytics now report real errors instead of silently showing empty/zero data. (#1609)
Remote & Agent
- Remote desktop streaming reaches much sharper quality on high-resolution screens (1440p up to 30 Mbps, 4K up to 50 Mbps), with an admin option to tune the bitrate cap. (#1669)
- Redesigned remote-desktop viewer toolbar — logically grouped controls, overflow menu, a single Quality popover, a local-fullscreen shortcut, and a polished credentials dialog. (#1641)
- Opening a second concurrent remote session no longer freezes the Viewer app. (#1627)
- Windows devices now report accurate BIOS, GPU, and motherboard details, with motherboard info shown on the device hardware page. (#1524)
- Watchdog version now appears on the device details page and as an optional device-list column. (#1390)
- The device filter's software picker now searches software names server-side for reliable results across large fleets. (#1461)
- Foundation for a new OneDrive Helper that will auto-mount the right SharePoint libraries per user (backend only this release). (#1679)
Platform & Reliability
- Approver registration redesign: a tech's phone provisions itself silently at login, so the first Face ID prompt is a real approval rather than setup; the web "Approval security" page lists registered phones and browsers. The static PIN was removed, and critical approvals now require fresh account re-authentication plus a hardware-backed signature. (#1433)
- New per-user 12-hour vs 24-hour time-format preference that applies throughout the web app. (#1672)
- Surfaced several built-but-unlinked pages in navigation — SSO, Access Reviews, Timesheets, Quarantined Devices, Third-Party Catalog, and Connected Apps now have sidebar/settings entry points (each gated by the permission its route enforces). (#1716)
- Redesigned the Update Ring editor into a single patch-approval matrix (default rule plus per-category overrides), creatable/editable directly from the Config Policy patch tab. (#1456)
- Customer portal (invoices and quote acceptance) is now served in production under a path prefix on the main domain. (#1474)
- Large software-package uploads now stream to disk and have a 10-minute window, eliminating false "aborted" errors and bounding memory under concurrent uploads. (#1664, #1602)
- Background integration sync workers (Huntress, Pax8, DNS) no longer hold database connections open across slow external calls, preventing connection-pool exhaustion. (#1703, #1704)
- Large bulk device-connection inserts are now chunked under the database parameter limit, fixing silent loss of connection inventory. (#1698)
Security & Hardening
This release includes a large security-review hardening wave. Highlights:
- Hardened multi-tenant site-axis isolation on alert, network, audit-baseline, peripheral-policy, DNS reporting, and AI list/audit-query endpoints so site-restricted users can't read or act on resources outside their assigned sites. (#1644, #1678, #1665, #1681, #1683, #1673, #1702, #1706, #1710)
- All mutating tunnel endpoints (open/close/allowlist) and credential-minting/viewer-transition endpoints are now audit-logged; manual and Stripe-initiated invoice payment voids are also audit-logged. (#1700, #1705, #1708, #1701, #1707)
- Required full agent-role authorization on security, patch, and posture-ingest endpoints, added a tenant-status gate on agent certificate renewal, and hardened the integrity of agent-reported backup/vault completion state. (#1687, #1690, #1688, #1711)
- SSO hardening: identity-first lookup with safe just-in-time linking, honoring the IdP MFA signal, a dedicated
sso:adminpermission, and DNS-based domain-ownership verification. (#1671, #1680, #1691, #1695) - Core authentication hardening: durable session/token revocation on password change, TOTP single-use replay protection, and strict refresh-token family enforcement. (#1648, #1677, #1653, #1655)
- Separation-of-duties enforcement on privileged-access elevation (distinct approver required, correct requester attribution). (#1662, #1682)
- Prevented cross-organization script execution and cross-partner catalog data leaks on quotes, and scoped alert routing-rule writes correctly. (#1674, #1684, #1654)
- Added rate limiting to VNC connect-code exchange and tunnel WebSocket upgrades, routed PSA integration requests through a safe-fetch wrapper to block SSRF, validated background automation job payloads, enforced partner org-access on ticket reads, authenticated inbound ticket-email senders, and neutralized CSV formula injection in fleet log exports. (#1670, #1659, #1661, #1667, #1666, #1699, #1692)
Security fixes are described at a high level here; any CVE/GHSA advisories are published separately after rollout.
Bug Fixes
- Fixed a production bug where the AI agent could not run any tool — every command returned "rejected or timed out" even after approval. (#1591)
- Fixed the Windows agent MSI installer rolling back when installed by double-click/UAC, and a false pre-flight refusal on some self-hosted reverse-proxy setups. (#1480, #1477)
- Windows agents now auto-detect and repair incorrect log/data folder permissions at startup when the installer's hardening step was blocked. (#1613)
- Windows devices no longer stay stuck showing "reboot required" forever in Patch Compliance. (#1478)
- The Patches page now respects the organization switcher (approve/decline/defer, export, ring actions), requires confirmation for destructive installs, and surfaces action results. (#1636)
- Fixed the mobile app showing a previous session's AI chat history after switching accounts, and surfaced sign-out credential-wipe failures instead of silently leaving data on the device. (#1415, #1626)
- Fixed running a script against multiple selected devices, which previously failed with a "must contain at least one item" error. (#1590)
- Fixed the script editor losing its color theme when navigating between scripts. (#1593)
- Permission-restricted pages now show a clear access-denied state instead of a misleading "session expired" prompt, and the sidebar only shows items the user can use. (#1640, #1629)
- Disabled identity integrations (Google Workspace / Microsoft 365) now show a calm "not enabled" message instead of a red error banner. (#1632)
- Partner Settings shows a loading spinner instead of a flashed "access denied" message. (#1642)
- Auth pages respect the saved light/dark theme on first load. (#1649)
- Add Organization now auto-fills the URL slug from the name (still manually overridable). (#1646)
- The Scripts "Available to" picker works again for partner-level users. (#1469)
- Collapsed AI and Documentation side panels no longer intercept clicks. (#1463)
- Fixed duplicate Role/Type columns on agent device rows. (#1462)
- Corrected the stale API version shown in the sidebar footer. (#1647)
Self-Hosting / Upgrade Notes
Upgrading from v0.81.0 → v0.82.0. Standard upgrade path applies: bump BREEZE_VERSION in /opt/breeze/.env and docker compose pull api web && docker compose up -d. If you build from source, run pnpm install — dependencies changed (new @fastify/busboy, nodemailer 8→9, @anthropic-ai/claude-agent-sdk 0.2→0.3, zod 3→4).
⚠️ Action required before/after upgrade
Database: nothing required — all 31 new migrations apply automatically on boot (autoMigrate runs at startup unless AUTO_MIGRATE=false), each wrapped in its own transaction and idempotent. No new env var is required at boot by the API.
New required service — the customer portal (#1474). v0.82.0 introduces a new portal container (Astro SSR, apps/portal) that serves the customer-facing Quotes/Invoices experience under a base path (default /portal) on your main domain — no dedicated hostname/cert needed. The release pipeline now builds and publishes it to ghcr.io/lanternops/breeze/portal, and it is wired into the official compose files (docker-compose.yml, deploy/docker-compose.prod.yml).
Its image line is guarded — image: ${BREEZE_PORTAL_IMAGE_REF:?…} (prod compose: ${BREEZE_PORTAL_IMAGE_DIGEST:?…}) — so if you adopt the v0.82.0 compose you MUST set the image ref or docker compose up aborts the entire stack, not just the portal. Add to your .env:
BREEZE_PORTAL_IMAGE_REF=ghcr.io/lanternops/breeze/portal:${BREEZE_VERSION} # base compose
# deploy/docker-compose.prod.yml instead wants a digest:
# BREEZE_PORTAL_IMAGE_DIGEST=sha256:<the v0.82.0 portal image digest>
PORTAL_BASE_PATH=/portal # baked into the image at build; keep in sync with the Caddyfile carve-out
PUBLIC_PORTAL_URL=https://<your-domain>/portal # public origin for emailed quote/invoice links; defaults to https://${BREEZE_DOMAIN}/portal
Also add the /portal carve-out to your Caddyfile so the main domain routes /portal* to the portal container (the rest stays on web).
- If you do a version-bump-only upgrade on a hand-edited compose that has no
portalservice: nothing breaks atuptime, but public quote/invoice accept-and-pay links will 404 — Quotes is not usable until you add the portal service. There is no env flag to "disable" the portal; you either run the container or you don't have the customer portal.
Optional things you may want to do:
- Self-hosted custom AI backend (#1473/#1412): new
ANTHROPIC_BASE_URLlets you route the AI Agent at any Anthropic/v1/messages-compatible backend (local vLLM, LiteLLM gateway). It is fail-closed: the API will refuse to boot ifANTHROPIC_BASE_URLis set whileIS_HOSTEDis not explicitlyfalse/0/no/off. So if you set it, you must also setIS_HOSTED=falseexplicitly (and threadIS_HOSTEDthrough theapiserviceenvironment:block — a value in.envalone is not enough). Leave it unset and nothing changes.
Database migrations
31 new migrations, all idempotent and auto-applied on boot. Notable ones and caveats:
-
pg_trgmextension (2026-06-17-software-inventory-name-trgm.sql): runsCREATE EXTENSION IF NOT EXISTS pg_trgmthen a GIN index onsoftware_inventory.name.pg_trgmis the only extension Breeze relies on and is present in the supported Postgres images / DO managed PG. Needs a role allowed toCREATE EXTENSION(standard setups qualify). Nopgcrypto/gen_random_bytesdependency anywhere. -
Column DROP / data loss (
2026-06-15-drop-approver-pin.sql): drops the approver-PIN columns fromusers/approval_requests/elevation_requests. The static approver PIN is replaced by L4 fresh re-auth; these columns were no longer read/written. If you used approver PINs, approvers now step up via account re-auth. -
Partitioned table creation (
2026-06-18-metric-rollups.sql+-n-…-partitions.sql): creates the new RANGE-partitionedmetric_rollupstable + default partition + monthly partitions for[now-1mo, now+3mo]. The table is new, so no large-table rewrite on existing DBs. -
New ML/anomaly/alert tables (
metric_anomalies,metric_anomaly_candidates,alert_correlation_groups,ml_feedback_events,remediation_suggestions, etc.): allCREATE TABLE IF NOT EXISTS, empty, no migration-time backfill. Optional one-time backfill scripts exist (pnpm --filter @breeze/api metric-rollups:backfill,metric-anomalies:backfill) but are not run automatically and are not required. -
role_permissionsPK (2026-06-20-role-permissions-unique.sql): de-dups duplicate(role_id, permission_id)rows (logs a WARNING with the count) then adds a composite PK. Small table; no scale concern. -
No large-table NOT NULL adds or backfills in this range. New
org_idcolumns are on new tables only.device_hardwaregets three nullablemotherboard_*columns (instant).sso_providersgetstrusts_idp_mfa boolean NOT NULL DEFAULT false(instant in PG11+). -
New
customer_email_domainstable (2026-06-20-a-customer-email-domains.sql, #1715): partner-axis RLS + denormalizedorg_id, new and empty — backs the email-to-ticket sender-domain→org mapping. No backfill.
Other migrations: Quotes/Proposals schema + decline-reason + contact fields, Pax8 billing sync, TD SYNNEX Digital Bridge, OneDrive Helper (feature enum + settings/libraries/device-state), billing roles, Stripe per-partner API-key + status check, the FK-child RLS backstop, and the SSO trio (idp-mfa, admin-permission backfill, verified-domains).
New configuration
The only new var that can block a deploy is the portal image ref (compose :? guard); the rest are optional:
| Name | Required? | Default | Purpose / notes |
|---|---|---|---|
BREEZE_PORTAL_IMAGE_REF (base compose) / BREEZE_PORTAL_IMAGE_DIGEST (prod compose)
| Required if you adopt the v0.82.0 compose | none (:? guard)
| Image for the new portal container (#1474). Unset → docker compose up aborts the whole stack. Set to ghcr.io/lanternops/breeze/portal:${BREEZE_VERSION} (or the release digest).
|
PORTAL_BASE_PATH
| Optional | /portal
| Base path the portal is served under; baked into the portal image at build, keep in sync with the Caddyfile carve-out. |
PUBLIC_PORTAL_URL
| Optional | https://${BREEZE_DOMAIN}/portal
| Public origin for portal links in outbound email (quote/invoice accept links); falls back to PUBLIC_APP_URL.
|
ANTHROPIC_BASE_URL
| Optional (self-host only) | unset | Route the AI Agent at an Anthropic-compatible backend (#1473/#1412). Boot-refuses unless IS_HOSTED is explicitly false/0/no/off; must be a valid http(s) URL. Pair with ANTHROPIC_AUTH_TOKEN.
|
ANTHROPIC_MODEL
| Optional | unset | Overrides the default model id for a raw vLLM endpoint (leave unset when a LiteLLM gateway aliases the model). |
SSO_DOMAIN_VERIFICATION_STRICT
| Optional | false (off)
| When true, every org must verify DNS domain ownership before SSO can JIT-link/provision. Off = gradual: an org is gated only once it has ≥1 verified domain. Already-linked identities are always exempt. Never blocks boot.
|
ML kill switches: ML_FEATURES_DISABLED / ML_OUTPUTS_DISABLED / ML_GLOBAL_KILL_SWITCH / ML_DISABLED_FLAGS
| Optional | unset (ML on) | Read at call-time (no redeploy needed) to stop ML/AI producers from writing outputs. ML_DISABLED_FLAGS is a comma list supporting ml.* wildcards.
|
Removed env vars (Stripe Connect → per-partner API key): STRIPE_CONNECT_CLIENT_ID and STRIPE_OAUTH_REDIRECT_URL are gone (now ignored — no action needed, but you can delete them). STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET remain.
Reminder: any var you set in .env must also be mapped in the api/web (and portal) service environment: block of your compose file — compose only interpolates listed vars. This applies especially to IS_HOSTED if you enable ANTHROPIC_BASE_URL.
Behavior & breaking changes
- Agent ingest now enforces token role (#1687, #1690). Eight agent posture-ingest routes now require the main-agent role token, rejecting the lower-privilege watchdog token with 403. Normal agents are unaffected — the main agent already owns these submissions; only the watchdog (heartbeat/log-shipping) token is newly rejected, and it never legitimately used them.
POST /:id/logsstays open (the watchdog ships failover journals there). No agent-side change needed; old agents continue to work. - SSO provider management requires
sso:admin(#1691). The SSO provider-mutation routes moved fromorganizations:writeto a newsso:adminpermission. Non-breaking: the backfill migration grantssso:adminto every role that already hasorganizations:write, and wildcard (*:*) roles satisfy it at check time. No existing SSO admin loses access. - SSO domain verification ships dark (#1695). New
sso_verified_domainstable + DNS-TXT proof-of-ownership before SSO will JIT-link/provision new accounts. No org is gated until it verifies a domain (or you setSSO_DOMAIN_VERIFICATION_STRICT=true); already-linked identities are exempt. Pending rows are auto-seeded from existingsso_providers.allowed_domains. Admin UI is a follow-up — backend only this release. - SSO IdP-MFA trust is opt-in (#1680). New
sso_providers.trusts_idp_mfadefaults tofalse; no behavior change unless a provider opts in. - Other auth hardening (mandatory id_token signature, identity-first JIT linking, TOTP replay protection, refresh-token
famclaim enforcement, stricter password-change session invalidation) tightens correctness and shouldn't affect a correctly-configured deployment, but is worth noting for non-standard IdP/token setups. - Legacy integration routes now 301-redirect into the
/integrationshub (#1716). Old standalone paths (e.g./integrations/psa,/security,/huntress,/monitoring) redirect to the corresponding hub tab (/integrations#psa, etc.). Bookmarks keep working; no action needed. - Email-to-ticket customer routing is opt-in and configured in-app (#1715). Sender-domain→org mappings and the optional triage-org fallback are set in the app (no env var); inbound mail is still gated by the existing DMARC/
senderAuth.verifiedcheck. Behavior is unchanged until you add a mapping or enable triage.
Notes
- Migrations are auto-applied; to apply them manually against a managed Postgres before the API boots, set
AUTO_MIGRATE=falseand run them yourself. - This release pins
zodto v4 internally — no operator action, relevant only if you maintain local patches. - New infra: the
portalcontainer (built & published by the release pipeline toghcr.io/lanternops/breeze/portal; required by the v0.82.0 compose — see the action-required note above) and the per-partner Stripe API-key billing model (partners paste their own restricted Stripe secret key in-app; no platform-level Stripe Connect client setup needed anymore).
Full changelog: v0.81.0...v0.82.0
What's Changed
- docs: billing suite + AI for Office, email-to-ticket, portal payments by @ToddHebebrand in #1458
- feat(rbac): dedicated billing roles, tighten technician grants, permission-aware UI by @ToddHebebrand in #1454
- feat: Quotes/Proposals — Phase 1 (schema, RBAC, service, routes, PDF, block editor) by @ToddHebebrand in #1455
- chore: zod 3.25 bump + v4-compatible pre-fixes (1/3) by @ToddHebebrand in #1451
- chore: upgrade zod to v4 (2/3) by @ToddHebebrand in #1452
- fix(scripts): gate availability picker on JWT scope, not partners list by @ToddHebebrand in #1469
- feat(catalog): complete the billing-catalog UI — per-org pricing, ticket-part link, archive confirm (#1368) by @ToddHebebrand in #1467
- feat: partner-wide alert templates — API + management UI (#1425) by @ToddHebebrand in #1466
- fix(billing): unambiguous in-flight state when issuing an invoice (#1418) by @ToddHebebrand in #1460
- fix(devices): stop Role and Type columns duplicating on agent rows (#1386) by @ToddHebebrand in #1462
- fix(ui): make collapsed AI + Documentation side panels inert (#1419) by @ToddHebebrand in #1463
- feat(ai-agent): make ANTHROPIC_BASE_URL configurable for self-hosted backends (#1412) by @ToddHebebrand in #1473
- fix(installer): pre-flight the /api version-metadata endpoint, not apex /health (#1470) by @ToddHebebrand in #1477
- fix(installer): run HardenProgramDataAcl deferred as LocalSystem (closes #1479) by @ToddHebebrand in #1480
- fix(patches): clear pendingReboot after reboot — derive from live OS signal (#1472) by @ToddHebebrand in #1478
- fix(api): restore Script AI assistant editor insertion by @ToddHebebrand in #1453
- fix(ai): wire script-builder library tools through the session guardrail by @ToddHebebrand in #1457
- feat(web): redesign Update Ring editor as a unified approval matrix by @ToddHebebrand in #1456
- feat: Quotes/Proposals — Phase 2 (send, portal/public view, e-sign accept → convert) by @ToddHebebrand in #1468
- docs(quotes): Phase 3 implementation plan (accept→pay + expiry) by @ToddHebebrand in #1475
- fix(api): CHECK constraints on authenticator assurance columns (#1372) by @ToddHebebrand in #1482
- feat(portal): deploy customer portal under /c path prefix by @ToddHebebrand in #1474
- chore(deps): bump pnpm/action-setup from 6.0.8 to 6.0.9 in the github-actions group across 1 directory by @dependabot[bot] in #1464
- feat(devices): server-side software-name search for filter picker (#1459) by @bdunncompany in #1461
- enhance(web): Show Watchdog version in device UI by @ramphex in #1390
- feat(authenticator): registration redesign — the phone just works (no setup), PIN→L4 re-auth by @ToddHebebrand in #1433
- fix(ai): approval poll read 0 rows under RLS — AI tools always "rejected or timed out" by @ToddHebebrand in #1591
- fix(web): multi-select "Run Script" sent empty deviceIds (400 "Array must contain at least one item") by @ToddHebebrand in #1590
- fix(ml): harden roadmap v0 controls by @ToddHebebrand in #1595
- fix(ml): avoid DB context during metric worker fanout by @ToddHebebrand in #1597
- feat(ml): use rollups for device metric history by @ToddHebebrand in #1598
- feat(ml): use rollups for AI metric analysis by @ToddHebebrand in #1600
- test(web): fix flaky ContractEditor create test (wait for async org option) by @bdunncompany in #1604
- fix(deps): bump undici 7.28.0 + nodemailer 9.0.1 to clear Trivy HIGH findings by @bdunncompany in #1603
- chore(deps): bump tauri from 2.11.2 to 2.11.3 in /apps/viewer/src-tauri by @dependabot[bot] in #1561
- chore(deps): bump tauri-build from 2.6.2 to 2.6.3 in /apps/viewer/src-tauri by @dependabot[bot] in #1562
- chore(deps): bump tauri-build from 2.6.2 to 2.6.3 in /apps/helper/src-tauri by @dependabot[bot] in #1564
- fix(scripts): preserve Monaco theme colors across View-Transition swap (#1589) by @bdunncompany in #1593
- fix(agent/web/api): Fix Windows hardware reporting for BIOS, GPU, and add motherboard details by @ramphex in #1524
- fix(web): give FormData uploads a 10-minute timeout, not the 30s API default (#1601) by @bdunncompany in #1602
- chore(deps): bump tauri from 2.11.2 to 2.11.3 in /apps/helper/src-tauri by @dependabot[bot] in #1563
- feat(docs): site-wide CTA banner pointing back to the product by @ToddHebebrand in #1592
- ci: harden Tauri apt step against slow mirror flake (#1605) by @ToddHebebrand in #1606
- fix(ml): address review findings across the ML roadmap by @ToddHebebrand in #1607
- docs: add GitHub branch/PR naming conventions to AGENTS.md by @ToddHebebrand in #1611
- feat(billing): add Pax8 license sync by @ToddHebebrand in #1594
- feat(catalog): add TD SYNNEX catalog import by @ToddHebebrand in #1596
- fix(test): exempt partner-axis Pax8 tables from org-tenant RLS coverage check by @ToddHebebrand in #1614
- feat(quotes): Phase 3 — expiry + accept→pay (Stripe) by @ToddHebebrand in #1483
- feat(billing): per-partner Stripe API-key model (replaces Connect) by @ToddHebebrand in #1610
- fix(api): surface analytics query failures instead of fake-empty 200 (#1608) by @bdunncompany in #1609
- test(billing): fix quote-pay integration mocks for per-partner Stripe key model (clears main red, #1619) by @ToddHebebrand in #1621
- feat: wt-stack — per-worktree test stack with Playwright wiring by @ToddHebebrand in #1620
- docs(plan): architectural design proposal for #1105 (txn-around-slow-work pool poisoning) by @ToddHebebrand in #1439
- chore(deps): bump claude-agent-sdk to 0.3 + port tool handler types (supersedes #1402) by @ToddHebebrand in #1484
- fix(authenticator): make AssuranceDecision a discriminated union (#1373) by @ToddHebebrand in #1622
- fix(agent): self-heal ProgramData ACL drift when MSI hardening is blocked (#1481) by @ToddHebebrand in #1613
- fix(billing): run Stripe Checkout outside the request DB transaction (#1448) by @ToddHebebrand in #1616
- chore(claude): commit curated .claude config + CLAUDE.md context by @ToddHebebrand in #1623
- fix(web): remove dead CSP script-src hash pins + real-browser drift guard (#1232) by @ToddHebebrand in #1624
- fix(mobile): clear all session state on sign-out (cross-session data leak) by @ToddHebebrand in #1415
- fix(quotes): show one-time "Due on acceptance" total, not first-period total by @ToddHebebrand in #1628
- fix(web): permission-gate sidebar nav + access-denied for billing roles by @ToddHebebrand in #1629
- fix(quotes): hydrate public quote-accept page (portal CSP) + harden acceptUrl by @ToddHebebrand in #1630
- fix(web): calm "not enabled" state for disabled identity integrations by @ToddHebebrand in #1632
- fix(mobile): surface SecureStore wipe failures on logout teardown (#1625) by @ToddHebebrand in #1626
- feat(integrations): Pax8 distributor UI + TD SYNNEX moved to Integrations hub by @ToddHebebrand in #1635
- fix(viewer): stop whole-app hang on a second concurrent remote session (#1409) by @ToddHebebrand in #1627
- docs(features): document the AI Insights / ML feature suite by @ToddHebebrand in #1637
- fix(web): scope ML feature-flag fetch to active org + SSR-safe alerts tabs by @ToddHebebrand in #1631
- fix(patches): respect org switcher + surface patch action failures by @ToddHebebrand in #1636
- fix(api): reject empty-authority portal URL in quote acceptUrl (#1630 follow-up) by @ToddHebebrand in #1639
- fix(web): render access-denied on 403 instead of "session expired" (#1629 follow-up) by @ToddHebebrand in #1640
- feat(ml): add anomaly v1 shadow model by @ToddHebebrand in #1638
- fix(web): show loading instead of flash-of-access-denied on partner settings by @ToddHebebrand in #1642
- fix: GET /alerts/routing-rules should not 400 on load by @ToddHebebrand in #1643
- fix(security): multi-tenant authz hardening from security review #1 by @ToddHebebrand in #1644
- feat(viewer): redesign remote-desktop viewer toolbar + connection UI by @ToddHebebrand in #1641
- fix(web): use hash (not query param) for Monitoring/Discovery tab state by @ToddHebebrand in #1645
- fix(web): auto-derive organization slug from name by @ToddHebebrand in #1646
- fix(web): correct stale API version in sidebar footer by @ToddHebebrand in #1647
- docs(testing): release-testing pass 2 results (v0.81.0→HEAD) by @ToddHebebrand in #1650
- feat(billing): seller contact info + Terms & Conditions on quotes & invoices by @ToddHebebrand in #1651
- fix(api): scope-aware org resolution for routing-rule writes (#1633) by @ToddHebebrand in #1654
- fix(web): preserve set theme on auth pages by @ramphex in #1649
- fix(auth): hard-reject refresh tokens without a fam claim (#917 L-1) by @ToddHebebrand in #1653
- docs(security-review): note experimental index-assisted enumeration by @ToddHebebrand in #1657
- fix(security): core authentication hardening from security review #2 by @ToddHebebrand in #1655
- fix(pam): require a distinct approver for elevation requests by @ToddHebebrand in #1662
- fix(software): stream multipart upload via busboy to bound peak heap (#1408) by @ToddHebebrand in #1664
- feat(remote-desktop): configurable + raised WebRTC bitrate ceiling (#1410) by @ToddHebebrand in #1669
- fix(alerts): enforce site-axis scope on correlation and bulk endpoints by @ToddHebebrand in #1665
- fix(security): SSO identity-first lookup + safe JIT linking (review #2 H-2/H-3) by @ToddHebebrand in #1671
- fix(scripts): require script org to match target device org by @ToddHebebrand in #1674
- fix(dns-security): gate and site-scope the top-blocked endpoint by @ToddHebebrand in #1673
- fix(security): TOTP replay protection (RFC 6238 §5.2) from security review #2 by @ToddHebebrand in #1677
- fix(alerts,network): enforce site-axis on by-id and bulk endpoints by @ToddHebebrand in #1678
- fix(security): SSO IdP-MFA signal (security review #2 H-1) by @ToddHebebrand in #1680
- fix(audit-baselines): site-check target devices on apply-approval decision by @ToddHebebrand in #1681
- fix(ai-tools): set subjectUserId on tech_jit_admin elevation requests by @ToddHebebrand in #1682
- fix(peripheral): require devices.read on policy read endpoints by @ToddHebebrand in #1683
- fix(quotes): scope catalog-line lookup to the quote's partner by @ToddHebebrand in #1684
- fix(devices): fail closed when permissions context is absent in site check by @ToddHebebrand in #1686
- fix(ai): harden page context and approvals by @ToddHebebrand in #1658
- fix(remote): rate limit tunnel websocket upgrades by @ToddHebebrand in #1659
- fix(web): wrap alert detail mutations in runAction by @ToddHebebrand in #1660
- fix(psa): route provider requests through safeFetch by @ToddHebebrand in #1661
- fix(installer): avoid host-derived install script URLs by @ToddHebebrand in #1663
- fix(tickets): enforce partner org access on reads by @ToddHebebrand in #1666
- fix(jobs): validate automation queue payloads by @ToddHebebrand in #1667
- fix(remote): rate limit VNC exchange by @ToddHebebrand in #1670
- feat(web): add user time format setting by @ramphex in #1672
- feat(onedrive-helper): provisioning + library-sync server foundation (Sub-project A, Phase 1) by @ToddHebebrand in #1679
- fix(auth): harden password-change session invalidation by @ToddHebebrand in #1648
- fix(agents): require agent-role token for security + patch ingest by @ToddHebebrand in #1687
- fix(agents): tenant-status gate on mTLS renew-cert by @ToddHebebrand in #1688
- fix(agents): require agent-role token for 5 more posture-ingest routes (F8) by @ToddHebebrand in #1690
- feat(security): sso:admin gating (Plan A — review #2 H-2 root-cause) by @ToddHebebrand in #1691
- docs: unified mesh fabric feasibility study by @ToddHebebrand in #1693
- docs(security): SSO domain-ownership + sso:admin design (review #2 H-2 root cause) by @ToddHebebrand in #1689
- fix(web): neutralize CSV formula injection in fleet log export by @ToddHebebrand in #1692
- feat(security): SSO domain verification (review #2 H-2, defense-in-depth) — backend by @ToddHebebrand in #1695
- fix(tunnels): audit-log all mutating tunnel endpoints by @ToddHebebrand in #1700
- fix(invoices): audit log manual payment record/void by @ToddHebebrand in #1701
- fix(aitools): site-axis narrowing on no-deviceId list tools by @ToddHebebrand in #1702
- fix(inbound-email): authenticate sender before identity/state actions by @ToddHebebrand in #1699
- fix(agents): chunk device_connections bulk insert under Postgres param limit (#1696) by @ToddHebebrand in #1698
- fix(integrations): fetch outside the DB transaction in Huntress + Pax8 syncs (#1697) by @ToddHebebrand in #1703
- fix(dns): fetch/mutate outside the DB transaction in the DNS sync worker (#1697) by @ToddHebebrand in #1704
- fix(tunnels): audit credential-minting endpoints by @ToddHebebrand in #1705
- fix(aitools): site-narrow device-typed rows in query_audit_log (R3b) by @ToddHebebrand in #1706
- fix(billing): audit Stripe full-refund payment voids by @ToddHebebrand in #1707
- fix(tunnels): audit viewer-transition tunnel handlers (R1c) by @ToddHebebrand in #1708
- fix(agent): bind run_as_user delivery to the target console session by @ToddHebebrand in #1709
- fix(aitools): site-narrow device-referencing audit rows in query_audit_log (R3b residual) by @ToddHebebrand in #1710
- harden agent backup/vault WS result integrity by @ToddHebebrand in #1711
- feat(ticketing): Phase 5 — email-to-ticket customer routing by @ToddHebebrand in #1715
- feat(web): surface orphaned pages in nav and consolidate integration routes by @ToddHebebrand in #1716
Full Changelog: v0.81.0...v0.82.0