Amend Docker Desktop patch policy SQL - #50041
Conversation
There was a problem hiding this comment.
Pull request overview
Adjusts the Docker Desktop macOS patch-policy SQL so stale .back bundles created by Docker’s self-updater don’t cause Fleet’s “up to date” check to incorrectly fail.
Changes:
- Update Docker Desktop’s
patchedquery to exclude anyapps.pathcontaining.backanywhere (not only as a suffix). - Align the Homebrew ingester’s Docker Desktop special-case query with the updated pattern and clarify the rationale in comments.
- Update the corresponding ingester test expectation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| ee/maintained-apps/outputs/docker-desktop/darwin.json | Updates the stored Docker Desktop patch-policy SQL to ignore .back paths anywhere in the app path. |
| ee/maintained-apps/ingesters/homebrew/ingester.go | Changes the Docker Desktop patched-query override to use path NOT LIKE '%.back%' and documents the nested-app scenario. |
| ee/maintained-apps/ingesters/homebrew/ingester_test.go | Updates the test to match the new patched-query SQL. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
WalkthroughDocker Desktop patch-status SQL now excludes installed app paths containing 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #50041 +/- ##
==========================================
- Coverage 67.98% 67.97% -0.01%
==========================================
Files 3923 3923
Lines 250102 250102
Branches 13361 13361
==========================================
- Hits 170022 170015 -7
- Misses 64779 64786 +7
Partials 15301 15301
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Docker Desktop's self-updater leaves stale copies of the old app that osquery's apps table picks up by bundle_identifier: - /Applications/Docker.app.back - ~/Library/Application Support/com.docker.install/in_progress/Docker.app The install script now removes the staged in_progress copy (in addition to Docker.app.back) both before copying the new bundle and at the end of the script, so patch policies report correctly after an install. The uninstall script now removes Docker.app.back and the com.docker.install staging directory via post_uninstall_scripts, so uninstalled hosts with leftovers no longer report Docker as installed.
|
In general I am not a fan of amending our patch policies to address multiple copies of an app being reported on a device because it creates a false positive where the patch policy will now pass but there is still an old, vulnerable, or potentially exploitable version of the app on the device. I have improved the install and uninstall scripts to hopefully further remove these backup files, including one that gets created at We should merge this as-is for now since the additional |
Script Diff Resultsee/maintained-apps/outputs/docker-desktop/darwin.json=== Install // 2c3a200a -> de33e1ce ===
--- /tmp/old.IYnb4O 2026-07-28 13:44:45.300538859 +0000
+++ /tmp/new.sMMJVI 2026-07-28 13:44:45.300538859 +0000
@@ -126,11 +126,14 @@
if [ -d "$APPDIR/Docker.app" ]; then
sudo mv "$APPDIR/Docker.app" "$TMPDIR/Docker.app.bkp"
fi
-# Docker Desktop's own in-app updater leaves a Docker.app.back bundle alongside
-# Docker.app when it self-updates. osquery's apps table still picks up the
-# stale bundle by its bundle_identifier, which causes Fleet patch policies to
-# report Docker as out of date even after a successful upgrade.
+# Docker Desktop's own in-app updater leaves stale copies of the old app behind:
+# a Docker.app.back bundle alongside Docker.app, and a staged copy at
+# ~/Library/Application Support/com.docker.install/in_progress/Docker.app.
+# osquery's apps table still picks these up by bundle_identifier, which causes
+# Fleet patch policies to report Docker as out of date even after a successful
+# upgrade.
sudo rm -rf "$APPDIR/Docker.app.back"
+sudo rm -rf /Users/*/Library/"Application Support"/com.docker.install/in_progress/Docker.app
sudo cp -R "$TMPDIR/Docker.app" "$APPDIR"
relaunch_application 'com.electron.dockerdesktop'
mkdir -p /usr/local/cli-plugins
@@ -142,3 +145,8 @@
/bin/ln -h -f -s -- "$APPDIR/Docker.app/Contents/Resources/bin/docker-credential-desktop" "/usr/local/bin/docker-credential-desktop"
/bin/ln -h -f -s -- "$APPDIR/Docker.app/Contents/Resources/bin/docker-credential-ecr-login" "/usr/local/bin/docker-credential-ecr-login"
/bin/ln -h -f -s -- "$APPDIR/Docker.app/Contents/Resources/bin/docker-credential-osxkeychain" "/usr/local/bin/docker-credential-osxkeychain"
+# A staged self-update can fire during the quit/relaunch window above and
+# recreate the stale copies after the earlier removal, so delete them again
+# now that the new bundle is in place.
+sudo rm -rf "$APPDIR/Docker.app.back"
+sudo rm -rf /Users/*/Library/"Application Support"/com.docker.install/in_progress/Docker.app
=== Uninstall // 29483ade -> ba7543f2 ===
--- /tmp/old.TRE0qj 2026-07-28 13:44:45.319538993 +0000
+++ /tmp/new.xaSBWW 2026-07-28 13:44:45.320539000 +0000
@@ -171,6 +171,8 @@
sudo rm -rf '/Library/PrivilegedHelperTools/com.docker.socket'
sudo rm -rf '/Library/PrivilegedHelperTools/com.docker.vmnetd'
sudo rmdir '~/.docker/bin'
+sudo rm -rf '/Applications/Docker.app.back'
+sudo rm -rf /Users/*/Library/'Application Support'/com.docker.install
sudo rm -rf "$APPDIR/Docker.app"
sudo rm -rf '/usr/local/bin/docker-credential-ecr-login'
sudo rm -rf '/usr/local/bin/docker-credential-osxkeychain'
@@ -189,8 +191,11 @@
trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.electron.dockerdesktop.sfl*'
trash $LOGGED_IN_USER '~/Library/Application Support/com.bugsnag.Bugsnag/com.docker.docker'
trash $LOGGED_IN_USER '~/Library/Application Support/Docker Desktop'
+trash $LOGGED_IN_USER '~/Library/Application Support/docker-secrets-engine'
trash $LOGGED_IN_USER '~/Library/Caches/com.docker.docker'
trash $LOGGED_IN_USER '~/Library/Caches/com.plausiblelabs.crashreporter.data/com.docker.docker'
+trash $LOGGED_IN_USER '~/Library/Caches/Docker Desktop'
+trash $LOGGED_IN_USER '~/Library/Caches/docker-secrets-engine'
trash $LOGGED_IN_USER '~/Library/Caches/KSCrashReports/Docker'
trash $LOGGED_IN_USER '~/Library/Containers/com.docker.docker'
trash $LOGGED_IN_USER '~/Library/Containers/com.docker.helper' |
That is a very good point. Thanks! |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
ee/maintained-apps/inputs/homebrew/docker-desktop.json:10
post_uninstall_scriptscurrently removes/Users/*/Library/Application Support/com.docker.install(the entire directory) for all users. The install script’s rationale only requires deleting the staged app bundle at.../com.docker.install/in_progress/Docker.app, so this broader deletion is potentially more destructive than necessary. Consider narrowing the cleanup path to the specific staged bundle and regenerate the corresponding output manifest/scripts.
"post_uninstall_scripts": [
"sudo rm -rf '/Applications/Docker.app.back'",
"sudo rm -rf /Users/*/Library/'Application Support'/com.docker.install"
],
**Related issue:** Resolves #50875 Docker Desktop on macOS never reported an installed version or "Installed" status, and offered "Install" on hosts that already had it. ## Root cause The FMA's `unique_identifier` was `com.electron.dockerdesktop`, which belongs to the embedded Electron bundle. The installed app reports a different identifier: | Path | CFBundleIdentifier | |---|---| | `/Applications/Docker.app` | `com.docker.docker` | | `/Applications/Docker.app/Contents/MacOS/Docker Desktop.app` | `com.electron.dockerdesktop` | The identifier was changed from `com.docker.docker` → `com.electron.dockerdesktop` in #37670 (Jan 5) as "the new bundle identifier … reflecting the current packaging". The top-level bundle never changed. That was latent until #47831 (#44199, Jul 9) added an embedded-bundle filter to the macOS software inventory query in `server/service/osquery_utils/queries.go`: ```sql FROM apps WHERE path NOT LIKE '%.app/Contents/%' ``` `/Applications/Docker.app/Contents/MacOS/Docker Desktop.app` matches that pattern, so the only row carrying the embedded identifier is filtered out and inventory keeps just `/Applications/Docker.app` → `com.docker.docker`. Since FMA↔inventory matching is by bundle identifier (`addSoftwareTitleToMatchingSoftware`), the title the FMA owns had zero installed versions. **Patch policies kept passing**, because they run the FMA's `exists`/`patched` SQL directly against the host's *unfiltered* `apps` table. That's also why #50041 needed a `.back` path exclusion, and why patch status and the software UI have disagreed since July. ## What changed **Catalog** — `unique_identifier` is now `com.docker.docker`, with `docker-desktop/darwin.json` regenerated. `outputs/apps.json` needed a hand-edit because `updateAppsListFile` (`cmd/maintained-apps/main.go`) only appends new apps and never updates an existing entry's identifier — filed separately. The remaining `com.electron.dockerdesktop` references are intentional and untouched: the install script's quit/relaunch targets (the Electron bundle is what responds to AppleScript) and the cask's zap paths. The `.back` exclusion in the patched query also stays — `/Applications/Docker.app.back` is a *top-level* bundle reporting `com.docker.docker` at a path the nested-bundle filter does not match, so a stale `.back` would otherwise show a false "Update available". **Migration** (`20260810152924_FixDockerDesktopBundleIdentifier`) — `fleet_maintained_apps` self-heals on catalog sync (`UpsertMaintainedApp` updates `unique_identifier` on duplicate slug) and `ReconcileMaintainedAppSoftwareNames` renames the existing "Docker" title, but an already-added installer's `software_installers.title_id` binding does not: - **No `com.docker.docker` title yet** → relabel the stale title in place, so everything already pointing at it stays correct. - **Title already exists** (the normal case — any host with Docker creates it) → merge the stale title into it: installer, install history, queued installs, patch policy, `software.title_id`, and per-team settings (icons, display names, pins, update schedules), then drop the stale title. ## Notes for reviewers - **Teams that already have an installer on the target title are skipped** rather than ending up with two installers on one title. `dedup_token` is the *version* for FMAs and the *storage_id* otherwise, so `idx_software_installers_dedup` would not have caught that collision. Those teams keep the pre-migration state instead of having data silently reshaped. - **The stale title is only deleted once nothing depends on it.** `fk_software_installers_title` is `ON DELETE SET NULL`, so deleting it while an installer still pointed at it would orphan that installer. Note also that `fk_patch_software_title_id` is `ON DELETE CASCADE` — re-pointing the patch policy is what keeps it from being deleted outright. - **Dangling-reference check:** the only title-referencing columns without an FK to `software_titles` are `software.title_id` (re-pointed), `software_titles_host_counts` (deleted; the cron recomputes), and `kernel_host_counts` / `in_house_app_install_tokens`, neither of which can hold a macOS app title. - **Naming lags briefly.** The existing title is named "Docker" (from osquery); `ReconcileMaintainedAppSoftwareNames` renames it to "Docker Desktop" on the next catalog sync, so there is a window after upgrade where the name is still "Docker". I left that to the sync rather than duplicating the rename logic in the migration. - **This fixes one app, not the class.** Any other macOS FMA keyed on a nested bundle fails the same silent way, and a green patch policy will not reveal it. An audit is filed separately. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements). Table/column names in the migration's generated SQL come from hardcoded struct literals, never from data; all values are placeholders. ## Testing - [x] Added/updated automated tests Five migration tests cover: relabel-in-place, merge-into-inventory-title, duplicate per-team settings dropped, teams with an existing installer skipped (and the stale title consequently retained), and no-op when the FMA was never added. The merge test also asserts `updated_at` is not restamped. Updated the homebrew ingester test expectations for the new identifier. Verified: full `server/datastore/mysql/migrations/tables` suite passes (201s), `ee/maintained-apps/...`, `cmd/maintained-apps/...`, and the FMA datastore tests pass, `make lint-go-incremental` clean. Root cause was confirmed against real bundles rather than inferred — `PlistBuddy` on both Docker bundles for the identifiers above, and `lsregister -dump` to confirm LaunchServices registers the nested bundles (which is why the raw `apps` table sees them and patch policies pass). - [ ] QA'd all new/changed functionality manually Needs QA on a real instance: add the Docker Desktop FMA, confirm the installed version and "Installed" status appear on a host that already has it, and confirm an upgrade over an instance that already had the FMA added re-points the existing installer. For unreleased bug fixes in a release candidate, one of: - [x] Confirmed that the fix is not expected to adversely impact load test results The migration touches only rows tied to a single software title, and is a no-op on instances that never added the Docker Desktop FMA. ## 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. Five of the written tables have `updated_at` as `ON UPDATE CURRENT_TIMESTAMP`: `software_installers`, `host_software_installs`, `software_install_upcoming_activities`, `policies`, and `software_title_team_pins`. Since this re-points a foreign key rather than modifying the records, each statement assigns `updated_at = updated_at` so MySQL leaves them alone, with a test asserting it. (Bumping them would have been cosmetic — none of these columns drives ordering, scheduling, or invalidation; policy membership uses `policy_membership.updated_at` and `hosts.policy_updated_at`, and the activity feed orders by the activities table — but preserving them is more faithful to what the migration actually does.) - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). No columns added or altered; this is a data-only migration. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved macOS Docker Desktop detection so installed versions and “Installed” status are reported accurately. * Ensured existing Docker Desktop installations and upgrade history remain correctly associated after detection updates. * Improved handling of stale application bundles during patch evaluation. * **Maintenance** * Updated detection data and migration coverage to support the corrected Docker Desktop identification. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
My workstation has Docker Desktop 4.84.0 (latest as of today) and was incorrectly failing the "macOS - Docker Desktop up to date" patch policy.
Summary by CodeRabbit
Bug Fixes
.backanywhere in the path, avoiding incorrect patching of nested/backup bundles.Improvements
Docker.app.backartifacts and related staged in-progress update copies (including cleanup during upgrade timing).Tests
.backpath filtering behavior.