Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated managed application versions: Adobe Acrobat Reader
(26.001.21411), NordVPN (10.0.3), and Santa (2026.3) with corresponding
installer metadata and checksums.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated Cursor to version 3.0.16 with new installer and checksum.
* Updated Ollama to version 0.20.5 with new installer and checksum.
* Standardized JSON formatting for application category metadata across
multiple applications (010 Editor, 7-Zip, Airtame, Firefox, GIMP,
Notion, Postman, and PuTTY).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: iansltx <472804+iansltx@users.noreply.github.com>
Co-authored-by: Allen Houchins <32207388+allenhouchins@users.noreply.github.com>
Resolves#42714.
Zed + Opus 4.6; initial prompts (see additional ones in follow-on
commits):
---
Audit our existing Fleet Maintained App catalog. Look for:
1. Software that has the wrong identifiers associated (e.g. Abstract),
e.g. in `exists` queries
2. Software that has the version number in the name that leaks into the
`exists` query, e.g. 7-zip or 010 Editor or Airtame. These should be
fuzzy-matched.
For each affected app, revise input manifests to fix the issues. For
(1), revise apps.json if needed as well. Don't modify apps.json for (2)
cases.
---
Are there any discrepancies between bundle identifiers in input
manifests for Darwin apps and apps.json? If so, fix them.
---
Outputs will get overwritten by the ingester if neither the ingester nor
the input JSON files are changed. Make whatever changes need to be made
so that these edits survive an FMA ingestion cycle.
---
Revise `fuzzy` to allow specifying a custom value e.g. `Mozilal Firefox
% (ESR)` in addition to the existing true/false, then use that new
functionality to build unique queries for Firefox ESR.
---
Commit these changes, across multiple commits (there will be cases where
a changes to a single file will be spread across multiple commits, most
notably apps.json). Split commits out as follows:
1. All darwin-related changes
2. Windows switches to fuzzy matching + associated unique_identifier
changes
3. Revised handling for Firefox ESR
Prefix commit messages with "🤖 ".
---
The ingester and test changes should've gone in commit 3. Move them
there from commit 2.
---
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated application identifiers for Abstract, Amazon Chime, Beyond
Compare, and Teleport Suite to use correct bundle and package
identifiers.
* Enhanced Windows and macOS installation detection queries to match
multiple application versions using pattern matching instead of exact
version strings.
* **New Features**
* Added support for configurable fuzzy matching patterns to improve
application name matching flexibility.
* **Tests**
* Added tests validating fuzzy matching configuration unmarshaling and
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#42883
Added a new premium GET /api/_version_/fleet/rest_api endpoint that
returns the contents of the embedded `api_endpoints.yml` artifact.
Automated ingestion of latest Fleet-maintained app data.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Chores**
* Updated metadata configurations for 13 applications to recognize and
support their latest version releases, enabling proper version detection
and seamless update management. Updated applications include Brave
Browser, Calibre, Canva, Claude, Cursor, Granola, Ollama, Postman, Warp,
WhatsApp, Windows App, and Zed across macOS and Windows platforms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: mostlikelee <16102903+mostlikelee@users.noreply.github.com>
Add wingetVersionManifestDirs to ignore non-version subfolders (e.g.
"Portable") and only consider semver-style directories when selecting
the latest manifest. Use the filtered list in ingestOne, return an error
if no version dirs found, and update unit tests and test server paths to
reflect the versioned directory layout. Also bump Ollama macOS and
Windows outputs to v0.20.4, updating installer URLs, patched queries,
and SHA256 checksums.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved package version directory detection and filtering with
enhanced error handling when version manifest directories are not found,
providing clearer diagnostics.
* **Chores**
* Updated Ollama to version 0.20.4 on macOS and Windows platforms,
including updated checksums and installer references.
* **Tests**
* Added test coverage for version directory filtering and updated test
fixtures for manifest endpoint handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This pull request updates the handling of `.msix` package extensions in
the software installer logic to clarify support for Fleet-maintained
Windows apps and to ensure custom uploads of `.msix` files remain
unsupported. Test coverage is also expanded to explicitly check these
cases.
**Platform support changes:**
* Updated `packageExtensionToPlatform` in `software_installers.go` to
include `.msix` as a valid extension for Fleet-maintained Windows apps,
while maintaining that custom uploads of `.msix` files are still
rejected.
**Test coverage improvements:**
* Added test cases in `TestSoftwareInstallerPlatformFromExtension` and
`TestSofwareInstallerSourceFromExtensionAndName` to ensure `.msix` files
are correctly handled as unsupported for custom uploads.
[[1]](diffhunk://#diff-581f0146919318ed08c10123ad2f4585bfcfda40cba1dfcb20a65afc40259f32L164-R166)
[[2]](diffhunk://#diff-581f0146919318ed08c10123ad2f4585bfcfda40cba1dfcb20a65afc40259f32L214-R218)
Change Claude package from EXE to MSIX: update input metadata, replace
the installer script to provision the MSIX machine-wide and attempt
per-user registration, and rewrite the uninstaller to remove provisioned
and installed Appx packages (with best-effort package matching, timeout
handling, and safer error reporting). Update Windows output metadata:
bump version, update installer URL and sha256, and refresh
install/uninstall script refs to the new MSIX-based implementations.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves #
# 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
- [ ] QA'd all new/changed functionality manually
Bump Cursor to 3.0.12 and Docker to 4.67.0: update installer URLs and
SHA256 hashes, add 'patched' SQL queries for version checks in Windows
outputs, and normalize default_categories from "Developer Tools" to
"Developer tools" in winget inputs and outputs.
Related to #40309
Changes:
- Added ee/fleet-agent-downloader/ - A Sails app that has a single page
locked behind SSO that end-users can use to download a Fleet installer
hosted in an S3 bucket.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#42680
This manually modified outputs/apps.json since currently it only adds
new FMAs and cannot update existing ones from ingestion. It looks like
the install/uninstall scripts changed a bit, but I was able to install
and uninstall it successfully on a VM.
<img width="1150" height="48" alt="image"
src="https://github.com/user-attachments/assets/dad9f5f6-1f21-4169-aed5-33fb25cb666b"
/>
Patch policy for up to date version seems to work too.
<img width="863" height="49" alt="image"
src="https://github.com/user-attachments/assets/a706794d-885f-4a5c-abc5-b65c26ba7733"
/>
This pull request enhances the safety of the `linux_wipe.sh` script by
ensuring that destructive file operations do not affect network-mounted
filesystems. The changes introduce checks to detect network filesystems,
prevent accidental deletion of remote data, and improve the reliability
of wipe operations by avoiding crossing filesystem boundaries.
**Network filesystem safety improvements:**
* Added a `NETWORK_FS_TYPES` variable and functions to detect and
unmount network filesystems, preventing the script from deleting data on
NFS, CIFS, SMB, SSHFS, and similar mounts.
(`ee/server/service/embedded_scripts/linux_wipe.sh`)
[[1]](diffhunk://#diff-7ac85220cbd45e63481837a405dacf198822a4fbf885b88f89b9bc870c947fccR3-R4)
[[2]](diffhunk://#diff-7ac85220cbd45e63481837a405dacf198822a4fbf885b88f89b9bc870c947fccR17-R84)
* Introduced an `unmount_network_filesystems` function called before
wiping operations to unmount all detected network filesystems.
(`ee/server/service/embedded_scripts/linux_wipe.sh`)
* Added an `is_network_mount` function to skip wiping any path residing
on a network filesystem.
(`ee/server/service/embedded_scripts/linux_wipe.sh`)
**Safe file deletion enhancements:**
* Implemented a `safe_rm` function that ensures file deletions do not
cross filesystem boundaries, using `rm --one-file-system` or `find
-xdev` as a fallback. All destructive operations now use this wrapper.
(`ee/server/service/embedded_scripts/linux_wipe.sh`)
* Updated `wipe_non_essential_data` and `wipe_system_files` to use
`safe_rm` and to skip paths on network filesystems.
(`ee/server/service/embedded_scripts/linux_wipe.sh`)
These changes significantly reduce the risk of deleting data on remote
or shared filesystems during a wipe operation.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves #
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [ ] 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.
- [ ] 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
- [ ] 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))
---------
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#42368
# 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. For the overall story
- [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 pull request transitions the Windows Slack package from an
MSI-based installer to an MSIX-based installer, updating the ingestion
logic, install/uninstall scripts, and package metadata to support the
new format. It also updates the Slack version and the associated
detection queries to match the MSIX deployment. The most important
changes are:
**Slack Package Migration to MSIX:**
* Changed the Slack package definition in `slack.json` to use
`installer_type: msix`, set the installer scope to `user`, and
referenced new install/uninstall scripts tailored for MSIX.
* Updated the output package version to `4.49.81`, switched the
installer URL to the MSIX package, and adjusted detection queries to
match the new MSIX app name and publisher.
**Installer/Uninstaller Script Updates:**
* Added a new PowerShell install script (`slack_install.ps1`) that
provisions the MSIX package machine-wide and registers it for the
current user to improve inventory visibility.
* Added a new PowerShell uninstall script (`slack_uninstall.ps1`) that
removes both provisioned and per-user MSIX installations, with a timeout
and error handling.
**Ingestion Logic Enhancements:**
* Updated the `wingetIngester` logic to handle MSIX installers by
populating `ProductCode` from `PackageFamilyName` when needed, and to
extract only the prefix for MSI product codes.
* Extended the `installer` struct to include a `PackageFamilyName` field
for MSIX support.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#42853
This PR simply adds the `require_all_software_windows` config option. It
doesn't use it. The logic to use it will be hooked up in subsequent PRs.
The fleetctl TestIntegrationsPreview test is expected to fail since it
builds the server against main and doesn't know about our new config
option.
# 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`.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
## New Fleet configuration settings
- [x] Verified that the setting is exported via `fleetctl
generate-gitops`
- Not exported. generate-gitops does not export
require_all_software_windows (or require_all_software_macos either). The
generateControls function (generate_gitops.go) outputs a "TODO: update
with your setup_experience configuration" placeholder when any setup
experience config exists, rather than exporting individual field values.
This is a pre-existing limitation that applies equally to both fields -
not something introduced by our PR.
- [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)
- Yes. PR #42046 adds require_all_software_windows to both docs/REST
API/rest-api.md and docs/Configuration/yaml-files.md.
- [x] 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)
- Yes, it gets cleared to false - both when setup_experience: is present
without the field, and when setup_experience: is omitted entirely. This
is the same behavior as the existing require_all_software_macos field
- [x] Verified that any relevant UI is disabled when GitOps mode is
enabled
- Covered by #42854 (frontend subtask). The existing macOS checkbox in
InstallSoftwareForm.tsx:271 already checks gitOpsModeEnabled to disable
itself. The Windows checkbox to be added in #42854 will follow the same
pattern.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a Windows setup experience software requirement setting. When
enabled, Windows devices will cancel the Autopilot setup if any required
software installation fails.
* **Tests**
* Added test coverage for the new Windows software requirement
configuration.
<!-- 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#41741
# 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
* **New Features**
* Software setup items are now ordered using custom display names when
available.
* **Bug Fixes**
* Software installations now process sequentially for improved
reliability and predictability.
* Enhanced handling of missing installation tracking data to prevent
failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ian Littman <iansltx@gmail.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#38988
# 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.
- [ ] 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.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## 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)
- [ ] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#42673
Every manifest version now matches what hosts report. Here's the
before/after comparison:
| App | Before (Library) | After (Library) | Host Reports | Match? |
|-----|-----------------|----------------|-------------|--------|
| Android Studio | `2025.3.2.6` | `2025.3` | `2025.3` | Yes |
| Citrix Workspace | `25.11.1.42` | `25.11.1` | `25.11.1` | Yes |
| Elgato Stream Deck | `7.3.1.22604` | `7.3.1` | `7.3.1` | Yes |
| FileMaker Pro | `22.0.5.500` | `22.0.5` | `22.0.5` | Yes |
| Microsoft Auto Update | `4.82.26020434` | `4.82` | `4.82` | Yes |
| Opera | `129.0.5823.28` | `129.0` | `129.0` | Yes |
| Royal TSX | `6.4.2.1000` | `6.4.2` | `6.4.2` | Yes |
| Twingate | `2026.29.22575` | `2026.29` | `2026.29` | Yes |
| Microsoft OneNote | `16.107.26032211` | `16.107.2` | `16.107.2` | Yes
|
| Microsoft Outlook | `16.107.26032211` | `16.107.2` | `16.107.2` | Yes
|
| Microsoft PowerPoint | `16.107.26032211` | `16.107.2` | `16.107.2` |
Yes |
| Sublime Text | `4200` | `Build 4200` | `Build 4200` | Yes |
| Sublime Merge | `2123` | `Build 2123` | `Build 2123` | Yes |
| MySQL Workbench | `8.0.46` | `8.0.46.CE` | `8.0.46.CE` | Yes |
| Lens | `2026.3.251250` | `2026.3.251250-latest` |
`2026.3.251250-latest` | Yes |
The library version, the patch policy `version_compare`, and the
frontend comparison will all use versions that match what hosts actually
report.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [ ] 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.
- [ ] 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.
- [ ] 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))
Capture osascript output into a variable and compare it to "true" when
checking if an app is running. Updated quit_application and
quit_and_track_application to use app_running=$(osascript ...) and [[
"$app_running" != "true" ]] rather than relying on the command's exit
status. This makes the running check more reliable across osascript
behaviors and avoids depending on its exit code.
## Summary
**Mode 1 fix (structural):** Applies
\`MicrosoftVersionFromReleaseNotes\` to \`microsoft-outlook/darwin\`,
\`microsoft-powerpoint/darwin\`, and \`microsoft-onenote/darwin\` in the
FMA enrichment \`Funcs\` map, and regenerates output manifests with
corrected short versions (e.g. \`16.106.2\` instead of
\`16.106.26022219\`). Word and Excel already had this transformation;
this brings the remaining Office suite into parity.
**Mode 2 fix (reliability):** When the exact Homebrew build number
cannot be matched against Microsoft's release notes page (e.g., because
the page hasn't been updated yet for a newly published build), the
transformer now falls back to the base \`major.minor\` version (e.g.,
\`16.106\`) rather than leaving the raw build string in the manifest
(e.g., \`16.106.26021521\`). The raw build string caused a perpetual
"update available" loop because \`compareVersions("16.106.1",
"16.106.26021521")\` always evaluates to -1, regardless of how many
times the update is installed. Also adds a guard for versions with fewer
than 3 segments to prevent silent corruption.
**Root cause:** osquery reports installed app versions using
\`CFBundleShortVersionString\` (e.g. \`16.106.2\`), but the FMA manifest
stored the raw Homebrew build version (\`CFBundleVersion\`, e.g.
\`16.106.26022219\`). The mismatch caused Fleet to perpetually show
"update available" even after the latest version was installed.
Fixes#40647
## Test plan
- [x] Verify \`microsoft-outlook/darwin.json\`,
\`microsoft-powerpoint/darwin.json\`, and
\`microsoft-onenote/darwin.json\` outputs now contain short version
strings (e.g. \`16.106.2\`)
- [x] Verify \`microsoft-word/darwin.json\` and
\`microsoft-excel/darwin.json\` are unchanged
- [x] Run \`go test ./ee/maintained-apps/...\` — all tests pass
- [ ] Add a fleet-maintained Outlook/PowerPoint/OneNote app to a team;
confirm a host with the current version installed shows as up-to-date
(no spurious "update available")
- [ ] Confirm that if the ingester runs against a Homebrew build whose
number is not yet in Microsoft's release notes, the manifest stores the
base version (e.g. \`16.107\`) rather than the raw build string (e.g.
\`16.107.26031234\`)
---------
Co-authored-by: Dante Catalfamo <43040593+dantecatalfamo@users.noreply.github.com>
- [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] QA'd all new/changed functionality manually
Server log when SCIM ingestion receives a deactivation event for the
last admin:
```log
ts=2026-04-01T15:23:01Z level=error msg="failed to delete fleet user on deactivation" component=SCIM err="cannot delete last global admin"
```
Server response when attempting to demote last admin:
```json
{
"message": "Validation Failed",
"errors": [
{
"name": "global_role",
"reason": "cannot demote the last global admin"
}
],
"uuid": "1d110f56-25ac-47b8-bc96-982354474a87"
}
```
Server response when attempting to delete last admin:
```json
{
"message": "Validation Failed",
"errors": [
{
"name": "id",
"reason": "cannot delete the last global admin"
}
],
"uuid": "1448c2da-30e2-4652-a9a8-a01fc4f9b9c1"
}
```
---
## Original AI Summary
- Fixes a TOCTOU race condition where two concurrent admin operations
could bypass the last-global-admin guard, leaving zero admins and
permanently locking out the Fleet instance (fleetdm/confidential#14827)
- Introduces two new atomic datastore methods
(`DeleteUserIfNotLastAdmin`, `SaveUserIfNotLastAdmin`) that wrap the
admin count check and the write in a single MySQL transaction with
`SELECT ... FOR UPDATE`
- Fixes all four vulnerable code paths: service `DeleteUser`, service
`ModifyUser` (two demotion paths), and SCIM user deletion
## Test plan
- [X] Manual verification: single admin cannot be deleted or demoted
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#42492
Includes changes from running ingestions on all FMAs
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [ ] 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.
- [ ] 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.
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## 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
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#41710
Updates (only) macOS software title names on FMA catalog sync.
Updates software title names on installer upload for Windows FMAs with
an upgrade code.
# 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.
- [ ] 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.
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## 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