e8f26ec4ef2e8a872778cb364b03b60a597871fe
5222
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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 --> |
||
|
|
a90eab6f62 |
Improved GitOps consistency for Windows BatchSetMDMProfiles (#48467)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves https://github.com/fleetdm/confidential/issues/16293 Test failures are not related to this change. They are currently failing on main. # 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** * Improved consistency when applying Windows configuration profiles in batch by validating against the latest server MDM state. * Fixed an issue where a temporary “assume enabled” setting could affect real configuration updates; it now applies only to dry runs. * Ensured team profile validation uses the freshly persisted server state during the same GitOps execution. * Added a regression test covering Windows MDM “assume enabled” behavior for dry-run vs real runs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5d531c10d9 |
Fix orbit nudge test mdm connection fidelity (#48423)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #44629 Test fix only. Test now distinguishes between being connected to Fleet MDM and being connected but not osquery-enrolled. [ ] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Tests** * Improved validation of host configuration nudge behavior by refining how Fleet MDM connection states are simulated. * Test scenarios now better cover: enrolled but not connected to Fleet MDM, and connected to Fleet MDM without enrollment. <!-- 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> |
||
|
|
40d286cbb4 |
Add Cache-Control to static assets served under /assets/ (#48409)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45682 # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually #### Before <img width="1252" height="1027" alt="Screenshot 2026-06-29 at 10 33 15 AM" src="https://github.com/user-attachments/assets/847ee011-7d2c-4cd2-9882-1508ed77bbd7" /> <img width="1248" height="1008" alt="Screenshot 2026-06-29 at 10 33 21 AM" src="https://github.com/user-attachments/assets/859c2860-5fdb-43f2-8323-af8fc0665ff8" /> #### After <img width="1198" height="819" alt="Screenshot 2026-06-29 at 10 29 25 AM" src="https://github.com/user-attachments/assets/b96a134a-1271-40f5-99ca-802c7a1fbe10" /> <img width="1201" height="804" alt="Screenshot 2026-06-29 at 10 29 29 AM" src="https://github.com/user-attachments/assets/37c4c262-95ce-4a77-8979-49944e7f2b75" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Content-hashed static assets under `/assets/` (e.g., hashed JS/CSS, images, fonts) now use long-lived, immutable `Cache-Control` to improve repeat page loads. * **Bug Fixes** * `Cache-Control` is now applied consistently for successful responses and `304 Not Modified`. * Non-hashed assets and non-success/error responses correctly avoid caching via `Cache-Control: no-cache`. * **Documentation** * Added a release note explaining the new `Cache-Control` behavior for hashed assets. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ed14c5385c |
Fix API endpoint validation for prefix-mounted SCIM routes
The SCIM endpoints are served by the elimity-com/scim library mounted as a single prefix handler on the root ServeMux, so they are never registered as individual gorilla/mux routes. Since the routes can't be discovered, supply them to the validator instead: add scim.RegisterValidationRoutes, a FeatureRouteFunc that registers stub routes for the SCIM endpoints (handlers are never invoked, only their path templates and methods are inspected). Wire it into the three Validate call sites (production serve, test helper, svctest). |
||
|
|
2c3e38b737 |
Foreign vitals mapping: Update SCIM integration instructions (#48413)
- Update the best practice is to create an API-only user w/ the admin role and access only to necessary SCIM API endpoints - These doc updates require [this bug](https://github.com/fleetdm/fleet/issues/48062) to be fixed because the `/scim/*` API endpoints aren't exposed as API endpoints one can pick when creating an API only user - Document the `/scim/*` API endpoints <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added SCIM API endpoints for managing users and groups. * Supported actions include listing, creating, viewing, replacing, updating, and deleting SCIM users and groups. * Added read-only endpoints for SCIM schemas, service provider configuration, and resource types. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Rachael Shaw <r@rachael.wtf> |
||
|
|
2ce30968f8 | Detect Citrix Workspace LTSR cumulative updates (#41790) (#47591) | ||
|
|
c15844c87b | Fix CPE generation for Citrix Workspace without YYMM suffix (#46811) (#47545) | ||
|
|
ddc126ea8d |
Google Workspace IdP [4/6]: fleetctl generate-gitops support (#48167)
### 🥞 Stack (review/merge bottom-up) 1. #48164 — Activity types (FE+BE) 2. #48165 — Backend (cron + directory sync) 3. #48166 — Usage statistics 4. **#48167 — fleetctl generate-gitops ⬅ this PR** 5. #48168 — Settings UI 📄 Documentation is tracked separately in #48169 (targets `docs-v4.89.0`). --- ## Summary **PR 4 of 6.** **GitOps / fleetctl**: `fleetctl generate-gitops` support for the Google Workspace integration, redacting `api_key_json` with a TODO + secret warning, plus updated golden testdata. > 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-3-statistics` (PR 3). **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** * GitOps now supports Google Workspace settings in organization configuration output. * **Bug Fixes** * Free-tier accounts no longer include Google Workspace settings in global GitOps output. * Sensitive Google Workspace API key content is now replaced with a placeholder in generated GitOps files, with a warning recorded. * GitOps applies a clear state when Google Workspace settings are omitted or left empty. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
8cf1796a7d |
Support advanced options for script-only packages (#48315)
**Related issue:** Resolves #42797 Adds support for pre-install query, post-install script, and uninstall script on script-only packages (`.sh` and `.ps1`) across the API, UI, and GitOps; previously these were silently stripped. The install script remains the uploaded file's contents (file-driven) and is shown read-only. Automatic install stays unsupported for script-only packages. - **API** (`POST`/`PATCH /software/package`): stop stripping the fields; validate post-install and uninstall scripts for script packages - **GitOps**: allow `uninstall_script`/`post_install_script`/`pre_install_query` paths inline in the team YAML for script-only packages - **UI**: show advanced options for `.sh`/`.ps1`; install script shown read-only # 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Script-only packages (`.sh`/`.ps1`) now expose advanced options—pre-install query, post-install script, and uninstall script—consistently across the UI, REST API, and GitOps. * Script-only packages display advanced options in the UI, and the “Install script” editor can be made read-only where appropriate. * **Bug Fixes** * Preserved advanced option values for script-only packages during upload, edits, and synchronization (including replace-file scenarios). * Improved YAML generation and validation so supported fields are included while unsupported ones are correctly rejected/omitted. <!-- 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 --> |
||
|
|
ef0a051482 |
Google Workspace IdP [2/6]: backend (cron + directory sync) (#48165)
### 🥞 Stack (review/merge bottom-up) 1. #48164 — Activity types (FE+BE) 2. **#48165 — Backend (cron + directory sync) ⬅ this PR** 3. #48166 — Usage statistics 4. #48167 — fleetctl generate-gitops 5. #48168 — Settings UI 📄 Documentation is tracked separately in #48169 (targets `docs-v4.89.0`). --- ## Summary **PR 2 of 6.** Core **backend** for the Google Workspace IdP integration: - Directory sync client (`ee/server/googleworkspace/`) and cron job (`server/cron/google_workspace_cron.go`) reusing the `scim_*` tables (Google Workspace and SCIM are mutually exclusive). - Config types + validation (`server/fleet/google_workspace.go`, `app.go`, `integrations.go`), appconfig handling + activity emission (`server/service/appconfig.go`), cron registration and schedule. - SCIM is ignored while Google Workspace is configured (`ee/server/scim/scim.go`). > 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-1-activities` (PR 1) — review/merge that first. **Related issue:** Resolves #42915 # Checklist for submitter - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements). - [ ] Timeouts are implemented and retries are limited to avoid infinite loops. ## Testing - [ ] Added/updated automated tests - [ ] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Google Workspace integration support for syncing users, groups, and host-related identity data. * Added a scheduled sync that keeps directory data up to date automatically. * Added support for configuring Google Workspace in app settings, with validation and masking of sensitive credentials. * **Bug Fixes** * Prevented SCIM provisioning from overwriting data when Google Workspace sync is configured. * Preserved existing Google Workspace credentials when an update omits masked API key values. * Added handling for deleted users and group membership changes during sync. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7f8e800003 |
Add private network IP blocking for outbound HTTP requests (#46463)
**Related issue:** N/A (security hardening) # 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. - [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 ## Summary Added network-level validation for outbound HTTP requests made by Fleet integrations (webhooks, SSO, Jira, Zendesk, certificate authorities, etc.) to prevent requests to unintended destinations. Includes a configuration option for environments that require connectivity to private network addresses. Also fixes a pre-existing nil pointer panic in Jira retry logic and ensures all HTTP clients use the validated transport. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually Unit and integration tests cover validation logic, boundary conditions, and multiple configuration modes. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
b1c3a31dac |
Google Workspace IdP [1/6]: activity types (frontend + backend) (#48164)
### 🥞 Stack (review/merge bottom-up) 1. **#48164 — Activity types (FE+BE) ⬅ this PR** 2. #48165 — Backend (cron + directory sync) 3. #48166 — Usage statistics 4. #48167 — fleetctl generate-gitops 5. #48168 — Settings UI 📄 Documentation is tracked separately in #48169 (targets `docs-v4.89.0`). --- ## Summary **PR 1 of 6** — splits the Google Workspace IdP host-vitals feature into a reviewable stack. Adds the **activity types** for the Google Workspace integration, frontend and backend: - Backend: `added_google_workspace_integration`, `edited_google_workspace_integration`, `deleted_google_workspace_integration` (`server/fleet/activities.go`). - Frontend: activity-feed rendering for those three types (`activity.ts` enum + display names + `domain` detail; `GlobalActivityItem.tsx` templates). > 🥞 **Stacked PR.** Base: `main`. **Related issue:** Resolves #42915 # Checklist for submitter - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements). - [ ] Timeouts are implemented and retries are limited to avoid infinite loops. ## Testing - [ ] Added/updated automated tests - [ ] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for new Google Workspace integration activity entries: added, edited, and deleted. * Activity feeds now display the integration domain when available. * New filter labels were added for these activity types. * **Bug Fixes** * Activity details now render Google Workspace integration events correctly in the dashboard feed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ba814f4965 |
Fix gitops leaving temporary url for script-only package in datastore (#48370)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47947 # 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 ## 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) - [ ] 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 * **Bug Fixes** * Fixed GitOps generation for script-only packages added by path so it no longer creates invalid output files. * Script package entries now use cleaner comments, while regular packages still show version details. * Placeholder `script://` installer URLs are now cleared properly and won’t remain stored after processing. * **Tests** * Added coverage for script package comment formatting and for clearing placeholder installer URLs during GitOps workflows. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
bef74a6ff5 |
Add per-host reverse index for small-target live queries
Resolves #42441 Store queries that target at most redis.live_query_small_target_threshold hosts (default 1000) in a per-host reverse index instead instead of a per-query bitfield indexed by host ID. Setting the threshold to 0 disables the reverse index (no query has <= 0 targets), serving as the kill-switch. |
||
|
|
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 --> |
||
|
|
a764e5d595 |
Parse both date formats while parsing macos profiles for verification (#48328)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45947 # 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 We do not know how to repro the customer issue and I spent about 6 hours across a couple of days throwing everything I could at it so testing was limited to macos profile verification smoke testing and unit tests to confirm the time we see from customer logs and queries is now supported <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Bug Fixes** * Fixed an issue where macOS configuration profiles could get stuck in “Verifying” when the reported install date uses a 12-hour time format. * Improved parsing of locale-formatted install dates, including handling of special spacing characters found on newer macOS versions. * Enhanced validation so unsupported or empty install date formats return clearer error messages. <!-- 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 --> |
||
|
|
ce1f85b9b8 |
Use active custom script if available (#48350)
**Related issue:** Resolves #48301 When the auto-update cron downloads a new Fleet-maintained app version, it now carries forward the previously-active install/uninstall scripts when they were customized (e.g. via GitOps), instead of overwriting them with the manifest defaults. Customization is detected per-script by comparing the active scripts against the manifest (the uninstall script is compared against the manifest template substituted with the active version's package IDs, since it's version-specific). When the active scripts match the manifest, the new version's manifest scripts are used as before. # 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 |
||
|
|
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 |
||
|
|
194f0cfb8f |
Fix SSO callback URLs doubling the subpath under a URL prefix
Fixes #46641 When Fleet runs under a subpath, server_url already includes that subpath, so appending url_prefix again produced a doubled ACS callback path (e.g. https://host/subpath/subpath/api/v1/fleet/sso/callback), breaking SAML authentication for both login and MDM end user authentication. Drop url_prefix from the callback URL construction so the path is appended directly to server_url, which is the full external base URL. Fixes the same flaw in all five ACS-construction sites: login SSO initiate and callback, and MDM SSO initiate plus both callback branches. |
||
|
|
8b737cc87c |
Fix duplicated URL prefix in transactional email links for subpath deployments
Fixes #46642 When Fleet is deployed under a subpath, server_url already carries that subpath, so the email link base was being built as server_url + url_prefix, duplicating the path (e.g. https://host/subpath/subpath/login/reset) and producing 404 links. Use server_url directly as the link base, matching how the rest of the codebase already treats server_url as the full external base URL. |
||
|
|
657ba985c3 |
Fix returned values on MDM command results endpoint (#48296)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # Fix tagging of hostnames on returned MDM command results so all returned results have a hostname # 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** * Fixed an issue where some MDM command results could return without hostnames. * Improved result visibility so only hosts the caller is allowed to see are included. * Ensured team-scoped users see only their permitted results, while global admins continue to see all available results. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
d563ed21a1 |
Add activity and enable managed account fleets endpoint (#48273)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #44153 - Adds mdm enabled and configured checks for the update fleet endpoint - Adds activity creation for the update fleet endpoint + gitops apply # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] 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 - [ ] 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) - [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) - [ ] 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 ## Summary by CodeRabbit * **New Features** * Added activity logs when the managed local account setting is enabled or disabled. * Managed local account updates now work consistently through both the Update Fleet endpoint and GitOps. * **Bug Fixes** * Prevented enabling managed local account unless macOS MDM is enabled and configured. * No activity is created when the setting is saved without any actual change. <!-- 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 --> |
||
|
|
608bd2764c |
Restrict conditional access Okta IdP asset endpoints to privileged roles (#48294)
# Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`. - [x] Input data is properly validated (authorization policy change only). ## Testing - [x] Added/updated automated tests — the role matrix in `TestConditionalAccessGetIdPSigningCertAuth` and `TestConditionalAccessGetIdPAppleProfileAuth` now asserts observer and observer+ are denied; `go test ./server/authz/` confirms the policy compiles. - [x] QA'd all new/changed functionality manually — covered by the automated role-matrix tests for this authz-only change. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Tightened access to conditional access identity provider assets so only higher-privilege roles can read them. * Users with observer and observer+ roles can no longer access these endpoints. * Updated validation coverage to reflect the revised access behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2f9147e685 | merge main | ||
|
|
d079bda8b3 |
Fix required password reset logging users out (#48287)
# Checklist for submitter - [x] Changes file added for user-visible changes in `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. ## Summary Fixes a regression from #47860 where `PerformRequiredPasswordReset` cleared **all** sessions (including the one the user was actively using), causing an error after completing the forced password reset. **Issue:** #47860 changed `setNewPassword(ctx, user, password, false)` to `true`, which calls `DestroyAllSessionsForUser`. This broke the first-login flow for new users: they'd complete the password reset successfully but then get a 401 because their own session was destroyed. **Fix:** Revert to `clearSessions=false`, then selectively destroy all sessions except the current one using `ListSessionsForUser` + `DestroySession`. This preserves the user's active session while still invalidating any other sessions. ## Reproduction 1. Create a new user (admin_forced_password_reset defaults to true) 2. Log in as the new user in an incognito window 3. Complete the required password reset 4. **Before fix:** 401 error, user is logged out 5. **After fix:** User lands on the home screen normally ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually - [x] Confirmed that the fix is not expected to adversely impact load test results ### QA results **Test 1: Security scenario (original #47860 goal)** | Step | Result | |------|--------| | Admin flags user for required password reset | Sessions cleared, `force_password_reset=true` | | Attacker logs in with old password | Gets restricted session (401 on `/hosts`) | | Real user performs required password reset | Succeeds, `force_password_reset=false` | | Attacker session invalidated | **PASS** (401 on `/me`) | | Real user session preserved | **PASS** (200 on `/me`) | | New password works | **PASS** | | Old password rejected | **PASS** | **Test 2: Regression fix (Lucas's repro)** | Step | Result | |------|--------| | Create new user (forced reset defaults to true) | `force_password_reset=true` | | Log in as new user | Token received | | Complete required password reset | Succeeds, `force_password_reset=false` | | User session still works after reset | **PASS** (200 on `/me`) | |
||
|
|
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> |
||
|
|
214619d935 |
Refactor makeAndroidAppAvailable to use staggered job queuing (#47880)
**Related issue:** Resolves #47543 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Updated Android app availability to use staggered batch jobs instead of processing everything at once, improving throughput and smoothing workload. * **New Features** * Added batched handling that can perform per-host managed configuration substitution when variables are present, including scheduling “pending apply config” updates when required. * **Configuration** * Reduced the default Android batch size (`mdm.android_batch_size`) to 100. * **Bug Fixes / Tests** * Updated unit and integration tests to verify batching, staggering timing, full host coverage, and order-independent policy application behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1b64b6104a |
Fix NDES not using the same retry clearing method as SmallStep for macos (#48105)
**Related issue:** Resolves #46291 |
||
|
|
26414db4ea |
Restrict authorization for team membership operations (#48201)
**Related issue:** N/A # 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] Reproduced the issue and verified the fix - [x] QA'd all new/changed functionality manually ## Summary - Introduced a more granular authorization action for team membership management - Updated OPA policy and service-layer authorization accordingly - Added comprehensive authorization test coverage ## Reproduction Verified that with the previous authorization check, an API-only user with team-scoped write access could call `PATCH /api/latest/fleet/teams/{id}/users` to modify team membership without restriction. After the fix, the operation correctly returns a 403 Forbidden for non-admin roles. Admin users retain full access to manage team membership. **Test**: `TestGitOpsCannotManageTeamMembers` in `server/service/teams_test.go` explicitly exercises this scenario and confirms the fix. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Tightened team member management so adding/removing team users now requires a dedicated team-membership write permission (global admins and team admins only, scoped appropriately). * Prevented GitOps users from modifying team membership, including self-promotion to admin. * Updated enterprise integration expectations to return **403 Forbidden** for blocked membership change attempts. * **Tests** * Expanded authorization test coverage for team member write access across roles and team scopes. * Added coverage ensuring GitOps cannot manage team members, while valid team admins can. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c041c6c24f |
Fix batch script execution validations (#48243)
<!-- 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** * Improved validation for batch script execution requests. * Added an extra authorization check before a batch script can be scheduled, helping ensure only permitted actions proceed. * Expanded test coverage for role-based access during batch script execution. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
872e38a9f5 |
Download a newly-published FMA version when pinned to it (#48144)
**Related issue:** Resolves #47215 ## Summary Pinning an FMA to a version via GitOps only resolved against versions already cached on the instance. Bumping a pin to a freshly released version failed with `specified version is not available` because Fleet never downloaded a pinned version it hadn't cached. `Hydrate` now falls back to the published app manifest on a cache miss. When the requested version is currently published, Fleet downloads and caches it, so an admin can bump a pin to a new version in a single apply. A version that's neither cached nor published still returns the same error. # Checklist for submitter - [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 |
||
|
|
20af889c56 | Add regression test for #46604 (#46613) | ||
|
|
997a4097c4 | Add docs for chart bounded context (#47877) | ||
|
|
6336443f37 | Report mobile devices in "hosts online" (#47222) | ||
|
|
82f7405f19 | Allow setting default vuln chart filters via GitOps (#47634) |