<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** NA
Cherry-pick of #48451 ("Adding changes for Fleet v4.89.0") from
`rc-minor-fleet-v4.89.0` into `main`.
This brings the v4.89.0 CHANGELOG entry and the corresponding `changes/`
cleanup into main. The CHANGELOG conflict was resolved by placing the
4.89.0 section above the existing 4.88.1 section (keeping main's 4.88.1
date of Jul 10, 2026).
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added vulnerability filtering by CVSS score and exploitability in
Fleet Desktop.
* Added default enrollment behavior for fleet-owned Apple devices.
* Added additional filtering options to the Vulnerability Exposure
chart.
* Improved certificate template variables, including IdP values and host
platform.
* **Bug Fixes**
* Fixed policy selection pagination, stale policy/report details, and
missing-host reporting.
* Corrected SSO and email links when Fleet is hosted under a URL
subpath.
* Improved Windows profile validation and MDM command labeling.
* Fixed several display and accessibility issues, including host counts,
checkbox wording, and dark-mode badges.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#38806
Add an IT-admin naming convention for macOS/iOS/iPadOS hosts. An admin
sets a name template (e.g. "iPad $FLEET_VAR_HOST_HARDWARE_SERIAL") under
Controls > OS settings > Host names for a fleet or for "No team"; Fleet
resolves it per host, delivers it via an Apple `Settings`/`DeviceName`
MDM command, renames its own record on ACK, then verifies the name via
osquery (macOS) or a DeviceInformation refetch (iOS/iPadOS). Clearing
the template stops enforcement without renaming any host. Fleet Premium
only, mirroring disk encryption.
Fixing an update of the main go.mod breaking the tool.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated internal tooling dependencies to support improved
compatibility and functionality.
<!-- 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:** #43667
# Summary
Renames the unreleased GitOps field `setup_experience_platforms` to
singular `setup_experience_platform`, accepting a comma-separated string
of `darwin`/`linux` (rejecting the `macos` alias) to match the
query/policy/label `platform` convention.
# Checklist for submitter
- [ ] 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
- [ ] QA'd all new/changed functionality manually
## New Fleet configuration 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)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Updated software setup-experience platform configuration to use a
single comma-separated `setup_experience_platform` value.
* Platform values are normalized for casing and whitespace,
deduplicated, and validated against supported platforms.
* macOS setup selections now use the canonical `darwin` value; the
`macos` alias is rejected.
* GitOps-generated configurations now use the updated field name and
platform format.
* **Bug Fixes**
* Improved validation messages for invalid setup-experience platform
values.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Two reasons:
- It's a testing/QA tool, so it should be under `tools/`
- Reduce security-noise because it's just an internal tool (all findings
under tools/ should be ignored).
Failing dependency review expected because of the security findings in
the docker Go packages. (Which can be fixed/updated when a patch is
issued but without urgency because this is an internal tool.)
## Testing
- [x] QA'd all new/changed functionality manually
Ran:
```
cd tools/upgrade
FLEET_VERSION_A=v4.87.1 FLEET_VERSION_B=v4.88.1 go test
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
* **New Features**
* Added an end-to-end upgrade test scenario across two Fleet versions.
* Added a Docker Compose-based upgrade environment (Fleet, MySQL, Redis,
osquery) with local TLS certs/keys and osquery flags.
* **Tests**
* Added automated Fleet readiness checks and host enrollment
verification before and after upgrade.
* **Chores / Security**
* Updated the database upgrade test workflow and Go module tooling for
the new upgrade test setup.
* Adjusted secret scanning allow-rules and refreshed Go dependencies for
the upgrade module.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Released a new Fleet chart and application version.
* Updated deployment defaults to use the latest Fleet container image.
* **Tests**
* Adjusted release-candidate branch expectations to match the new
version.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Adds the **4.89.0** load test metrics artifacts, following the existing
`tools/loadtest/metrics/runs/` conventions.
### Baseline — `runs/baseline/489loadtest/`
18h run on a fresh RC instance (no data).
- `489loadtest-2026-07-10-210313Z-18h.json` / `.md`
### Migration — `runs/migration/487to489mig/`
4.87 → 4.89 migration, before vs. after.
- `487to489mig-2026-07-10-162812Z-1h.{json,md}` — pre-migration (1h
window)
- `487to489mig-2026-07-10-192738Z-130m.{json,md}` — post-migration (130m
window)
## Results
| Run | Fleet errors | ALB 5xx | Abnormal stops | Threshold checks |
|-----|:---:|:---:|:---:|---|
| Baseline (18h) | 0 | 0 | 0 | RDS Writer Deadlocks avg 0.13
(occasional, retried) |
| Migration pre (1h) | 0 | 0 | 0 | ✅ all within thresholds |
| Migration post (130m) | 0 | 0 | 0 | RDS Writer Deadlocks avg 0.08
(occasional, retried) |
The only flag is a near-zero average of occasional RDS writer deadlocks
(MySQL retries these); everything else is within expected range and
holds steady across the migration. Full per-metric comparison
(`compare-metrics.sh`) is posted on the release QA issue.
Data only — no code changes.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Added baseline and migration load-test performance reports.
* Included infrastructure, database, Redis, load balancer, network,
container health, error, and SQL performance metrics.
* Added reports covering multiple test durations and migration intervals
for improved performance analysis.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#43667
# Summary
Adds a `setup_experience_platforms` field to the GitOps software package
spec so `.sh` script-only installers can be selected for macOS setup
experience declaratively. Reconciles the cross-platform selection table
on every batch apply.
# 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] QA'd all new/changed functionality manually
## New Fleet configuration settings
- [x] Verified that the setting is exported via `fleetctl
generate-gitops`
- [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)
- [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)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added declarative `setup_experience_platforms` to software package
definitions to control “setup experience” targets, including selecting
script-only installers for macOS (mapped appropriately).
* Batch uploads now propagate these cross-platform selections and
reconcile installer cross-entries.
* **Bug Fixes**
* Improved platform normalization (trimming, casing, alias mapping),
deduplication, and extension-specific validation.
* Enhanced update behavior: omitting the field leaves existing
selections unchanged; providing an empty list clears them, with correct
setup/installation timing.
* **Tests**
* Added unit and integration coverage for normalization and batch
re-apply/reconcile behavior (nil vs empty, idempotency, mixed updates,
and validation failures).
<!-- 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#48570
# 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. Added in a previous PR
- [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
* **New Features**
* Added end-to-end Apple DDM asset support in GitOps, including export
and GitOps parsing for `macOS settings` assets.
* Introduced Apple DDM asset management APIs
(list/get/download/create/delete) plus a batch set operation with
dry-run.
* **Bug Fixes**
* Improved Apple MDM/DDM reconciliation so referenced asset updates
trigger re-delivery via asset-aware tokening.
* Added safer validation around asset type changes and deletion
conflicts when assets are still referenced.
* **Tests**
* Expanded unit and integration coverage for asset parsing, upload/apply
behavior, reconciliation, and access control.
<!-- 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:** NA — resolves high-severity code-scanning alerts in
`tools/dibble`
## Problem
The dibble seeder committed 14 installer fixtures under
`tools/dibble/pkg/seed/data/installers/` and bundled them into the
binary with
`//go:embed`. The `.exe`/`.msi`/`.deb`/`.rpm` files tripped **8
high-severity
"Binary-Artifacts" code-scanning alerts** on `main`.
11 of the 14 are byte-identical to fixtures already in
`server/service/testdata/software-installers/`, but `go:embed` can't
reference
files outside the package (no `..`, no symlinks), so the copies couldn't
simply
point at the originals.
## Change
Replace the embed with an on-demand fetch that runs **only when seeding
software** (`SoftwareCustom`):
- Fixtures are downloaded, **SHA-256 verified** against a pinned
manifest, and
cached under the user cache dir (`os.UserCacheDir()/dibble/installers`)
so
repeat runs stay offline.
- Fixtures shared with Fleet's tests are pulled from `testdata` via
`raw.githubusercontent.com` at a **pinned commit**; the 7-Zip and
python-manager installers come from their **upstream URLs**.
- No binaries remain committed in this module.
Checksums for all sources were verified to match the
previously-committed bytes
exactly, and the download + verify + cache path was smoke-tested
locally.
## Tradeoff
`dibble software custom` now requires network access on first use
(downloads are
cached afterward). This only affects the software-seeding path; all
other
seeders are unchanged.
# Checklist for submitter
- [x] Input data is properly validated (downloaded fixtures are rejected
unless their SHA-256 matches the pinned manifest), `SELECT *` is
avoided, SQL injection is prevented, JS inline code is prevented, 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 (HTTP client uses a 2-minute timeout; no retry loop).
## Testing
- [x] QA'd all new/changed functionality manually (verified download,
checksum verification, and cache reuse for testdata- and upstream-hosted
fixtures)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Installer fixtures are now downloaded on demand and cached locally for
faster repeat runs.
* Expanded installer fixture coverage, including additional
Windows-signed installers for improved platform support.
* **Bug Fixes**
* Added SHA-256 integrity verification for cached and newly downloaded
installer fixtures.
* Improved reliability and safety by re-downloading when cache contents
don’t match and by writing downloads atomically to avoid partial files.
* **Chores**
* Updated indirect dependency versions related to OpenTelemetry and
`golang.org/x/*`.
<!-- 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#45524
# 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
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
- [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`).
## 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:
- [x] Verified that the setting is exported via `fleetctl
generate-gitops`
- [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)
- [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)
- [x] Verified that any relevant UI is disabled when GitOps mode is
enabled
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Apple Platform SSO (PSSO) for macOS with device registration,
sign-in, and public discovery (JWKS + Apple app-site association)
protected by single-use nonces.
* Added Apple account provisioning (Platform SSO password sync)
configuration with masked client-secret handling and GitOps support.
* Added a host-scoped PSSO device registration token variable for Apple
MDM profile generation.
* **Bug Fixes**
* Fixed macOS packaging to correctly build, embed, and sign the Platform
SSO extension.
* Resetting device Apple MDM data now also clears stored PSSO enrollment
records.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Magnus Jensen <magnus@fleetdm.com>
Resolves#48954.
- [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
Tested a package generated with new `fleetctl` on Fedora 43, Ubuntu
25.04, and Omarchy.
## 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] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [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
## Summary of changes
* **Bug Fixes**
* Improved Linux RPM packaging consistency, including more reliable
output filename normalization and correct platform metadata.
* Ensured RPM metadata extraction stays aligned with the updated
packaging flow.
* **Tests**
* Added coverage for RPM filename normalization edge cases.
* Updated a CPE rule validation test expectation to match the new
error-string format.
* **Chores**
* Upgraded packaging tooling and refreshed Go dependencies.
* **Security**
* Removed a previously ignored CVE entry from vulnerability scan ignore
settings.
<!-- 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:** #43544.
Moves `fleet-mcp` from `tools/fleet-mcp/` to `cmd/fleet-mcp/`. It is
becoming a production server used by customers, so it now lives under
`cmd/` alongside the other Fleet binaries.
Per the module strategy chosen for this move, it **remains a standalone
Go module** (keeps its own `go.mod`/`go.sum` and isolated deps such as
`mark3labs/mcp-go`, `logrus`, `gorilla/websocket`, `godotenv`) — the
root `github.com/fleetdm/fleet/v4` module is unchanged.
### What changed
- `git mv tools/fleet-mcp/ → cmd/fleet-mcp/` (history preserved as
renames).
- Updated all path references:
- Root `Makefile` `update-go` module list.
- `.github/workflows/test-fleet-mcp.yml` — trigger paths,
`go-version-file`, `working-directory`.
- `.github/dependabot.yml` — gomod directory.
- `cmd/fleet-mcp/render.yaml` — `rootDir`.
- `cmd/fleet-mcp/README.md`, `Makefile`, `schema.go` — path
comments/links.
- `articles/fleet-mcp.md` — README link.
- Removed the `fleet-mcp/` row from `tools/README.md`.
### Follow-up (not in this PR)
- The Render service's Blueprint file path must be updated from
`tools/fleet-mcp/render.yaml` to `cmd/fleet-mcp/render.yaml` in the
Render dashboard.
## Testing
- `go build .` in `cmd/fleet-mcp` — OK
- `go test -race -count=1 ./...` — `ok fleet-mcp`
- [x] QA'd all new/changed functionality manually
Resolves#48988.
I ran `make update-go version=1.26.5`.
- [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
Fleet:
<img width="301" height="102" alt="Screenshot 2026-07-09 at 8 41 49 AM"
src="https://github.com/user-attachments/assets/baf76ce7-6192-4506-a9db-52f5318939ee"
/>
fleetctl:
```
fleetctl --version
fleetctl - version orbit-v1.57.0-402-ge3d0c005dc
branch: 48988-update-go-1.26.5
revision: e3d0c005dc6698c024ad47a124c99e4f264855a0
build date: 2026-07-09
build user: lucas
go version: go1.26.5
```
Also verified orbit in Linux:
<img width="582" height="121" alt="Screenshot 2026-07-09 at 8 51 55 AM"
src="https://github.com/user-attachments/assets/65672676-8010-45a1-8c28-9f9959e72134"
/>
## 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 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
* **Chores**
* Updated the project and all included tooling modules to Go 1.26.5.
* Refreshed build images used by desktop Linux, load testing, and
related utilities to the newer Go toolchain.
* Updated change log entries to reflect the Go version bump.
* **Bug Fixes**
* Improved the automation that refreshes Go-pinned Docker image
references to resolve and apply correct digests, helping prevent broken
build images.
<!-- 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:** Relates to #43544
The Fleet MCP calls the legacy `/api/v1/fleet/teams` routes for fleet
and policy lookups. Fleet's current API endpoints catalog only lists the
renamed `/fleets` routes, so an endpoint-restricted api-only user cannot
be granted `/teams` and those calls return 403. This switches the MCP to
the `/fleets` paths, which return the same response shape, so fleet
resolution and per-fleet policy compliance work under a least-privilege
token. Verified against a running Fleet.
## 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**
* Team-related Fleet data now loads from the correct service endpoints,
improving policy and compliance views.
* Policy listings and policy detail checks for teams should now return
the expected results.
* Updated test coverage to match the revised Fleet route behavior.
<!-- 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:** NA — resolves high-severity code-scanning alerts in
`tools/`
Bumps the outdated `golang.org/x/net` and `golang.org/x/crypto` indirect
dependencies in the four `tools/` Go modules to clear 39 high-severity
code-scanning (SCA) alerts on `main`. Target versions match the root
Fleet
module.
| Module | x/net | x/crypto |
| --- | --- | --- |
| `tools/dibble` | v0.53.0 → **v0.55.0** | v0.50.0 → **v0.52.0** |
| `tools/hangar` | v0.53.0 → **v0.55.0** | v0.50.0 → **v0.52.0** |
| `tools/terraform` | v0.48.0 → **v0.55.0** | v0.46.0 → **v0.52.0** |
| `tools/github-manage` | v0.38.0 → **v0.55.0** | — |
CVEs cleared:
- **x/net v0.55.0**: CVE-2026-25681, -27136, -33814, -39821, -42502
- **x/crypto v0.52.0**: CVE-2026-39827, -39828, -39829, -39830, -39832,
-39835, -42508, -46595, -46597
All four modules `go mod verify` clean and build. Dependency-only change
to
internal dev tooling — no product code, no user-visible behavior.
> The remaining 8 high-severity alerts in `tools/` are OpenSSF Scorecard
> "Binary-Artifacts" findings for embedded dibble seed installers; those
are
> tracked separately and not addressed here.
# Checklist for submitter
- [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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated several bundled Go dependencies across internal tooling to
newer versions.
* This includes refreshes to common networking, cryptography, text, and
system packages, plus one added telemetry-related dependency.
* No user-facing features or behavior changes were introduced.
<!-- 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#48746
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Added a CI workflow to run build and race-enabled tests for dibble
changes.
* Included a dependency consistency check to ensure dibble’s Go module
files stay tidy.
* Configured CI concurrency to cancel in-progress runs for newer
changes.
* Updated dibble’s Go dependencies (indirect) to newer versions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Fully resolves
https://github.com/fleetdm/fleet/issues/34591.
## Testing
- [X] QA'd all new/changed functionality manually.
<img width="533" height="454" alt="Screenshot 2026-07-03 at 10 40 37 AM"
src="https://github.com/user-attachments/assets/892fb548-21c6-467c-b270-65f1c9338fdc"
/>
<img width="1287" height="259" alt="Screenshot 2026-07-03 at 10 41
55 AM"
src="https://github.com/user-attachments/assets/d3528b0c-0d05-4ace-8512-ab363241b97c"
/>
<img width="1077" height="123" alt="Screenshot 2026-07-03 at 10 41
46 AM"
src="https://github.com/user-attachments/assets/249e80de-320c-48f3-962a-59c98c736c54"
/>
<img width="725" height="208" alt="Screenshot 2026-07-03 at 10 41 32 AM"
src="https://github.com/user-attachments/assets/361764cf-26fc-4a44-b5d6-489d883a392b"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added CachyOS Linux to rolling-release OS detection and reporting.
* Added a CachyOS fleetd package/image variant and a new CachyOS fleetd
service for local testing.
* **Bug Fixes**
* Improved rolling-release OS version labeling for host “Vitals”
display.
* Updated OS inventory normalization so CachyOS is aggregated with Arch
Linux, including correct “rolling” version handling.
* **Tests**
* Expanded OS version ingest test coverage for rolling-release and
CachyOS scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
The `get_policies` MCP tool wasn't returning each policy's osquery SQL,
making it impossible to diagnose policy behavior via MCP — you had to
fall back to `curl` against `GET /api/v1/fleet/global/policies/{id}` to
read the `query` field.
Root cause: the `Policy` struct in
`tools/fleet-mcp/fleet_integration.go` didn't declare a `Query` field,
so Go's JSON decoder silently dropped the key from the Fleet API
response. One-line fix on the struct; the same struct backs both the
global path and the per-team fan-out, so both are covered.
Purely additive — no existing field changes shape, name, or type.
# Checklist for submitter
## 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
* **New Features**
* Fleet policies now include a query field so the actual policy
query/SQL content is available with policy metadata.
* **Tests**
* Added integration-style test coverage to confirm the query field is
parsed and returned (including empty queries) and that policy responses
contain the expected entries.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45513)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: nulmete <nicoulmete1@gmail.com>
osquery [5.23.1](https://github.com/osquery/osquery/releases/tag/5.23.1)
was released by osquery publicly today, this updates our schema with the
changes in it.
- [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 schema support for certificate `subject2` and `issuer2` fields
on Linux and macOS.
* Documentation generation and download tooling now target osquery
`5.23.1`.
* **Bug Fixes**
* Clarified the `process_open_handles` table behavior by removing
outdated default-process wording.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Relates to #43544Resolves#45901
Relates to #45902 (repo hygiene specifically)
## Summary
Fixes two production bugs in `tools/fleet-mcp` surfaced via dogfood
usage, plus mirrors PR #45513 so the policy-SQL field is available on
this branch.
### Bug A — `fleet=<team>` filter silently dropped on platform/label
calls
`get_endpoints fleet=Workstations platform=windows` returned hosts from
every team. Fleet upstream `/api/v1/fleet/labels/:id/hosts` accepts
`?team_id=` but discards it: `applyHostLabelFilters` in
`server/datastore/mysql/labels.go` reads the RBAC `filter.TeamID`, never
`opt.TeamFilter` parsed from the URL. The MCP now intersects label-path
results client-side by `host.TeamID` via the new
`filterEndpointsByTeamID` helper so the caller's `fleet=` scope is
actually applied. Operational-quirk comment updated to match real
upstream behavior.
### Bug B — `Total` field showed global count regardless of filters
`get_endpoints fleet=Workstations` reported `Total: <global>` even
though the returned slice was correctly team-scoped — `GetHostCount`
accepts no filters. New `GetHostCountWithFilters` mirrors the listing
path's filter dimensions through a shared `buildHostListParams` helper
so list + count stay in lockstep:
- No label/platform →
`/hosts/count?team_id=…&status=…&query=…&policy_id=…&policy_response=…`
(Fleet's count endpoint honors these).
- Label/platform → reuses the listing fan-out's client-side team
intersection (the count endpoint has the same upstream `team_id` bug
when `label_id` is set).
`mcp_tools_hosts.go` `get_endpoints` handler branches on `anyFilter` and
calls the filtered count when any filter dimension is supplied.
### Policy SQL retrieval (mirror of #45513)
The `Policy` struct lacked a `Query` field, so Go's JSON decoder
silently dropped the `query` key from `/api/v1/fleet/global/policies`.
One-line addition; same struct backs both the global path and the
per-team fan-out.
### Repo hygiene
- Sanitized environment-specific values throughout the package (README,
tool descriptions, attribution comments): dogfood URL →
`your-fleet.example.com`; team examples drop emoji prefixes; specific
real CVE IDs swapped for placeholders; `vetted_queries.go` source
attribution now references CIS-8.1 benchmarks instead of a
personal-handle GitHub fork; canonical repo link points at
`fleetdm/fleet/tree/main/tools/fleet-mcp`.
- Re-vendored `osquery_fleet_schema.json` via the `//go:generate`
directive so the embedded snapshot matches the canonical monorepo copy.
- Deleted `fleet_integration_test.go` and `rate_limit_test.go` per repo
policy: production package ships no `_test.go` files.
## Test plan
- [x] `go build ./...` clean
- [x] `go vet ./...` clean
- [x] `gofmt -l .` empty
- [x] Manual smoke via Claude Desktop stdio: `get_endpoints
fleet=<team>` returns `Total == Returned == team's actual host count`
(no longer global)
- [x] Manual smoke: `get_endpoints fleet=<team> platform=windows`
returns hosts whose `team_id` all match the requested fleet (no longer
all-team Windows)
- [x] Manual smoke: `get_policies` response contains a non-empty `query`
field for each policy
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added new osquery tables for system monitoring: Adobe plugins, open
handles, secure boot certificates, and YARA events.
* Added host-count and endpoint counting scoped by filters (team,
platform, status, query, label, and policy).
* **Improvements**
* Enhanced host filtering behavior to correctly apply filter scope when
computing totals.
* Improved label-based host listing responses by optionally populating
per-host label details.
* Updated tool and schema descriptions/examples for clearer query and
CVE guidance.
* **Tests**
* Extended coverage for policy-filtered label host listing and related
behaviors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@nulmete:
- [x] QA'd all new/changed functionality manually
---------
Co-authored-by: Luke Heath <luke@fleetdm.com>
Co-authored-by: nulmete <nicoulmete1@gmail.com>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated the project’s Go version settings to keep tooling in sync
across all relevant components.
* Running the standard Go update workflow will now apply version updates
to an additional part of the codebase.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved release preparation and publishing reliability, including
more consistent version updates and chart version bumps.
* Streamlined milestone cleanup so release tracking issues are closed
more predictably.
* **Chores**
* Added a faster path to create a QA issue during release workflows.
* Refined cherry-pick handling for release candidates to better track
remaining work.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Bumped Fleet to version **v4.87.1** across Helm, Terraform, and the
npm package.
* Updated deployment image tags so environments using the chart or
infrastructure defaults will pick up the new release.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
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:** Relates to #43544
Security review + hardening of the experimental Fleet MCP server. Issues
were reproduced against a live dev Fleet; this PR fixes the MCP-layer
ones.
| Finding | Before → After | Where |
|---|---|---|
| **A** least privilege | No signal about the token's power → startup
`/me` check **refuses any non-API-only token** (fails closed if
unreachable). API-only users can be scoped to specific endpoints/teams
and their token revoked. Who-can-do-what is documented (Fleet RBAC), not
inferred at runtime. | `main.go` `requireAPIOnlyUser`;
`fleet_integration.go` `WhoAmI` |
| **B** rate-limit XFF bypass | Per-IP keyed on spoofable
`X-Forwarded-For` → Removed rate-limiting (assuming Fleet handles this).
| N/A |
| **C** token egress / SSRF | `FLEET_BASE_URL` unchecked → This is
configured at deployment time and not per-request, so no action is
taken. | N/A |
| **D** error-body leak | Raw Fleet JSON (incl. internal `uuid`) →
trimmed, e.g. `Fleet API returned HTTP 409: Resource Already Exists`. |
`fleet_integration.go` `fleetErrMsg` |
| **E** dead code / docs / tests | Removed dead `GetFleetConfig`; README
18→19 / 16→17; added validator/role tests. | `fleet_integration.go`,
`README.md`, `*_test.go` |
| **F** writes auto-runnable | Only the advisory `destructive=true`
annotation → `fleetMCPInstructions` now tells the client to show the SQL
+ targets and confirm before running `run_live_query`. **Advisory, not a
server control.** | `mcp_server.go` |
| **G** abrupt SIGTERM shutdown | `ListenAndServe` blocked with no
signal handling → on SIGTERM the process was killed immediately (**exit
143**), resetting any in-flight connection at once. Now a signal-aware
root context (`signal.NotifyContext`) drains in-flight requests via
`http.Server.Shutdown` (10s cap), logs `shutting down`, and **exits 0**
— and the startup `/me` check + temp-query sweep + stdio loop all honor
it. Matters for Render redeploys (SIGTERM). | `main.go` |
### Key decisions
- **Rate limit: removed**: assuming Fleet server handles this.
- **`fleetMCPInstructions` / `destructive=true` are advisory** — a
prompt-injected or raw client ignores them. The enforceable controls are
the token role and `--disable_tables` flag. Added an explicit
confirm-before-run instruction for `run_live_query` to
`fleetMCPInstructions` as a cross-client complement to the
`destructiveHint=true` annotation -- the annotation only prompts on
clients that honor it, whereas the instruction reaches any client that
forwards server instructions to the model (and raw JSON-RPC callers that
have no approval UI at all). Both are advisory; the real bound on writes
remains the `FLEET_API_KEY`'s Fleet role.
- **Device-side `curl`/`carves` exfil is a Fleet/osquery capability**,
equally reachable via the UI/`fleetctl`/REST — not an MCP bug.
Comprehensive fix is agent `--disable_tables` (separate
Fleet-server/agent issue).
### Residual attack surface (re: *"no new attack vectors"*)
None of these is a vector the MCP invents beyond what Fleet already
exposes:
| Config choice | Residual vector | Mitigation |
|---|---|---|
| Non-API-only / admin token | Leak = arbitrary osquery everywhere |
API-only **required** (refuses to start otherwise); use **observer** for
read-only. As an API-only user it can also be **scoped to specific
endpoints/teams** and its **token revoked** on leak — neither possible
with a UI session token. |
| `run_live_query` via an auto-approving / prompt-injected client |
Arbitrary osquery on currently-online hosts - read/exfil-capable
(`curl`, `curl_certificate`, `file`, `carves`). No data mutation. |
Non-advisory: `FLEET_API_KEY` role - **observer-plus** needed to run
live queries. A "read-only" deployment (**observer** token) removes the
vector entirely; plus agent-side `--disable-tables` to drop exfil
tables. Advisory: `destructiveHint=true` + confirm-before-run
instruction (F) - an auto-approving client ignores these. |
| Live query at all | `curl`/`carves`/`file` device SSRF + exfil | Agent
`--disable_tables` (separate issue) — not an MCP-layer fix |
| Public SSE, no edge | Unauth flood `429`s operators (shared bucket —
fails safe) | We assume Fleet server handles rate-limiting. |
**Bottom line:** with an API-only observer/+ token (now enforced) over
stdio, `ip` mode, or SSE-behind-an-edge, the MCP adds no new attack
vector beyond Fleet's existing live-query capability; the residual
`curl`/`carves` risk is a Fleet-layer concern tracked separately.
# 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.
## 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
* **Improvements**
* Startup now verifies the Fleet API key belongs to an **API-only**
Fleet user
* Added `/healthz` endpoint
* Hardened Fleet base URL validation to prevent token leakage to unsafe
hosts
* Improved rate limiting behavior (429 includes `Retry-After: 1`; per-IP
uses the direct client address host)
* Signal-driven graceful shutdown and stricter `MCP_AUTH_TOKEN` length
checks
* More robust schema fetching by blocking cross-host and overly long
redirect chains
* **Documentation**
* Expanded/clarified write-operation guidance and confirmation
requirements
* **Chores / Tests**
* Updated `.env` docs/ignores, added developer Makefile helpers, and
refreshed Fleet base URL tests
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
**QA / load-test tooling** for the Google Workspace IdP integration —
lets QA exercise the real sync path at scale without a Google Workspace
tenant.
- **`tools/gw-directory-fake`** — a standalone fake of the Google Admin
SDK Directory API (not production code):
- `generate` — writes an editable JSON fixture (`-users`, `-groups`,
`-members-per-group`, `-domain`).
- `serve` — serves users/groups/members with real pagination from the
fixture, **hot-reloading** the file on change (poll modtime), plus
`-latency` / `-error-rate` (429/503) knobs. Responses are built from the
real `directory` SDK structs so the schema can't drift.
- **Fleet-side seam** (`ee/server/googleworkspace/google_workspace.go`):
- honors `token_uri` from the service-account JSON (falls back to
Google's endpoint),
- `FLEET_TEST_GOOGLE_WORKSPACE_ENDPOINT` redirects the Directory API
base to the fake (logs a warning each sync; never set in production),
- `seam_test.go` proves the loop end to end (JWT token exchange +
paginated Directory calls against a local fake over plain HTTP).
### QA workflow
```
go run ./tools/gw-directory-fake generate -users 50000 -groups 2000 -domain qa.example.com -out fixture.json
go run ./tools/gw-directory-fake serve -fixture fixture.json -addr :8091
```
Set `FLEET_TEST_GOOGLE_WORKSPACE_ENDPOINT=http://<host>:8091` on Fleet
and configure the integration with a throwaway service-account JSON
whose `token_uri` is `http://<host>:8091/token`. Edit `fixture.json`
anytime to change directory state mid-test.
> 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-5-frontend` (top of the
feature code stack, #48168).
**Related issue:** Resolves#42915
# Checklist for submitter
- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
## Testing
- [ ] 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
* **New Features**
* Google Workspace directory access now supports custom OAuth token
endpoints and a configurable API base endpoint for testing and special
environments.
* Added a local fake Google Workspace Directory server tool for
generating sample data and serving directory responses, including
pagination and optional fault injection.
* **Bug Fixes**
* Improved handling for Google Workspace API calls when alternate
endpoints are required.
* **Tests**
* Added coverage for overriding the Google Workspace directory endpoint.
<!-- 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 #
# 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.
- [ ] 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
- [ ] 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
* **Chores**
* Updated the container build process for the migration proxy so the
binary is built during image creation.
* Adjusted the runtime image packaging to copy the generated executable
from the build output location while keeping runtime behavior unchanged.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
### 🥞 Stack (review/merge bottom-up)
1. #48164 — Activity types (FE+BE)
2. **#48165 — Backend (cron + directory sync) ⬅ this PR**
3. #48166 — Usage statistics
4. #48167 — fleetctl generate-gitops
5. #48168 — Settings UI
📄 Documentation is tracked separately in #48169 (targets
`docs-v4.89.0`).
---
## Summary
**PR 2 of 6.** Core **backend** for the Google Workspace IdP
integration:
- Directory sync client (`ee/server/googleworkspace/`) and cron job
(`server/cron/google_workspace_cron.go`) reusing the `scim_*` tables
(Google Workspace and SCIM are mutually exclusive).
- Config types + validation (`server/fleet/google_workspace.go`,
`app.go`, `integrations.go`), appconfig handling + activity emission
(`server/service/appconfig.go`), cron registration and schedule.
- SCIM is ignored while Google Workspace is configured
(`ee/server/scim/scim.go`).
> 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-1-activities` (PR 1) —
review/merge that first.
**Related issue:** Resolves#42915
# Checklist for submitter
- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops.
## Testing
- [ ] 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
* **New Features**
* Added Google Workspace integration support for syncing users, groups,
and host-related identity data.
* Added a scheduled sync that keeps directory data up to date
automatically.
* Added support for configuring Google Workspace in app settings, with
validation and masking of sensitive credentials.
* **Bug Fixes**
* Prevented SCIM provisioning from overwriting data when Google
Workspace sync is configured.
* Preserved existing Google Workspace credentials when an update omits
masked API key values.
* Added handling for deleted users and group membership changes during
sync.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves#46005
Implement flow for ad-hoc distributed query campaign streamed over the
/api/v1/fleet/results/websocket endpoint, the same way the Fleet UI and
fleetctl run live queries.
**Related issue:** N/A — follow-up cleanup to #46406 (Add Hangar).
## What & why
Fleet Hangar is a macOS-only, GUI-only dev tool built natively, but the
Wails v3 project template left behind config for modes/platforms it
never uses. None of it was referenced by CI, scripts, or the documented
build flow (`dev` / `build` / `package` / `dist` / `sign`).
Removed:
- **Server-mode + Docker tasks** (`build:server`, `run:server`,
`build:docker`, `run:docker`, `setup:docker`) in the root and common
Taskfiles. They point at `build/docker/Dockerfile.{server,cross}`, which
don't exist, and there is no `server` build tag anywhere in the Go code.
- **Docker cross-compilation** in `build/darwin` (`build:docker`,
`CROSS_IMAGE`, the `build:universal` `lipo:go` fallback). `build:` and
`build:universal` now call the native macOS paths directly.
- **iOS tasks** (`ios:device:list`, `ios:run:device`) — no iOS project
exists.
- **`frontend:vendor:puppertino`** — fetched CSS into
`frontend/public/puppertino` and rewrote `index.html`; none of those
targets exist and no task called it.
- **`.gitignore`** lines for `build/linux` and `build/windows` (neither
dir exists).
- **`config.yml`** template placeholders (commented `ios` /
`fileAssociations` blocks, the `My Other Data` `other` entry).
The darwin signing vars (`SIGN_IDENTITY`, `KEYCHAIN_PROFILE`,
`ENTITLEMENTS`) are now declared as empty strings instead of comments,
so removing `CROSS_IMAGE` doesn't leave `vars:` as a null mapping (which
the Taskfile schema rejects). Behavior is unchanged — the `sign:`
preconditions still guard on non-empty values.
Net: **11 insertions, 280 deletions** across 5 files. No change to the
real build flow.
## Testing
- Verified with `task build` — exit 0, produces `bin/fleet-hangar`
(arm64 Mach-O).
- `task --list-all` parses all three Taskfiles with no schema errors and
no dangling task references.
## Checklist
- [x] QA'd manually (`task build`)
No changes file: `tools/hangar` is an internal dev tool, so this is not
a user-visible change.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Simplified build configuration by removing Puppertino CSS integration
and server/Docker/iOS build tasks.
* Updated development task with improved process management to prevent
orphaned processes.
* Streamlined macOS build process to native-only implementation,
removing cross-compilation support.
* Cleaned up build configuration files and project ignore patterns.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Adds `tools/hangar` — a macOS desktop control panel for working on Fleet
locally: branch management, `fleet serve` orchestration, log tail, dev
MySQL backup/restore, `fleetctl`, GitOps, and `osquery-perf`, all in one
window.
Built with **Go + [Wails 3](https://v3alpha.wails.io)** — the backend is
plain Go (`os/exec`, `syscall`, goroutines) so Fleet engineers can
contribute to it; only the desktop shell is Wails. The `internal/`
packages are pure and unit-tested.
### History note
Hangar started as a Rust/Tauri app. It was ported to Go, and **the Go
port is now the canonical `tools/hangar`**. The original Rust/Tauri
implementation has been removed from the monorepo (preserved in a
standalone repo) — so although this branch's earlier commits add and
then replace the Rust app, the net diff is just the Go app at
`tools/hangar`. The bundle identifier is `com.fleetdm.fleet-hangar`,
matching the original app so existing settings carry over.
# Checklist for submitter
- [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
> No `changes/` file: `tools/` is contributor tooling, not a
user-visible Fleet change. No DB migrations, no Fleet config settings,
no fleetd/orbit changes.
## Testing
- [x] Added/updated automated tests (Go unit tests across `internal/`,
including a path-traversal regression for backup deletion)
- [x] QA'd all new/changed functionality manually
## Test plan
- [x] `cd tools/hangar && task dev` launches the app (live-reload)
- [x] `task build` produces `bin/fleet-hangar`; `go test ./...` is green
- [x] First-run gate discovers a local Fleet clone and runs dep checks
- [x] Server tab can run the build chain and start `fleet serve`
- [x] Git tab branch search finds an older branch (e.g. a stale `qa-*`)
by name
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Introduced Fleet Hangar, a comprehensive desktop application for Fleet
development workflows, providing unified controls for server/database
management, git operations, configuration, logging, and troubleshooting.
* Added database backup management with metadata tracking.
* Integrated process orchestration for development services (Docker,
ngrok, Python).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: George Karr <georgekarrv@users.noreply.github.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#44746
# Details
* Adds the ability to filter historical CVE data by software type, EPSS,
CVSS, CVE ID (exclude only) and "has known exploit"
* Hard-codes the CVSS filter to 9.0+ for now, since that's the only data
that's been collected thus far
* Un-gates the collection code so that it will collect CVE data for
_all_ severities (but still in the restricted set of software)
Related PRs [update the
front-end](https://github.com/fleetdm/fleet/pull/47674) to allow sending
these filters, and [update
GitOps](https://github.com/fleetdm/fleet/pull/47634) to allow changing
the default filters.
# 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] QA'd all new/changed functionality manually
### Manual test plan — CVE chart filtering (backend smoke test)
#### Setup
- Premium dev server running with a few hosts carrying vulnerable
software (so `cve_meta` / `software_cve` /
`operating_system_vulnerabilities` are populated)
- Chart data present — collector ran once, or seeded: `go run
./tools/charts-backfill --dataset cve
--use-tracked-cves --days 7`
- API token exported and helper set:
```bash
BASE=https://localhost:8080/api/v1/fleet/charts
peak() { curl -sk -H "Authorization: Bearer $TOKEN" "$BASE/$1" | jq
'[.data[].value] | max'; }
#### Checks (compare against the no-filter baseline)
- [x] Baseline returns data — GET /charts/cve?days=7 returns a data
series; .filters is empty/default
- [x] Severity force-pinned to critical — cve?days=7 and
cve?days=7&severity_min=0&severity_max=10 give identical
peaks (no low-severity leak; client severity ignored)
- [x] Category narrowing — software_categories=browsers ≤ baseline;
software_categories=os,browsers,office,adobe ==
baseline
- [x] OS category includes kernel — software_categories=os returns
OS-vuln + Linux-kernel CVE counts
- [x] Known-exploit narrowing — known_exploit=true ≤ baseline
- [x] EPSS narrowing — epss_min=0.9 ≤ baseline; epss_min=0&epss_max=1 ==
baseline (EPSS is 0.0–1.0 on the API)
- [x] Exclude is subtractive + tolerant — excluding a visible CVE
lowers/keeps counts; exclude_cves=CVE-0000-00000
== baseline (no-op)
- [x] Filters echo back — filtered requests return applied values under
.filters
- [x] Uptime untouched — GET /charts/uptime?days=7 returns its normal
series
- [x] Free-tier safety (optional) — on non-Premium, /charts/cve returns
an empty series, no error
- [x] > 0 rows from:
SELECT COUNT(DISTINCT scd.entity_id) AS below_critical
FROM host_scd_data scd JOIN cve_meta cm ON cm.cve = scd.entity_id
WHERE scd.dataset='cve' AND cm.cvss_score < 9.0;
- (confirms lower-severity CVEs are stored)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary of changes
* **New Features**
* Added advanced CVE chart request filters: software categories,
known-exploit flag, EPSS min/max, severity min/max, and excluded CVEs.
* Expanded CVE chart coverage to use the full “collectible” CVE set,
with filtering applied when serving chart data.
* **Tests**
* Added coverage for collecting collectible CVEs and resolving chart
entities based on filter combinations and exclusions.
* **Chores**
* Updated CVE chart backfill to use collectible CVE discovery.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Adds the loadtest metrics for the **4.86 → 4.87 migration** run,
following the existing `tools/loadtest/metrics/runs/migration/`
convention (cf. `485to486mig`).
Two files:
- `486to487mig-2026-06-17-195042Z-1h.md` — 1h metrics synopsis
- `486to487mig-2026-06-17-195042Z-1h.json` — raw collected metrics
## Results (1h window, 2026-06-17)
✅ All metrics within expected thresholds
- Fleet errors: **0**
- RDS deadlocks: **0**
- Abnormal container stops: **0**
- ALB 5xx: **0**
Data only — no code changes.
cc @AndreyKizimenko for approval.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Added load testing metrics data capturing performance statistics for
infrastructure components including Fleet Server, database, caching, and
load balancer metrics during a 1-hour test window.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Baseline loadtest results for Fleet 4.87.0 (20h run).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Added baseline load test performance metrics for infrastructure
monitoring and analysis.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->