3aff5504220ecc41ceed85710c8ca04b975f258a
2745
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b3c2a6368d |
Count FMAs by slug (#48783)
**Related issue:** Resolves #48528 This keys the count, pagination, and the frontend row-combining on the app's slug token (the prefix before `/`, shared across an app's platform entries but distinct across apps). The count now equals the rows shown in every view (macOS, Windows, All), and name-colliding apps stay as separate rows. # 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. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [x] Confirmed that the fix is not expected to adversely impact load test results <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Software listings now group platform-specific installers into a single app row based on the app identifier, improving how macOS and Windows entries appear together. * **Bug Fixes** * Apps with the same display name but different identifiers now stay separate instead of being merged incorrectly. * List counts and pagination now match the combined app view more accurately across the software pages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
bf94df6e6f |
Show certificates on host details page for Windows (#31294) (#48469)
Surface the existing "Certificates" card on the host details page for Windows hosts, with parity to macOS. Requires osquery 5.23.1 or higher. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #31294 Demo video: https://www.youtube.com/watch?v=kGRp-YtnnJc Docs: https://github.com/fleetdm/fleet/pull/48493/changes # 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 ## 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. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Windows host certificates now display on the host details page (gated by minimum agent/osquery version), including scope (**System** vs **User**) and improved scope-aware certificates list details. * **Bug Fixes** * Certificate table labeling and help text are now platform-appropriate (with “Keychain” renamed to “Scope”). * Windows certificate reconciliation is more resilient, preserving certificates for scopes not observed during a collection run and preventing row collapsing when ids repeat across scopes. * **Tests** * Expanded coverage for Windows/malformed DN parsing and scope-aware reconciliation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
51f1e85c05 |
Improved the performance of Windows MDM profile installation (#48733)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45650 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Bug Fixes** * Improved MySQL migration handling for MDM command results by safely removing an outdated foreign key when present, preventing issues during upgrade and re-run scenarios. * Updated the database schema definition to keep related response foreign key behavior consistent. * **Chores** * Added the latest migration version to the migration status seed data to ensure version tracking stays in sync. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
dfc8c272d3 |
Add Zorin OS as a recognized Linux platform (#45712)
**Related issue:** Resolves #45710 # Checklist for submitter - [x] Changes file added (`changes/45710-zorin-os-support`). - [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 — `server/vulnerabilities/oval/oval_platform_test.go` extended with Zorin → Ubuntu LTS mapping cases (16/17/18) plus an unknown-version case (`Zorin OS 99` → `zorin_99`, which `IsSupported()` rejects). - [x] QA'd all new/changed functionality manually — Zorin OS 17.0 and 18.1 hosts enrolled against a patched Fleet server, host details show `platform=zorin`, software inventory populates, and OVAL CVE matching produces results against the corresponding `ubuntu_2204` / `ubuntu_2404` feeds. ## Database migrations - N/A. No schema changes. ## New Fleet configuration settings - N/A. No new settings. ## fleetd/orbit/Fleet Desktop - N/A. Server + frontend only; no fleetd/orbit changes. --- ## Summary Fleet previously logged `unrecognized platform` for Zorin OS hosts (osquery reports `platform=zorin` from `/etc/os-release` `ID=zorin`). The common workaround was running osquery with `--force_platform=ubuntu`, which masquerades the host. This change adds `zorin` as a first-class Linux platform alongside Ubuntu: - **`server/fleet/hosts.go`** — register `zorin` in `HostLinuxOSs` and `HostDebPackageOSs` - **`server/datastore/mysql/linux_mdm.go`** — include Zorin in the Linux disk-encryption summary query - **`server/vulnerabilities/oval/oval_platform.go`** — map Zorin major version to the underlying Ubuntu LTS OVAL feed (16 → 20.04, 17 → 22.04, 18 → 24.04). Unknown future versions fall through to an unsupported `zorin_<major>` identifier so vulnerability scanning is skipped rather than served stale data from an aging LTS feed. - **frontend** — add `zorin` to `HOST_LINUX_PLATFORMS`, the disk-encryption support list and type guard, the label platform dropdown, and the icon mapping (Ubuntu icon, since no Zorin-specific asset exists in the repo). No new dependency, schema migration, or config setting. Reuses existing Ubuntu OVAL feeds and the existing Ubuntu icon. Diff is ~30 lines net across 9 files (8 patched + 1 `changes/` file). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Zorin OS as a supported Linux platform. * Zorin hosts included in Linux disk-encryption summaries and treated as disk-encryption capable. * Zorin OS available as a selectable/filterable platform label and considered DEB-install compatible. * Vulnerability scanning enabled for Zorin 16→Ubuntu 20.04, 17→22.04, 18→24.04; unknown/future Zorin versions are marked unsupported and skipped for CVE matching. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45712?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6ba04b0d20 |
Optimize query aggregated stats cron to skip queries without execution data (#48698)
**Related issue:** Resolves #48697 ## Summary The hourly `UpdateQueryAggregatedStats` cron job currently walks **every query ID** in the `queries` table and runs 5 expensive percentile-calculation queries per query against `scheduled_query_stats`, plus 1 INSERT/UPDATE to store results. Most queries have no execution data at all (they are saved queries, live-only, or de-scheduled), so this work is pure waste. This PR changes the cron to only process queries that actually have execution data, by querying `scheduled_query_stats` directly instead of the `queries` table. The now-unused `walkIdsInTable` helper function is also removed. ### How the calculations work `CalculateAggregatedPerfStatsPercentiles` computes performance statistics for each query that has been scheduled and executed by hosts. For each qualifying query ID, it runs these operations against the read replica: 1. **P50 user_time** -- Calculates the median (50th percentile) of per-host average user-mode CPU time. The query groups `scheduled_query_stats` rows by `host_id`, computes `SUM(user_time) / SUM(executions)` per host, sorts them, then picks the row at position `FLOOR(total_rows * 0.5) + 1` using a `@rownum` session variable. 2. **P95 user_time** -- Same calculation but picks the 95th percentile row (`FLOOR(total_rows * 0.95) + 1`). 3. **P50 system_time** -- Same percentile calculation for kernel/system CPU time. 4. **P95 system_time** -- 95th percentile of system CPU time. 5. **Total executions** -- `SELECT COALESCE(SUM(executions), 0) FROM scheduled_query_stats WHERE scheduled_query_id = ?` 6. **INSERT/UPDATE** -- Writes the JSON result (`user_time_p50`, `user_time_p95`, `system_time_p50`, `system_time_p95`, `total_executions`) into the `aggregated_stats` table via `INSERT ... ON DUPLICATE KEY UPDATE`. ### What changed **Before:** `SELECT id FROM queries` -- walks every query (200-400+ in a typical deployment). **After:** `SELECT DISTINCT scheduled_query_id FROM scheduled_query_stats WHERE executions > 0` -- walks only queries that have actual execution data (typically 10-20). ### Benchmark results (MySQL 8.0, 300 queries seeded, only 15 with stats) | Metric | Before | After | Improvement | |--------|--------|-------|-------------| | Avg time per cron run | 3.36s | 0.28s | **12.2x faster** | | DB operations per run | 1,800 | 90 | **95% fewer** | | DB operations per day | 43,200 | 2,160 | **41,040 eliminated** | | `aggregated_stats` rows written | 300 (285 empty) | 15 (all meaningful) | Less table bloat | | Correctness | baseline | byte-identical JSON | **Zero regression** | At 500+ queries the current approach **drops MySQL connections** (`unexpected EOF` / `invalid connection`) because the cursor is held open across thousands of heavy serial queries. The optimized version handles any scale trivially. ### Impact analysis Verified safe across all consumers: all query endpoints use `LEFT JOIN aggregated_stats` (NULL-safe for missing rows), the frontend explicitly handles null stats as "Undetermined", live query stats (`service_campaigns.go`) call `CalculateAggregatedPerfStatsPercentiles` directly and are unaffected, and query deletion already cleans up both `scheduled_query_stats` and `aggregated_stats` rows. # 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) - [x] Added/updated automated tests - [x] Confirmed that the fix is not expected to adversely impact load test results Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
1ceca6ad8e |
Cleanup policy_membership stale entries in distributed/write (#48674)
Resolves #47241. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [X] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Better host policy results by automatically cleaning up out-of-scope `policy_membership` records. * Refreshes host failing-policy counts after cleanup, including when distributed writes report “no policies in scope.” * Preserves existing safeguards by skipping this cleanup during setup/initial configuration to prevent premature updates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
171504dc18 |
Fix nondeterministic device_mapping order in ListHosts (#48696)
Fixes the `device_mapping` ordering flake in `TestIntegrations/TestListHostsByLabel` and `TestIntegrations/TestHostsReportDownload`, seen across integration-core jobs on `main` since July 1 (e.g. [this run](https://github.com/fleetdm/fleet/actions/runs/28567132474)). #48488 replaced the derived-table `GROUP_CONCAT` join in `ListHosts` with a correlated subquery, but the `GROUP_CONCAT` has no `ORDER BY`, so MySQL returns `device_mapping` entries in arbitrary order. The old plan happened to read `idx_host_emails_host_id_email` in index order, which masked this; the new access path doesn't, so the order now varies between endpoints and runs — the tests compare `GET /hosts` output against `GET /labels/{id}/hosts` (and CSV report) output for the same host and intermittently see `[b@b.c, a@b.c]` vs `[a@b.c, b@b.c]`. This adds `ORDER BY he.email, he.source` inside the `GROUP_CONCAT`, matching the ordering of the single-host `listHostDeviceMappingDB` query. The sort applies only within each host's few email rows, so it doesn't affect the perf improvement from #48488. No changes file: #48488 is unreleased (not in any RC branch), so this is a fix to an unreleased change. # 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. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually Covered by existing tests: `TestIntegrations/TestListHostsByLabel` and `TestIntegrations/TestHostsReportDownload` assert the (now deterministic) ordering. Ran both 4× locally with `MYSQL_TEST=1 REDIS_TEST=1`, plus the `TestHosts` device-mapping/ListHosts datastore tests — all green. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved consistency of host device mapping results by making the ordering deterministic. * Fixed an issue where device mapping entries could appear in different orders between requests. * **Tests** * Added coverage to verify the device mapping order remains stable and predictable. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8b1e806754 |
Fix GitOps creating duplicate software titles (#48664)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48054 Changes: - Changes batch add installer path to reuse `getOrGenerateSoftwareInstallerTitleID` - Adds migration to retroactively fix duplicate titles created by this bug # 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) - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - The tables will actually be updated, so it makes sense for that to change if it happens <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Resolved a case where GitOps uploads of Windows software could create duplicate software titles when a host had already reported the same program. * Improved deduplication and reassociation so related records (installers and icons) are merged into the retained title, preserving the correct upgrade code. * **Tests** * Added regression coverage for the duplicate-title scenario to prevent future repeats. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
dea65b824c |
Bump migration timestamps after 4.88 cherry-pick (#48617)
**Related issue:** Resolves NA (release hygiene — migration ordering) ## What & why The `4.88.0` patch cherry-picked two migrations, `20260624210253_AddHostMDMAppleEnrollmentPermissions` and `20260624210311_RenamePersonalEnrollmentStatus`. Eight migrations on `main` were **not** cherry-picked into 4.88 but had **earlier** timestamps than those two: | Old timestamp | Migration | |---|---| | 20260611202649 | AddWindowsMDMConfigProfilesPendingDelete | | 20260615135619 | AddSetupExperienceSoftwareInstallers | | 20260617172853 | CreateSoftwareTitleTeamPins | | 20260617194413 | AddAndroidProfileVariableTracking | | 20260622124714 | AddPolicyGateToSetupExperienceResults | | 20260622124734 | AddBYODFleetAndADUEEnrollment | | 20260623140135 | AddSupportSoftwareCategory | | 20260624152755 | AddCertAndAndroidAppVariableTracking | This violates the rule in `docs/Contributing/workflows/releasing-fleet.md`: > Any migrations that are not cherry-picked in a patch must have a _later_ timestamp than migrations that were cherry-picked. Left as-is, a customer on `4.88.0` (who applied migrations through `20260624210311`) upgrading to `4.89.0` would hit these 8 as out-of-order/missing migrations older than their highest-applied version. ## Fix Bumped the 8 non-cherry-picked migrations to new timestamps (`20260702013055`–`20260702013102`) using `tools/bump-migration`, **preserving their relative order**, so they now sort after the cherry-picked migrations and `20260626120000_CompressWindowsMDMResponsesColumn`. Regenerated `schema.sql`. Verified `20260626120000_CompressWindowsMDMResponsesColumn` (the only other non-cherry-picked migration, already correctly ordered) touches only `windows_mdm_responses` — none of the 8 moved migrations touch that table, so no dependency inversion is introduced by the reorder. None of these 10 migrations shipped in `4.87.1`, so no released database is affected. `rc-patch-fleet-v4.88.0` needs no change. This lands on `main` and should be reflected on `rc-minor-fleet-v4.89.0`. # Checklist for submitter ## Database migrations - [x] Migration files renamed via `tools/bump-migration`; function names updated to match new timestamps. - [x] Regenerated `schema.sql` via `make dump-test-schema`; migrations apply cleanly in the new order. - [x] No schema/content changes to the migrations themselves — timestamp renumber only. ## Testing - [x] `go build ./server/datastore/mysql/migrations/...` and `go vet` pass; schema regeneration ran all migrations successfully in order. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for additional device/profile tracking across Android, Apple, Windows, certificates, and apps. * Added new setup and software management records, including support software categories and team pins. * Added a policy-gating flag for setup experience results. * **Bug Fixes** * Improved database consistency with stronger uniqueness and cascade-delete behavior. * Updated schema tracking so migrations apply cleanly with the latest database state. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4afd59833d |
Fix installed_software status in policy automation activities
Relates to #38670 The policies/:id/automation_activities endpoint derived the top-level status for installed_software activities from the live host_software_installs.status generated column. That column becomes NULL when the install row is marked removed=1 (e.g. after the installer package is edited/updated or the software is re-installed), so a historically-successful install was miscategorized as "error". Derive the outcome from the activity's recorded details.status instead, which reflects the install result at the time the activity was created. The install output still comes from host_software_installs. This applies to both the displayed status and the ?status=error|success filter. Also fixed alignment with the info icon on the policy automations table. |
||
|
|
80b883a2e7 |
Adding in check to disable recovery lock on personal macos since it doesn't have the required permissions (#48598)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48594 # 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: - [x] Confirmed that the fix is not expected to adversely impact load test results - [x] Alerted the release DRI if additional load testing is needed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Recovery-lock password checks now skip personally owned (BYOD) Apple devices, avoiding failures on eligible hosts. * Recovery-lock clear actions are no longer applied to personally owned enrollments. * **Tests** * Added coverage to verify BYOD devices are excluded from both recovery-lock enforcement and clear workflows. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e8f26ec4ef |
Fix S3 file carve cleanup hang and rework reconciliation
Relates to #48549 The S3 carve cleanup (server/datastore/s3, run by the cleanups_then_aggregation cron) advanced ListObjectsV2 pagination using the response's ContinuationToken — an echo of the request token — instead of NextContinuationToken. On any bucket with more than one page of objects this looped forever, hanging the entire serial cleanup cron and stalling every cleanup/aggregation job ordered after it. Replace the bucket-listing reconciliation with a direct HeadObject probe per carve, which is exact and independent of listing order or object counts: - Only carves older than 24h with a completed upload are reconciled (mirrors the MySQL carve store's floor; skips in-flight multipart uploads). A carve is expired only on a definitive not-found; transient or other probe errors leave it for a future run, so a carve whose object still exists is never expired. - Probes run with bounded concurrency; expirations are written in one batched, retryable UPDATE (new ExpireCarves datastore method) rather than one per carve. - The number of carves reconciled per run is capped so a large backlog drains across runs without any single run making unbounded S3 requests. Add S3-carve-store-only server settings (the MySQL carve store is unaffected): - s3.carves_cleanup_disabled — skip reconciliation entirely - s3.carves_cleanup_max_per_run — per-run cap (default 1000) - s3.carves_cleanup_concurrency — concurrent probes (default 32) Also log the expired count per run and fix the test bucket cleanup helper to paginate. Adds unit tests (transient-error safety, partial failure, concurrency) and a MySQL integration test for ExpireCarves. |
||
|
|
6223af892e |
Fix manual-personal enrollment for iOS/iPadOS (#48534)
<!-- 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. Unreleased bug, no changes file - [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) - [ ] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [x] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Personal enrollment status is now preserved and updated correctly when MDM device records change. * macOS MDM ingestion now keeps the BYOD/personal enrollment flag for Fleet devices instead of defaulting it away. * Incoming server URLs continue to have query parameters removed while still retaining the enrollment status used for processing. * **Tests** * Added coverage for personal enrollment updates and macOS ingestion scenarios, including BYOD and non-BYOD cases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2d70a7b500 |
Associate all matching hosts with a SCIM/IdP user (not just the first) (#48351)
Resolves https://github.com/fleetdm/fleet/issues/48378 (issue found while working on the Google Workspace IdP integration). ## Summary Fixes a bug where an IdP user associated with **multiple hosts** only had IdP host vitals populated on **one** of them. `maybeAssociateScimUserWithHostMDMIdP` (called when a SCIM/IdP user is created) matched all hosts whose MDM IdP account corresponds to the user, but then deliberately linked only `hostIDs[0]` (with a `// TODO: confirm desired behavior` / "just use the first one"). So when a user is created *after* the hosts already enrolled — e.g. a directory sync creating users for people who each have a laptop and a desktop — only the first host got a `host_scim_user` row, and therefore only that host received the user's IdP host vitals and profile-variable resends. The fix links **every** matching host. `associateHostWithScimUser` is keyed on `host_id` (`INSERT … ON DUPLICATE KEY UPDATE`) and triggers its own per-host profile resend, so calling it once per host is safe and idempotent. This is shared SCIM linking code, so the fix benefits all IdP sources (Okta/Entra SCIM as well as the Google Workspace directory sync that surfaced it). Deletes and updates already handled multiple hosts correctly; only the initial reverse-link was capped. ## Testing Added `testScimUserCreateAssociatesAllMatchingHosts` (`server/datastore/mysql/scim_test.go`): two hosts share one MDM IdP account, then a SCIM user is created — both hosts must resolve to it via `ScimUserByHostID`. Fails before the fix (host #2 unlinked), passes after. **Related issue:** Resolves #48378 # 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). ## 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** * SCIM/IdP user provisioning now associates a new SCIM user with **all** matching hosts, not just the first match. * Host end-user details (including IdP username/full name) are now populated consistently on every associated host. * **Tests** * Added SCIM integration and datastore regression coverage to ensure multiple hosts linked to the same IdP account are all associated during user creation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
bec3b0dc2a |
Reduce MySQL reader load on GET /hosts with device_mapping + search query (#47722) (#48488)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47722 The issue was from a customer running `GET /api/v1/fleet/hosts?device_mapping=true&page=1&per_page=100&query=<ADDRESS>%40example.com` on a script in a for loop. This change reduces the impact of the API on such workflows. Results from my local load test: EXPLAIN ANALYZE: ``` ┌───────────────────────────────────┬────────────────┬─────────────┬─────────────────────────────────────────────┐ │ │ optimizer cost │ actual time │ device_mapping aggregation │ ├───────────────────────────────────┼────────────────┼─────────────┼─────────────────────────────────────────────┤ │ Old (derived-table GROUP BY join) │ ~23,179 │ ~73 ms │ materialized dm derived table, cost ~7,125 │ ├───────────────────────────────────┼────────────────┼─────────────┼─────────────────────────────────────────────┤ │ New (correlated subquery) │ ~1,260 │ ~25 ms │ Aggregate … loops=1 (only the returned row) │ └───────────────────────────────────┴────────────────┴─────────────┴─────────────────────────────────────────────┘ ``` Tests with 10k hosts: ``` ┌───────────────────────────────────┬────────────┬───────────────┬───────┐ │ dataset │ OLD (main) │ NEW (this PR) │ ratio │ ├───────────────────────────────────┼────────────┼───────────────┼───────┤ │ 10k hosts × 3 emails (30k rows) │ 4.6s │ 1.1s │ ~4× │ ├───────────────────────────────────┼────────────┼───────────────┼───────┤ │ 10k hosts × 30 emails (300k rows) │ 35.9s │ 1.2s │ ~30× │ └───────────────────────────────────┴────────────┴───────────────┴───────┘ ``` # 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 ## What & why `GET /api/v1/fleet/hosts?device_mapping=true&page=1&per_page=100&query=<email>` caused high MySQL **reader** load on instances with ~10k hosts. Each page load ran an expensive aggregation over the entire `host_emails` table even though only ~100 rows are returned. **Root cause:** with `device_mapping=true`, `applyHostFilters` added a `LEFT JOIN` on a derived table with `GROUP BY host_id` over `host_emails`. Because of the `GROUP BY`, MySQL must fully materialize that derived table (aggregating every row for all hosts) before the outer `WHERE`/`LIMIT 100` can be applied, so the full cost is paid on every page request regardless of result size. `CountHosts` reused the same options, materializing the aggregation a **second** time per page load. **Fixes (both in `server/datastore/mysql/hosts.go`):** 1. Replaced the derived-table join with a correlated subquery in the `SELECT` list (only when `opt.DeviceMapping`), so it is evaluated only for the rows actually returned, each as an indexed lookup on `idx_host_emails_host_id_email`. This matches the existing `host_additional` pattern in the same query. 2. Set `opt.DeviceMapping = false` in `CountHosts` — the column is never selected for counting — mirroring the existing `opt.DisableIssues` handling. ## Notes - The composite index `idx_host_emails_host_id_email (host_id, email)` already exists, so the correlated subquery resolves via an indexed lookup per returned row. - `TestHosts` (full suite) passes, including `HostDeviceMapping`, `CustomHostDeviceMapping`, and `IDPHostDeviceMapping` (the last two verify the `custom_*` → `custom` and `idp` → `mdm_idp_accounts` source translation still works through the new subquery). - Recommend validating with `EXPLAIN ANALYZE` on a ~10k-host dataset before/after, per the issue. I did not have access to such a dataset. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Performance** * Improved host list responsiveness when using search filters alongside device mapping. * Reduced database load during host listing by retrieving device mapping more efficiently per host. * Improved host counting speed by avoiding device-mapping evaluation for count queries. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fe46e41a52 |
Add public IP address to host search (#46809)
**Related issue:** Resolves #4842 # Checklist for submitter - [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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * IP-based host searches now match both private and public IP addresses. * Updated the host search box placeholder and tooltip to refer to “IP address” (instead of “private IP”). * **Tests** * Expanded backend coverage to verify matching (and non-matching) results for both private and public IPs when listing and searching hosts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com> |
||
|
|
af2d4dbbbd |
Optimize IsHostConnectedToFleetMDM on the orbit check-in hot path (#44629) (#48375)
**Related issue:** Resolves #44629 This folds the connected-to-Fleet check into `GetHostMDM` via a `connected_to_fleet` column that mirrors the existing `IsHostConnectedToFleetMDM` and `hostMDMSelect` conditions, and derives the value in `GetOrbitConfig` from the `host_mdm` data it already fetches. Result: **2 queries → 1** on the orbit check-in hot path, with no semantic change. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Performance Improvements** * Orbit check-ins now determine MDM connection status from existing host MDM data, reducing database work and improving response time. * **Bug Fixes** * Added platform-aware connection detection so Windows, Apple, and Android devices report MDM connectivity more accurately. * Updated related checks and tests to keep connection status consistent across enrollment and unenrollment changes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
70b41063a4 |
Google Workspace IdP [3/6]: usage statistics (#48166)
### 🥞 Stack (review/merge bottom-up) 1. #48164 — Activity types (FE+BE) 2. #48165 — Backend (cron + directory sync) 3. **#48166 — Usage statistics ⬅ this PR** 4. #48167 — fleetctl generate-gitops 5. #48168 — Settings UI 📄 Documentation is tracked separately in #48169 (targets `docs-v4.89.0`). --- ## Summary **PR 3 of 6.** **Usage statistics**: report whether a Google Workspace IdP integration is configured via the new `googleWorkspaceConfigured` field (`server/fleet/statistics.go`, `server/datastore/mysql/statistics.go`). > 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-2-backend` (PR 2). **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** * Usage statistics now include whether Google Workspace is configured, improving reporting accuracy. * **Bug Fixes** * Fixed statistics submissions so the Google Workspace configuration status is included consistently in outgoing requests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a019cfb8f4 |
Compress windows_mdm_responses envelopes on the Windows MDM hot path (#48320)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #44188 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## 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. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Windows MDM check-in response payloads are now stored gzip-compressed in the database to reduce write pressure for large SyncML data. * When fetching results, responses are automatically decompressed so the original content is returned to clients. * Empty payloads are preserved, and stored data is validated to ensure only valid gzip content is accepted. * **Database / Migration** * Added a migration and backfill to move existing records from uncompressed storage to the new compressed column format. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b438893bc2 |
Do not block further wipe commands on inactive existing entry (#48358)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45931 # 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved device lock handling so only active pending lock commands are treated as valid. * Fixed stale lock state cases where an old lock reference no longer blocks a new lock request. * When a prior lock command is no longer deliverable, a new lock command is now issued and tracked correctly. * Updated coverage to verify lock status transitions and replacement behavior in these edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0f439f9593 |
Auto-update, pin, and rollback Fleet-maintained apps via UI and GitOps (#48293)
**Related issue:** Resolves #38504 **Constituent PRs (merged into this feature branch):** - #47682 — Fleet UI: APRF Software title details page Library/Inventory layout - #47808 — Extend update software installer API to support FMA version pinning - #47944 — Fleet UI: APRF library item accordion component - #48081 — Versions modal, multi-row Library, pinned state - #48098 — Add `pinned_version` to `edited_software` activity - #48123 — Auto-update FMA cron - #48144 — Download a newly-published FMA version when pinned to it # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Fleet-maintained app version pinning (Latest, exact, and major) via a new Versions modal. * Introduced premium auto-updates for maintained apps with pin-aware promotion and rollback-safe caching. * Added expandable library version rows and a Policies modal. * **Bug Fixes** * Improved pin handling, cache/manifest hydration, and safer update behavior on per-app failures and deduplication. * **UI/UX** * Refreshed the Software title details experience with new accordion/list patterns, redesigned details widget/tooltips, and updated installer presentation. * **Documentation** * Expanded Storybook component/page coverage and adjusted Storybook canvas padding. * **Tests** * Added/updated unit and integration tests for pinning, auto-update flows, and new modal/UI behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d5afa45efd |
Pin-cleanup on FMA delete (#48333)
**Related issue:** Resolves #48309 Deleting a Fleet-maintained app from a team now also deletes its `software_title_team_pins` row. Previously the pin survived the delete (the FK cascades only on title deletion, and the title row outlives the installer rows), so re-adding the app resurfaced a stale pin pointing at a version no longer cached. # 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. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually |
||
|
|
0b6f8066db |
Return per-version filename in fleet_maintained_versions (#48335)
**Related issue:** Resolves #48334 The software title response now returns a per-version `filename` in `fleet_maintained_versions`, and the Library version rows render each version's own filename instead of the active installer's. Previously, every cached-version row showed the active installer's filename because the array didn't include one. # 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. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually |
||
|
|
a2af2d97a0 |
Adding BYOD backend changes (#47716)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** #23242 Backend changes for Apple BYOD (personal) MDM enrollment. - Adds a `byod` enrollment path that distinguishes personal devices from organization-owned devices. - Persists per-host Apple MDM enrollment access rights in a new `host_mdm_apple_enrollment_permissions` table so SCEP/ACME renewal honours Apple's monotonic-narrowing invariant (permissions can never be widened on profile replacement). - Surfaces wipe/lock/clear-passcode allowed flags on host details for manually-enrolled Apple hosts. - Renames the personal enrollment status label to `On (manual - personal)`. # 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] 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) - [ ] QA'd all new/changed functionality manually ### Test plan - Manual (profile) enrollment, company-owned: device receives full access rights; wipe/lock/clear-passcode allowed. - Manual (profile) enrollment, personal (BYOD via `byod=1`): device receives narrowed access rights (no device lock/erase); host details show wipe/lock/clear-passcode disabled. - SCEP/ACME renewal for each of the above: renewed profile preserves the original ServerURL (incl. `byod=1`) and the stored (narrowed) access rights; Apple does not reject the replacement. - Renewal batching: multiple company-owned hosts collapse into a single InstallProfile command; a BYOD host gets its own command. - Account-Driven User Enrollment (ADUE): enroll a personal device via ADUE and confirm it is inherently restricted (Apple `UserEnrollment` mode — no device lock/erase regardless of AccessRights), and that its SCEP renewal succeeds and preserves the account-driven enrollment profile. - Deleted-then-returned device: delete a still-enrolled BYOD host in Fleet, let it check back in, and confirm a subsequent SCEP renewal still uses the narrowed permissions. ## 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`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added personal (BYOD) Apple MDM enrollment support across manual profiles, OTA enrollments, and SCEP/ACME certificate renewals, with access rights generated appropriately. * Apple host details now surface per-device permission flags for wipe, lock, and clear passcode when available. * Enrollment status text now shows personal manual enrollments as “On (manual - personal)”. * **Bug Fixes** * Enforced remote wipe/lock (and clear passcode) permissions correctly for personal devices, including persistence across renewals. * Host deletion cleanup now removes newly tracked enrollment permission data. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c226a3feab |
On var change resend Android certificate templates and managed app configs (#48278)
**Related issue:** Resolves #36681, #48042 # 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 - [ ] QA'd all new/changed functionality manually ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Certificate templates and managed Android app configurations now keep track of referenced variables. * Variable changes can now trigger automatic re-sending of affected profiles and app availability updates. * **Bug Fixes** * Resend behavior now refreshes certificate templates when related variable values change. * Android managed app configurations are re-queued when their variables are updated. * **Database** * Added support for variable tracking on certificate templates and Android app configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2f9147e685 | merge main | ||
|
|
6630aec5fb |
Auto-update FMA cron (#48123)
**Related issue:** Resolves #47681 Adds an hourly, Premium-only cron (maintained_apps_auto_update) that keeps Fleet-maintained apps current. For each FMA-backed active installer (per team), it fetches the latest manifest, downloads and caches a newly-published version when the pin allows, and advances the team's active installer based on the pin state: - Unpinned (Latest): download/cache the newest published version and advance the active installer to it. - Caret pin (^N): advance to the newest version within major N (downloading it if newly published). Never cross into another major. - Literal pin: never advance and never download. New versions are cached as additional software_installers rows (no schema change; reuses the existing (global_or_team_id, title_id, version) index), capped at the two most recent per team for rollback. # 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 ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually |
||
|
|
07ebe1d836 |
Check if host is still on script's team before executing batch (#48244)
<!-- 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. - [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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Scheduled batch script execution now re-checks host team membership at execution time, skipping any hosts moved to a different team before the batch runs. * Added a clear “team mismatch” incompatibility outcome and ensured incompatible hosts are not queued for execution. * **Tests** * Expanded script scheduling tests to cover host-to-team transfers between scheduling and execution, including updated incompatibility counts and per-host expectations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
faff41e41d |
Fix My device page software sorting by display name (#45836)
**Related issue:** Closes #43673 (remaining issue reported by @getvictor after PR #44873) ## Changes The "My device" page / host details software tab sorts software by `software_titles.name` (often an installer filename) instead of the custom display name. PR #44873 fixed this for the global `/software/titles` endpoint but missed the host-specific `ListHostSoftware` query path. **Fix:** Add a `LEFT JOIN software_title_display_names` to the outer query wrapper in `ListHostSoftware`, and update `hostSoftwareAllowedOrderKeys` to use `COALESCE(NULLIF(stdn.display_name, ''), name)` so display names are used for sorting when set. **1 file changed:** `server/datastore/mysql/software.go` # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Dante Catalfamo <43040593+dantecatalfamo@users.noreply.github.com> |
||
|
|
d66242856f |
Disambiguate FMAs sharing macOS bundle IDs (#47951)
Fix handling of Fleet-maintained apps that share a macOS bundle identifier (e.g. Firefox and Firefox ESR). Removed the blind rename from UpsertMaintainedApp and added ReconcileMaintainedAppSoftwareNames: a two-pass, idempotent reconciliation that (1) renames titles tied to a single FMA via installer links and (2) heuristically renames by bundle identifier only when the identifier maps to exactly one FMA name. Updated team join logic to prefer matching by installer link and fall back to bundle identifier, changed GetFMANamesByIdentifier to omit ambiguous identifiers, added a call to reconcile during the maintained-apps sync, and extended the datastore interface and mock accordingly. Added tests and a manifest check for known shared identifiers, plus a changelog entry. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #42445 # 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) - [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 - [ ] 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 ## Bug Fixes * Fixed an issue where macOS apps sharing a bundle identifier (e.g., Firefox and Firefox ESR) would incorrectly report each other as already installed and could have their software titles unexpectedly changed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
20af889c56 | Add regression test for #46604 (#46613) | ||
|
|
b784de80b0 |
Cancel software install records instead of deleting when an installer is deleted (#48127)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47348 Does two things: - Removes the software_installers and software_titles joins. These could be null, but we would still want to create software install records for these installs even if the installer or title were deleted. - Changes every case where a host_software_installs is deleted into setting the canceled flag to 1 on that row. It also updates some comments. `deletePendingSoftwareInstallsForPolicy` had a comment that said it should be called _after_ deleting a policy, but that seems wrong and was not actually reflected in the code even when it was originally added. It should be called _before_ deleting the policy so that the siua.policy_id column is still available before it gets set to null by the FK constraint. Same for `deletePendingHostScriptExecutionsForPolicy`. Also removes the `NOTE(mna): ...` comment, because it seems like the code works as intended and only the comments were wrong. # 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) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Prevented a 500 error when late software installation results are reported after the related installer has been deleted. * Pending software install entries are now preserved as **canceled** (instead of being deleted) during installer, policy, and batch update flows, keeping results consistent. * Improved correctness of intermediate failure recording and setup-experience deletion behavior, including distinguishing **canceled** vs **removed** installs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b55d45806c |
Align software category name comparison with DB (#47983)
Normalize category name comparisons to match MySQL's utf8mb4_unicode_ci collation (case-insensitive and ignoring Unicode variation selectors) to avoid duplicate-entry errors. Add normalizeSoftwareCategoryName and SoftwareCategoryNamesEqual (server/fleet/software.go) and use them where categories are deduped (ee/server/service/software_installers.go). Make batch insert idempotent by using ON DUPLICATE KEY UPDATE in the MySQL batch insert (server/datastore/mysql/software.go). Add tests for name-equality behavior and idempotent batch inserts (server/fleet/software_test.go, server/datastore/mysql/software_test.go). This prevents collisions between visually identical emoji forms (e.g. with/without U+FE0F) and tolerates concurrent/default category inserts. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47981 # 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 * **Bug Fixes** * Fixed GitOps runs failing due to software category duplicate-entry errors when names contain certain Unicode characters (e.g., emoji variation selectors). * **Improvements** * Enhanced software category deduplication to properly handle Unicode-equivalent names. * Made batch category insertion operations idempotent to prevent duplicate-key errors. * **Tests** * Added tests for software category idempotency and Unicode character handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8e94d5e820 |
Remove unused migration tests (#48074)
This is just removing tests that are never run (always skipped), see: https://github.com/fleetdm/fleet/blob/7fa7e8f26d108c9421ed7b8e83ffde4468dab6ba/server/datastore/mysql/migrations/tables/migration_test.go#L101-L110 - [X] QA'd all new/changed functionality manually |
||
|
|
5c3eacae21 |
Extend update software installer API to support FMA version pinning (#47808)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46726 Updates the `PATCH /api/v1/fleet/software/titles/:id/package` endpoint to be able to set the pinned version in the `software_title_team_pins` table and set the active installer if it changed. `GET /software/titles/:id` returns the pinned version for a title from that table now. A few small fixes and updates that are related to this feature but not strictly in the scope of the subtask are also included (see individual comments). # 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 - [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 ## New Fleet configuration settings This setting is already handled by gitops, this PR adds control of it with the update software installer api - [ ] 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` - TODO in another PR - [ ] 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added version pinning for Fleet-maintained app installers, allowing teams to lock to specific versions or clear pins to use "Latest" * Policies automatically repoint to the newly active installer when a version pin is changed * Support for semantic version syntax including caret-style version constraints * **Tests** * Added comprehensive integration test for Fleet-maintained app version pinning workflows and validation rules <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a972ca21b0 |
Add "Support" default software category (#47923)
**Related issue:** Resolves #48064 Adds a new default self-service software category, rendered as **🛟 Support**, alongside the existing six defaults (Browsers, Communication, Developer tools, Productivity, Security, Utilities). ## What changed **Backend (Go)** - `server/fleet/software.go` — added `🛟 Support` to `DefaultSelfServiceCategoryNames` (seeds new fleets) and `"Support": "🛟 Support"` to `LegacySoftwareCategoryNames` (so GitOps/FMA manifests can reference the non-emoji `Support`). - New migration `20260619120000_AddSupportSoftwareCategory` — inserts the global default (`team_id=0`) and backfills every existing fleet. Timestamps pinned for deterministic schema dumps; `INSERT IGNORE` guards the `(team_id, name)` unique key. - `schema.sql` regenerated via `tools/dbutils`. - `cmd/maintained-apps/main.go` — added `Support` to the FMA validator allowlist. **Frontend** - `frontend/interfaces/software.ts` — added `"Support"` to the `SoftwareCategory` union. - `frontend/pages/hosts/details/cards/Software/SelfService/helpers.ts` — added `{ label: "🛟 Support", value: "Support" }` to the fallback list. **Docs** - `docs/Configuration/yaml-files.md` — documented `Support` as a supported GitOps category. ## Note on sort order `ListSoftwareCategories` does `ORDER BY name` under `utf8mb4_unicode_ci`, which sorts by the word after the (ignorable) emoji. `🛟 Support` is therefore placed between `🔐 Security` and `🛠️ Utilities`. # 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), 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 Verified against a dockerized MySQL: - Migration test `TestUp_20260619120000` - `TestSoftware/SoftwareCategoryCRUD` (order-sensitive assertion) - `TestSelfServiceCategoriesCRUD` + `TestDeviceSelfServiceCategories` integration tests - `cmd/maintained-apps` tests, ee categories test, `go vet`, `make lint-go-incremental` (0 issues) - `tools/dbutils` schema regeneration matches ## 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 - [x] Verified the setting is documented (GitOps `categories` supported values in `docs/Configuration/yaml-files.md`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced the "🛟 Support" category as a new self-service software classification option. Users can now better organize support-related applications within their software catalog. The category is available globally across all teams, providing improved organization and discovery capabilities for support applications alongside utilities and other existing software categories. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
47db1a63bd |
Fix host software details dropping pending installs/uninstalls (#47954)
**Related issue:** Related to #47839 Follow-up to #47949 (same root cause, same issue). That PR fixed the OR-dominance drop out in the software *title summary* queries; this applies the same fix to the four per-host queries behind a host's *software details* page. A host with more than one queued install or uninstall for the same installer, VPP app, or in-house app could disappear from its software details page: the old self anti-join's `(priority < OR created_at >)` predicate let two rows eliminate each other, so neither survived. This rewrites those four queries (`hostSoftwareInstalls`, `hostSoftwareUninstalls`, `hostVPPInstalls`, `hostInHouseInstalls`) to rank with `ROW_NUMBER()` and keep one row per item. No performance change — these are per-host queries. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] `SELECT *` is avoided and SQL injection is prevented (named placeholders used for all values in the modified statements). ## 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) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed an issue where installers, VPP apps, and in-house apps could disappear from a host's software details page when multiple install or uninstall actions were queued for the same item. * **Tests** * Added regression tests to prevent this issue from recurring. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
cf32a02fbc |
Bump migrations that conflict with v4.87 (#48002)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves migration failure dsicussed here: https://fleetdm.slack.com/archives/C019WG4GH0A/p1782131309693279 20260610172952_AddHasACMEPayloadToHostMDMAppleProfiles.go was backported to v4.87 but had a newer timestamp so would have conflicted with migrations merged in the frist few days of v4.89 development # Checklist for submitter If some of the following don't apply, delete the relevant line. No changes file as this is ultimately an `unreleased-bug` - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] QA'd all new/changed functionality manually ## 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`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for policy gating in setup workflows. * Added support for BYOD fleet and enrollment tracking capabilities. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3f5b58888f |
Fix software title page timeout for large upcoming-activity backlogs (#47949)
**Related issue:** Resolves #47839 The software title details page (`GET /api/v1/fleet/software/titles/{id}`) could take minutes to load and return a 500 or 502 when an installer, VPP app, or in-house app was scoped to many hosts. The cause was the status summary query. To find each host's most recent pending activity, it joined `upcoming_activities` to itself, and an `OR` in the join condition stopped MySQL from using an index. The query got much slower as the pending backlog grew. This rewrites the query in all three summary functions (`GetSummaryHostSoftwareInstalls`, `GetSummaryHostVPPAppInstalls`, `GetSummaryHostInHouseAppInstalls`) to use a `ROW_NUMBER()` window function. It filters to the installer or app first, then picks each host's most recent activity, which removes the self-join. It also fixes a related bug where the old `OR` condition could drop a host from the counts. Verified live against a 6,000-host backlog. The page went from ~12.7s to ~1.1s with identical status counts. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-chan ges.md#changes-files) for more information. - [x] `SELECT *` is avoided and SQL injection is prevented (named placeholders used for all values in the modified statements). ## 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 ## Before (reproduction): [before.webm](https://github.com/user-attachments/assets/f03154d5-6062-42e3-81d3-ce33b0809145) ## After (fix): [after.webm](https://github.com/user-attachments/assets/b6d1ce53-7778-4023-84b7-56c49d846649) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed software title details pages timing out for installers, VPP apps, and in-house apps when hosts have large backlogs of pending activities. * Improved pending software install status selection to prevent hosts from being dropped or counted inconsistently when multiple upcoming activities exist. * **Tests** * Added regression coverage for upcoming-per-host counting without dropouts when multiple queued activity entries share the same host and app context. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fcd99a1842 |
Fix GenerateHostStatusStatistics query so that hosts enrolled chart is accurate (#47791)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47605 # Details The queries in GenerateHostStatusStatistics (which feeds the host_summary API) were incorrectly filtering out hosts that had been removed from ABM from the denominator (i.e. "total hosts") count, while keeping them in the per-platform counts. This PR fixes the query so that the sum of the platforms matches the total. # 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 **Before** <img width="499" height="420" alt="image" src="https://github.com/user-attachments/assets/9b8d22bc-1dac-49e6-9d2f-8ce9ffda5f17" /> **After** <img width="501" height="420" alt="image" src="https://github.com/user-attachments/assets/fe3705b7-9a90-4d9c-a9dc-b04b2905f3fb" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed an issue causing incorrect platform percentage breakdowns in the "Hosts enrolled" dashboard chart. * Corrected host status calculations to ensure accurate total and per-platform host counts by properly handling device enrollment assignment records. * **Tests** * Added regression tests to validate the correct handling of device enrollment records in host status calculations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5368b99636 |
Policy status page: automation activity history, reset endpoint, and details UI
Resolves #38670 Adds the backend and frontend for the Policy status page — a historical, per-host view of policy automation outcomes — plus a way to reset a policy's results. |
||
|
|
ad52492c78 |
Undo rename from utilities to support (#47881)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # ## 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) - [x] QA'd all new/changed functionality manually Tested with fleet maintained apps and VPP in UI and gitops 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 N/A since this is just editing the existing migration - [ ] 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: - [x] 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) - [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) - newly added custom category, or default category, was cleared if was not in the yaml file - [ ] 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 * **Bug Fixes** * Corrected the “Productivity” category emoji/name and the “Utilities” category emoji/name across the system for consistent display and behavior. * **Tests** * Updated unit, integration, and handler tests to expect the corrected category strings and delete-button labels. * **Chores** * Refreshed database seed data and migration/test expectations to align default and per-team category names, preserving IDs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b32ceb72e1 |
Added variables in Android configuration profiles (#47750)
**Related issue:** Resolves https://github.com/fleetdm/fleet/issues/41968 # 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 - [ ] QA'd all new/changed functionality manually ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for using Fleet variables (`$FLEET_VAR_HOST_*`) in Android configuration profiles, enabling per-host dynamic value substitution during deployment. * **Improvements** * Strengthened Android profile validation to reject unsupported Fleet variables and prevent invalid placements (for example, using variables in JSON object keys or non-string fields). * Enhanced deployment behavior when variables can’t be resolved for a host, marking affected profiles as delivery failed and avoiding partial policy application. * Improved Android per-host rollout by applying installs in staggered batches for smoother throughput. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8d26d298e2 |
fixed update teams not updating appconfig, and team delete not cleaning up appconfig (#47826)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Unreleased bugs while going through test plan # 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. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Apple Business Manager (ABM) token team assignments now stay synchronized when team defaults change across BYOD, macOS, iOS, and iPadOS. * “No team” selections are now saved as cleared (empty) assignments for cleaner configuration output. * Improved ABM token cleanup during team deletion to remove references tied to the deleted team. * **Tests** * Added/extended coverage for ABM token team update behavior (including invalid team handling and nil inputs) and deletion cleanup. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a2757a1d7c |
Don't require end user auth on orbit re-enrollment (#46300) (#47740)
Windows and Linux hosts that had already orbit-enrolled were prompted for end user authentication (an SSO browser tab) when fleetd re-enrolled after a service restart, node key file loss, or osquery DB rebuild. Hosts enrolled before EUA was enabled have no host_mdm_idp_accounts row, so the service-layer EUA gate treated every re-enroll like a brand-new device. Before returning END_USER_AUTH_REQUIRED, EnrollOrbit now checks whether a host matching the enrollment identifiers already exists and previously held an orbit node key (HostPreviouslyOrbitEnrolled, reusing matchHostDuringEnrollment's semantics). If so, the re-enroll proceeds without prompting. Genuinely new devices, and hosts moved to a different Fleet server, are still gated. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46300 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit **Bug Fixes** * Fixed unnecessary end-user authentication prompts for Windows and Linux hosts during fleetd re-enrollment after a service restart. Previously enrolled devices can now re-enroll without being prompted for SSO authentication, while new devices still require the appropriate authentication. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
75a0a03732 |
Pin Fleet-maintained apps - migration (#47778)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47678 # 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) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Teams can now pin software titles to designate preferred versions for tracking and management. * **Chores** * Database schema updated to support software title pinning. * Updated team deletion procedures to handle associated pins. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f677e904ab | Self-service categories: bug fixes on empty state, fleet-free layout, dropped fleet_id (#47779) | ||
|
|
042b0b0498 |
Prevent in-flight carves from being wrongly expired by S3 cleanup
Relates to #43045 Skip carves whose upload has not completed (BlocksComplete) so cleanup only reconciles carves that should already have a listable object. |
||
|
|
ead9d40293 |
Added FLEET_VAR_HOST to android configs (#47642)
**Related issue:** Resolves #45353 # 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 - [ ] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added support for `$FLEET_VAR_HOST_*` variables in Android managed app configurations, including host UUID, hardware serial, platform, and end-user IdP details. * **Improvements** * Android app configurations are now validated to reject unsupported Fleet variables. * Fleet variables are substituted with real per-host values during Android app configuration deployment, including batch/GitOps and host-specific workflows. * **Tests** * Added unit and integration coverage for supported/unsupported variables, substitution behavior, and JSON escaping. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fe4d74edc2 |
Join MDM for missing status for non osquery devices (#47672)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46243 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed incorrect reporting of iOS, iPadOS, and Android hosts as missing (including MIA and missing-over-30-days counts). * Host status filtering and dashboard cards now correctly fall back to Apple MDM activity when OSQuery “last seen” data is unavailable, preventing recently active devices from being flagged. * **Tests** * Added coverage to verify iOS/iPadOS hosts aren’t treated as missing when Apple MDM “last seen” is recent, and are flagged once it becomes stale. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |