<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45862
Speculative fixes since I wasn't able to repro issue locally.
Refresh AppContext and the React Query ["config"] cache directly after
the SSE/DELETE response so AndroidMdmCard and AndroidMdmPage flip
without a manual page reload, with a bounded retry to defeat the 1s
cached_mysql.AppConfig TTL. Also harden startSSE to detect the success
signal across chunk boundaries and reject (rather than hang) when the
stream ends without it.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
## Testing
- [x] QA'd all new/changed functionality manually
For unreleased bug fixes in a release candidate, one of:
- [x] Confirmed that the fix is not expected to adversely impact load
test results
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed Android Enterprise page not refreshing after connecting or
disconnecting Android MDM. The Enterprise ID and card state now update
automatically without requiring a manual page reload.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45914?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes#45763
The recent bump of github.com/Azure/go-ntlmssp to v0.1.1 changed the
Negotiator to send an unauthenticated probe before NTLM. NTLM is
connection-bound on IIS, and the extra round-trip breaks the handshake
on NDES setups behind reverse proxies, Okta Access, or a WAF.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45720
# Details
When requesting CVE chart data, we were making a call to get the set of
tracked CVEs to filter the data by. Currently we're only _collecting_
data for the tracked CVEs, so there's no reason to make this call at
all.
When we add more filtering options and start collecting more data, we'll
need a call like this again, and will likely need to start caching the
results. Otherwise it's a multi-second cost per query on large
deployments.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [X] Added/updated automated tests
- removed some outdated tests
- replaced with a test that checks that when an entity filter returns no
items (an empty, rather than nil slice) we get empty buckets returned
rather than getting data for all entities. This is a regression test for
when we add filtering back.
- [X] QA'd all new/changed functionality manually
- validated that chart still loads and shows the same data.
- tried it on a load test env and saw dramatic API request time
improvement
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Bug Fixes**
* Optimized CVE chart data retrieval by eliminating redundant queries,
reducing unnecessary database operations and improving performance.
* Fixed entity ID filtering logic to correctly handle edge cases and
prevent unintended filter interactions across metrics.
* **Tests**
* Added test coverage for chart data queries with empty entity filters.
* Improved test isolation to ensure metric-specific filtering behavior
is properly separated.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45813?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#42288
# Summary
This PR adds support for configuring an optional SES sender domain.
When the SES email backend is enabled, Fleet can now use a configured
sender domain for the `From` address instead of always deriving the
domain from `server.server_url`. If the setting is not provided, Fleet
keeps the existing behavior.
# Impact
This gives self-hosted operators a server-side SES configuration option
for email sending without changing UI-managed SMTP settings.
# Root cause
The SES sender path only generated `do-not-reply@<server host>` from the
Fleet server URL, so there was no way to override the sender domain
through server configuration.
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] Added/updated automated tests
- [x] Setting(s) is/are explicitly excluded from GitOps
## Testing
- [x] `go test -tags full,fts5,netgo ./server/mail -run
'Test_(getFromSES|sesSender_SendEmail)$'`
- [x] `go test -tags full,fts5,netgo ./server/config -run
'TestConfig(SESSenderDomain|Roundtrip)$'`
- [x] `go test -tags full,fts5,netgo ./server/service -run
'TestService_EmailConfig$'`
- [ ] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added optional SES sender domain configuration. Users can specify a
custom domain for the email "From" address via config or environment
variable; when unset it falls back to the server hostname.
* **Tests**
* Added and expanded tests to verify sender-domain precedence,
From-header generation, and related error cases.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/43811?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45715
# Details
This PR refactors the way the charts module stores historical data to
use the [roaring bitmap](https://github.com/RoaringBitmap/roaring)
package instead of saving raw bitmaps. See [this
blurb](https://github.com/RoaringBitmap/roaring#how-does-roaring-compares-with-the-alternatives)
to learn how roaring compresses data, but TL;DR for our purposes it
represents a huge improvement especially for larger deployments where
host ID numbers may be very large. In testing, some data was reduced
96%.
The majority of the changes in this PR are straight swapping of types
from `[]byte` to `*roaring.Bitmap` in vars and function signatures, and
updating the internals of our bit math helpers to use roaring methods
instead of native AND and OR methods. I've tried to comment on all
functional changes.
Since the charts have been shipped already, so there will be data in the
wild in the prior "dense" format, the code still handles dense bitmaps
on _read_, but will always _write_ roaring bitmaps. The majority of the
data will therefore have turned over within 30 days on its own, but I
plan on a follow-up PR that will transform open rows when the cron runs
so that we should be guaranteed to turn over completely within 30 days.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [X] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
## Testing
- [X] Added/updated automated tests
- Tests updated to accommodate the new format, and existing unchanged
tests act as proof against regression
- [X] QA'd all new/changed functionality manually
- Using a tool that dumps the `host_scd_data` rows data into a JSON file
(with the keys being entity_id+data and the values being host IDs on
that date), compared the data from main branch and this and confirmed
they're identical
- With a host count of ~9000, some of which have IDs of over 1,000,000,
the data storage requirements were:
* 82,558,976 bytes for dense
* 2,867,200 for roaring (a 96% decrease)
For unreleased bug fixes in a release candidate, one of:
- [X] Confirmed that the fix is not expected to adversely impact load
test results
- should hugely improve
- [X] Alerted the release DRI if additional load testing is needed
## Database migrations
- [X] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Implemented roaring bitmaps in historical data collection to optimize
bitmap handling for chart data aggregation
* Added encoding support to bitmap storage schema for flexible data
representation
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43895
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [ ] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [ ] QA'd all new/changed functionality manually
For unreleased bug fixes in a release candidate, one of:
- [ ] Confirmed that the fix is not expected to adversely impact load
test results
- [ ] Alerted the release DRI if additional load testing is needed
## Database migrations
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
## New Fleet configuration settings
- [ ] Setting(s) is/are explicitly excluded from GitOps
If you didn't check the box above, follow this checklist for
GitOps-enabled settings:
- [ ] Verified that the setting is exported via `fleetctl
generate-gitops`
- [ ] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [ ] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
## fleetd/orbit/Fleet Desktop
- [ ] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [ ] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [ ] Verified that fleetd runs on macOS, Linux and Windows
- [ ] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Self-service install/uninstall activities now render in passive voice,
omit an actor name, and include a “(self-service)” marker across feeds
* Global admins see a "My device" button on host user cards that opens
the end‑user device page in a new tab; the link is refreshed/generated
as needed
* Device page and browser tab header show the end‑user's name when
available (fallback: "My device")
* **Tests**
* Added/updated coverage for self‑service activity rendering and the "My
device" flow
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45659?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Closes#43637
## Summary
- Adds `min-width: 0` to `.side-nav__card-container` so the flex child
can shrink below its content width, enabling horizontal scroll on data
tables inside the side-nav layout at narrow viewports.
## Root cause
`.side-nav__container` uses `display: flex`, and its child
`.side-nav__card-container` has `width: 100%` but no `min-width`
override. Flex children default to `min-width: auto`, which prevents
them from shrinking below their content width. This means `overflow-x:
auto` on `.data-table__wrapper` never activates because the parent chain
stretches to fit the table content instead of constraining it.
## Changes
**`frontend/pages/admin/components/SideNav/_styles.scss`** -- added
`min-width: 0` to `.side-nav__card-container`.
## Manual testing
- [x] Built and ran Fleet server locally (`make fleet && ./build/fleet
serve --dev --dev_license`)
- [x] Navigated to **Controls > Disk encryption**
(https://localhost:8080/controls/os-settings/disk-encryption?fleet_id=2)
- [x] Enabled disk encryption for the team and confirmed the table
rendered
- [x] Resized browser to smallest supported viewport width
- [x] **Before fix:** table columns were squished/truncated with no
horizontal scrollbar
- [x] **After fix:** horizontal scrollbar appeared and table content
scrolled correctly
- [x] Verified other pages using the SideNav component (e.g., Settings)
were not affected
## Unit tests
- [x] Ran all related frontend test suites (`SideNav`, `DiskEncryption`,
`TableContainer`) -- 39 tests, all passing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Fixed side navigation layout to properly handle content overflow and
enable horizontal scrolling when navigation items exceed available
space.
* **Documentation**
* Added note: Disk Encryption > Disk encryption table now supports
horizontal scrolling on narrow viewports.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45736?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves#36417.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
## Testing
- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
## Manual tests performed
✅ MDM enrollment first, then fleetd enrollment (checked both activities
match serial and display name is preserved).
✅ fleetd enrollment first, then MDM enrollment (checked both activities
match serial and display name is preserved).
<img width="520" height="383" alt="activities_mdm_macos_enrollment"
src="https://github.com/user-attachments/assets/35c74612-ad80-4245-bfd9-20a3dc5e78bb"
/>
✅ Enrolled ABM iPad.
<img width="599" height="65" alt="Screenshot 2026-05-18 at 10 57 23 AM"
src="https://github.com/user-attachments/assets/b7ad552b-82af-4606-a860-361eedb97483"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Enrollment activities now show device serial numbers alongside host
display names, avoid duplicating the serial if already included, and
fall back to serial/generic messaging when no display name is available.
* Fleet enrollment entries no longer show an actor prefix, matching
other enrollment activity items.
* **Bug Fixes**
* Display names set by prior fleetd enrollment are preserved and no
longer overwritten during MDM enrollment.
* **Tests**
* Added and relaxed activity-feed tests covering enrollment message
variants.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45697?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes#45520
The Pub/Sub status-report and enrollment handlers dereferenced
device.HardwareInfo before any nil check, so a payload from Google's
Android Management API with hardwareInfo omitted panicked the request
goroutine.
Fixes#42874
Empty, whitespace-only, and missing `FLEET_JIT_USER_ROLE_*` SAML
attribute values are now treated as `null` (ignored) instead of
returning an error, matching the literal `"null"` workaround.
- **Adding vpp users table**
- **Adding ManagedAppleID to HostMDM tables to pull when installing vpp
apps to a BYOD user enrolled device**
- **Adding user create vpp apis**
- **Updating install application to support user enrolled devices**
- **Handling already installed gracefully**
- **Adding provision user logic**
- **Adding logic to associate assets on install**
- **Add license managemnt logic**
- **Adding self service ui**
- **Adding setup experience support**
- **Adding setup experience flow**
- **Fix issue with fleet's docker image in k8s environments (#44373)**
- **Changing how the appleid is captured to use idp mdm users**
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Account-based User Enrollment (iOS/iPadOS) supports VPP and in‑house
.ipa installs, including self‑service installs.
* Enrollment now applies the selected Setup experience automatically for
user‑enrolled hosts.
* Installs and license associations are scoped to account user
associations (user‑scoped installs).
* **Bug Fixes**
* Improved error messaging for license/association failures (including
per‑user device cap cases).
* Mobile UI: self‑service now shows user‑enrolled iOS/iPadOS apps.
* “Already installed” install results are treated as acknowledged
successes.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45202)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45330
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [X] Added/updated automated tests
so many
- [X] QA'd all new/changed functionality manually
- [X] was able to set gitops mode to enabled via `fleetctl gitops`
- [X] attempting to set gitops mode w/out repository_url in `fleetctl
gitops` failed w/ helpful error
- [X] attempting to set gitops mode w/ invalid repository_url in
`fleetctl gitops` failed w/ helpful error
- [X] attempting to set gitops exceptions in `fleetctl gitops` failed w/
helpful error
- [X] was able to unset gitops mode via `fleetctl gitops`
- [X] leaving `gitops:` blank in `fleetctl gitops` left the mode
untouched (it would retain its previous value)
## New Fleet configuration settings
- [ ] Setting(s) is/are explicitly excluded from GitOps
If you didn't check the box above, follow this checklist for
GitOps-enabled settings:
- [ ] Verified that the setting is exported via `fleetctl
generate-gitops`
it is not, but it's not a requirement here and leaving it out is a no-op
- [x] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [ ] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
it is not, nor should it be, as that would clear gitops mode on every
customer currently using it
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
n/a, you still need to be able to do gitops mode in the UI
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* GitOps mode and repository URL can now be set via GitOps YAML.
* **Bug Fixes**
* Server preserves existing GitOps settings during config updates;
requires repository URL when enabling and rejects unsupported exceptions
in GitOps YAML.
* **Tests**
* Added tests covering apply behavior, YAML validation, activity
emission on mode changes, and license-restricted rejection on free tier.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45537)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#43091
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
## Testing
- [ ] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
Was able to reproduce by enrolling a Ubuntu 25.10 host and mounting /
onto a different path like this:
```bash
sudo mkdir -p /tmp/snap.rootfs_TESTING
sudo mount --bind / /tmp/snap.rootfs_TESTING
```
Then, refetched vitals and saw the total disk space doubled:
<img width="211" height="108" alt="Screenshot 2026-05-07 at 9 40 12 PM"
src="https://github.com/user-attachments/assets/81cad4af-f146-4ea9-84e3-ee56eb426d8a"
/>
With the fix applied on this branch, refetched again and saw the correct
total disk space:
<img width="251" height="118" alt="Screenshot 2026-05-07 at 9 31 15 PM"
src="https://github.com/user-attachments/assets/cbb6f91b-320a-4d48-8583-f5fdf5a4fcd9"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Bug Fixes
- Resolved inaccurate total disk space reporting on Linux systems where
the same filesystem is bind-mounted at multiple paths.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43027
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Endpoints for fleet script batch executions now return HTTP 404 for
nonexistent batch execution resources.
* **Tests**
* Added tests to verify 404 behavior for missing batch execution
resources and related error handling.
* **Tools**
* Added a command-line load-test seeding/teardown utility to create and
remove configuration profiles and related test data.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45348)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#44422
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* The CLI command to list MDM commands now requires a --host flag;
calling it without a host will error.
* The API endpoint for listing commands now requires a host_identifier
parameter; requests without it are deprecated.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45476)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45491
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Deterministic MDM solution name reporting for osquery ingestions when
server URLs match multiple vendor substrings; resolves ambiguous matches
(e.g., jumpcloud.awmdm.com) and normalizes case.
* **Tests**
* Added unit tests covering empty/unknown inputs, multiple vendor
hostnames, case-insensitive URLs, and ambiguous-match resolution.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45496)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43997
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
## Database migrations
- [x] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [x] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [x] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
## fleetd/orbit/Fleet Desktop
- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [x] Verified that fleetd runs on macOS, Linux and Windows
- [x] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Configure Orbit to enable debug logging for a limited window on agent
enrollment; enrolled hosts receive debug/verbose behavior while the
window is active and it is reflected in agent config.
* **Chores**
* Added database column to record per-host debug-until timestamps and
datastore support to extend it safely.
* **Tests**
* Added integration and unit tests covering validation, enrollment
stamping, config generation, and runtime debug toggling.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45367)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Closes#43673
## Changes
Sorts the `/software/titles` endpoint by display name (when set) instead
of the internal `software_titles.name` (often an installer filename).
**3 changes in `server/datastore/mysql/software_titles.go`:**
1. **Order key mapping** (line 24): `"name"` sort key now maps to
`COALESCE(NULLIF(stdn.display_name, ''), st.name)` — uses display name
when set, falls back to `st.name`. `NULLIF` ensures cleared display
names (empty string) are treated as unset.
2. **Secondary sort** (line 579): Same `COALESCE(NULLIF(...))`
expression for tie-breaking when sorting by a non-name column.
3. **LEFT JOIN** (line 635): Joins `software_title_display_names` so the
COALESCE expressions can resolve.
## Testing
### Manual testing
Inserted test software titles with display names that sort differently
from installer filenames. Confirmed:
- Before fix: sorted by internal `st.name` (installer filename)
- After fix: sorted by display name, with fallback to `st.name` when no
display name is set
- Verified with `order_direction=asc`, `desc`, and secondary sort via
`hosts_count`
### Unit tests
`server/datastore/mysql/software_titles_sort_test.go` — 5 subtests (no
MySQL required):
- Order key mapping uses `NULLIF` for empty display names
- Secondary sort uses `NULLIF` for empty display names
- Primary name sort doesn't add redundant secondary name sort
- SQL template includes `display_names` join
- Empty display name falls back to `st.name` in sort expression
SQL fixture (`select_software_titles_sql_fixture.gz`) regenerated to
match updated queries.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Software titles listing now sorts by team-specific display names when
present, falling back to default names; tie-breaking and overall sort
behavior refined for more consistent ordering.
* **Tests**
* Added tests validating display-name sorting, correct fallback for
empty names, secondary sort behavior, and generated query structure to
ensure consistent results.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/44873)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#44804
This does not bulk every sql command, for simplicity.
It does not bulk profiles with variables in them, those containing
$FLEET_VAR_* placeholders. These still use individual command INSERTs
per host.
Remove commands are also not bulk-inserted because each removal requires
computing activeLocURIs which varies per profile and can result in nil
commands that should be skipped.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Reconciler now pre-builds and bulk-inserts Windows MDM commands for
non-variable install profiles, reducing repeated writes and improving
batching/enqueue efficiency.
* Streamlined enqueue + host-profile upsert flow to handle pre-inserted
commands and batch host processing.
* **Tests**
* Added tests for bulk command insertion, duplicate-command handling,
and end-to-end enqueue/upsert behavior.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45401)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#45258
The change to zero time is conventionally consistent with the rest of
the codebase, and produces zero observable behavior differences anywhere
I could find except for the cleanup SQL (which is the bug being fixed).
Decided not to do a migration since we do not expect hosts to actually
stick around with the `1970-01-02` value, and we have not heard about
this issue from customers.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Resolved an issue where hosts were being automatically deleted and
re-enrolled repeatedly when host expiry cleanup was enabled.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45471)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43984
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Updated the setup experience "Users" card to explain automatic
creation of local accounts via identity provider credentials (PSSO),
improving clarity for admins.
* **Documentation**
* Added a learn-more link to PSSO local account documentation from the
Users card.
* **Style**
* Improved spacing and description layout within the Users card for
better readability.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45023)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#43294.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [X] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
## Testing
- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed an issue where host team assignments were not persisting during
re-enrollment. Team assignments are now sticky and remain unchanged when
hosts re-enroll using a different team's enrollment secret, ensuring
consistent team ownership across re-enrollments.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45339)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes#44630
## Summary
- After a fresh Fleet install (`fleet prepare db` + `fleetctl setup`),
`enable_host_users` persisted as `false` despite the documented and
coded default being `true`.
- **Root cause**: During setup, `NewAppConfig` correctly saves
`enable_host_users: true`. However, the starter library then runs
`fleetctl gitops` with a template that has no `features` section. In
`DoGitOps`, when `features` is absent, an empty features map is created.
`enable_software_inventory` was explicitly defaulted to `true`, but
`enable_host_users` was not. The overwrite-mode PATCH then reset
`enable_host_users` to `false` (Go's bool zero value).
- Adds the same defaulting logic for `enable_host_users` as exists for
`enable_software_inventory`, in both the global and team config paths in
`DoGitOps`.
## Test plan
Reproduced locally before and after the fix with a Fleet server +
osqueryd agent (osquery 5.23.0):
**Before fix:**
1. Created a fresh database, ran `fleet prepare db`, started `fleet
serve --dev`, ran `fleetctl setup`.
2. Checked DB: `enable_host_users` was `false` (bug).
3. Enrolled a local osqueryd agent against the server.
4. Queried the host details API: `users` field was `null` (user
collection disabled).
5. Confirmed `features.enable_host_users: false` via `GET
/api/latest/fleet/config`.
**After fix:**
1. Same steps with the fixed binary.
2. Checked DB: `enable_host_users` was `true` (correct).
3. Enrolled a local osqueryd agent against the server.
4. Queried the host details API: `users` field contained 3 collected
users (root, sharonkatz, testuser) -- user collection working.
5. Confirmed `features.enable_host_users: true` via `GET
/api/latest/fleet/config`.
**Unit tests:**
- [x] `TestGitOpsFeatures` -- updated assertion to expect
`enable_host_users: true` when features are omitted from GitOps YAML
(was previously testing the broken behavior).
- [x] All `TestGitOps*` tests pass (`go test ./cmd/fleetctl/fleetctl/
-run TestGitOps`).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Bug Fixes
* Fixed default host user collection behavior on fresh Fleet installs.
Host user collection now correctly defaults to enabled, matching
documented settings and ensuring the host details page displays accurate
collection status information instead of incorrectly showing it as
disabled.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45393)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#41985
Fixed issue were hosts migrated from another MDM via the macOS Tahoe
end-user authentication flow had only the IdP email populated on host
details because the SCIM user mapping was never created at
OTA-enrollment ingest time.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#43640
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [x] QA'd all new/changed functionality manually
I figured out that the RunScriptModal was being re-rendered without any
user events or network calls after the 2s mark.
At first I thought the parent (ScriptModalGroup.tsx) could have been the
culprit since there's a lot going on there (lots of callback functions
passed to multiple modals).
It turns out that RunScriptModal is wrapped in React.memo to avoid
re-rendering but since some of its props changed in the parent
component, this caused it to re-render and close the Actions dropdown
randomly.
To detect which where the problematic props changing, I threw this code
at the top of RunScriptModal.tsx:
```react
const prev = useRef<any>({});
useEffect(() => {
const current = {
currentUser,
hostTeamId,
onClose,
page,
setPage,
hostScriptResponse,
isFetchingHostScripts,
isLoadingHostScripts,
isError,
onClickViewScript,
onClickRunDetails,
onClickRun,
isRunningScript,
isHidden,
};
const changed = Object.entries(current).filter(
([k, v]) => prev.current[k] !== v
);
console.log(
"RunScriptModal re-render. Changed props:",
changed.map(([k]) => k)
);
prev.current = current;
});
```
and the output was:
```
RunScriptModal re-render. Changed props:
(2) ['onClickViewScript', 'onClickRunDetails']
```
So I just wrapped those two in useCallback and that fixed the issue.
https://github.com/user-attachments/assets/f6eae13e-2a60-4fda-9468-2952acdedd58
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Bug Fixes
* Fixed the Actions dropdown in the Run script modal on the Host details
page auto-closing after 2-3 seconds.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45349)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes#43609 and #43566
Fixed bug were toggling GitOps mode was creating a spurious
update_conditional_access_bypass activity whenever Okta conditional
access was already configured with bypass_disabled=true.
**Related issue:** Resolves#44459
## Summary
Fixed an issue where the recovery lock password for a macOS host could
become unretrievable via the UI and API after the host was transferred
to a team with recovery lock disabled, even though the password was
still stored in the database.
## Root causes
Three bugs combined to produce the symptom:
- **Frontend visibility**: `canShowRecoveryLockPassword` gated the "Show
Recovery Lock password" action on the current team's
`enable_recovery_lock_password` setting and ignored the
`recoveryLockPasswordAvailable`
signal, so the UI option vanished whenever the host's new team had the
feature off.
- **API 404 on view**: `MarkRecoveryLockPasswordViewed` returned a
`notFound` error when its UPDATE matched zero rows. This happened as
soon as the `ClaimHostsForRecoveryLockClear` cron flipped the password
row's
`operation_type` from `install` to `remove` — causing `GET
/hosts/:id/recovery_lock_password` to 404 even though the password had
already been successfully retrieved and decrypted moments earlier in the
same
request.
- **Stale rotation deadline**: `ClaimHostsForRecoveryLockClear` left the
row's `auto_rotate_at` untouched when flipping to `remove`, so
subsequent reads still surfaced the pre-transfer view-deadline and the
UI
rendered a rotation banner promising an auto-rotation that the cron
(filtered on `operation_type='install'`) would never honor.
## Fix
- **Frontend**: updated `canShowRecoveryLockPassword` to also show the
action when a password is available, regardless of the team setting.
- **API**: changed `MarkRecoveryLockPasswordViewed` to return a zero
`time.Time` with no error when no install-state row exists. The service
skips the `AutoRotateAt` assignment in that case and explicitly nulls
any stale value loaded from the DB, so the response's `auto_rotate_at`
is omitted.
- **Data hygiene**: updated `ClaimHostsForRecoveryLockClear` to also set
`auto_rotate_at = NULL` when flipping a row to `remove`, since the
rotation deadline is meaningful only for install-state rows.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#44046
# Details
Updates GitOps to ensure that team labels are created before any
consumers (e.g. profiles, policies, software) that might use the labels
are applied. It does this by adding a new `afterTeamApply` callback
option to `ApplyGroup` that is called after team config is applied --
this is when team labels are now created, instead of after `ApplyGroup`
runs.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [X] Added/updated automated tests
- [ ] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed GitOps deployments failing when a label and a profile that
references it are created in the same run.
* Ensures the correct apply ordering so dry-run/log output shows label
application before profile application.
* **Tests**
* Added a regression test validating label → profile apply ordering to
prevent future regressions.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45194)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#42026
- Show "uninstall" button if the status is `installed` (or
`recently_installed`) which just reflects that the install script ran
successfully, not that the software title for the installer is in the
software inventory. For example, even with a no-op install script that
exits successfully the button will be available.
- Make the status clickable by removing the recentlyTakenAction check,
since that only represents the last install script that ran. This should
only really affect the `recently_installed` status (according to claude
at least).
This behaviour is already possible through the API, but it mostly
depends on the specific uninstall scripts if they will pass or fail when
the software doesn't even exist.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Uninstall option now appears for installers even when the host
inventory lacks a matching software entry, ensuring uninstall remains
accessible.
* **Tests**
* Added regression tests verifying the uninstall button is visible and
enabled for relevant installed states, including on personal device
pages.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45273)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#45256
In macOS:
before: 129 MB build/fleet, 58 MB build/fleetctl.
after: 86 MB build/fleet, 42 MB build/fleetctl.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
## Testing
- [X] QA'd all new/changed functionality manually. (Basic smoke testing
of the binaries in macOS.)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Optimized binary sizes for fleet and fleetctl releases.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45260)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes#43279
On the My device page (DeviceUserPage), the Location and MDM status rows
in the Vitals card rendered as <Button variant="link"> even though no
modal was wired up, so clicking did nothing while the link styling
implied otherwise.
Resolves#39727
Fixed bug on QueryDetailsPage's backPath() implementation, so the "Back
to host details" button does not followed the stale filteredQueriesPath
set when the user previously visited the reports page.
**Related issue:** Resolves#44798
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
## Testing
- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Performance Improvements**
* Optimized Windows MDM profile removal operations for improved
performance when managing device profiles.
* **Bug Fixes**
* Enhanced Windows profile handling during host team transfers to ensure
correct profiles are properly installed and removed based on team
configuration.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45203)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->