ebda171dada6c26d61056e23d7620da66066b4e9
3429
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e14ef67b55 |
Fix Windows Autopilot ESP hang: gate release on user-scope ack (#49134) (#49542)
The ESP release wrote the user-scope ServerHasFinishedProvisioning Replace and immediately committed awaiting_configuration=None. During OOBE the device rejects user-scope writes with SyncML 405 until its user MDM context initializes, so the Account setup phase never received its completion signal and the device hung until the 3-hour timeout, while Fleet believed the ESP had completed (and relaxed the DMClient poll, crippling remediation). The release path now stays Active until the device acks the user-scope Replace with a 200: a new resend phase re-sends the Replace once per session (bounded by the existing 3-hour timeout), and the Active->None transition commits only on the 200. Live-validated on Win11 26200 on both a fresh and a re-enrolled device: the 405 reproduced at release time in both flows, and the retried Replace acked 200 one session after the user context came up, releasing the ESP. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49134 # 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] 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Bug Fixes - Fixed an issue where Windows Autopilot enrollment could intermittently hang at **“Account setup”** on the Enrollment Status Page. - Updated Enrollment Status Page release handling so enrollment **stays active until the device acknowledges** the user-scope completion command. - When the user-scope completion is rejected or still unacknowledged, it is **retried in subsequent management sessions** until successfully acknowledged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
17e115a517 |
add mdm configured endpoints for DDM assets for testing (#49633)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # Saw I missed these when doing the DDM assets backend # Checklist for submitter If some of the following don't apply, delete the relevant line. ## 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 * **Tests** * Expanded endpoint coverage for device management asset routes, including listing, retrieving, deleting, and batch creation. * Documented a remaining limitation affecting multipart asset uploads. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
15a0f4b201 |
48342 edit config profile endpoint (#49141)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48342 # 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for editing existing Apple, Windows, and Android configuration profiles through the API. * Supports updating profile content, names where applicable, label targeting, and Fleet variable associations without replacing the profile identity. * Added support for editing Apple DDM declarations. * Added activity tracking for configuration profile edits. * **Bug Fixes** * Added validation for unsupported edits, invalid labels, duplicate names, missing profiles, and protected Fleet-managed profiles. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Jordan Montgomery <elijah.jordan.montgomery@gmail.com> |
||
|
|
900c54e822 |
Fix label membership being cleared when a label query errors (#49403)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46399 When a label's query errors on a host (e.g. the extension socket is unavailable) instead of returning zero rows, Fleet was recording that error the same as a definitive "no match," clearing the host's existing label membership. This could unintentionally remove configuration profiles or other automations scoped to that label. The fix leaves existing label membership untouched when a label query errors. # 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 **Setup:** macOS VM enrolled as a Fleet host, with a dynamic label whose query targets a real, always-present table but with a deliberately invalid `WHERE` clause, so the query fails deterministically (a `no such column` SQL error). ```sql -- working version (label matches) SELECT * FROM os_version; -- broken version (query errors on every run) SELECT * FROM os_version WHERE this_column_does_not_exist = 1; ``` ### Before (bug reproduced on unpatched code) 1. Set the label's query to the working version and refetched the host — confirmed it shows up under the host's Labels. 2. Edited the label's query to the broken version. 3. Clicked **Refetch** on the host. 4. **Result:** the label disappeared from the host's Labels list — a query error incorrectly cleared existing membership. ### After (fix verified) 1. Reset the label's query to the working version and refetched — confirmed membership was restored. 2. Edited the label's query to the broken version again. 3. Clicked **Refetch** on the host. 4. **Result:** the label remained on the host's Labels list — a query error now correctly leaves existing membership untouched. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Preserved existing dynamic label memberships when label queries fail or yield unknown results. * Avoided treating unknown/failed evaluations as label removals. * Ensured label updates/removals are applied only when a definite match or non-match is returned. * **Tests** * Expanded coverage for label query errors across datastore, async processing, and distributed execution to confirm memberships remain unchanged. * Updated expectations for queued async updates to skip errored labels. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7cb2399700 |
Redirect FMA installs to the active version after auto-update (#49525)
**Related issue:** Resolves #49495 Redirects queued Fleet-maintained app installs to the newly-active installer (canceling already-dispatched ones) atomically when an auto-update or pin change flips the active version, and re-resolves install retries to the active installer, so a host no longer installs a superseded cached version. # 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. ## 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** * Fleet-maintained app installs now consistently use the currently active version after automatic promotions, preventing stale installer targeting. * Queued installs tied to an older promoted installer are redirected to the newly active installer instead of being canceled. * Install retry flows now re-resolve to the active installer at retry time, avoiding stale retries after version changes. * **Tests** * Added datastore coverage for active-installer redirection and updated retry tests to verify the correct installer ID is used. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8a33fcd058 |
Fix FMA pinning not changing patch policy (#49519)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49474 # 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 - Relied on integration test for testing changes made by the `maintained_apps_auto_update` job <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed patch policies for Fleet-maintained apps not updating when the active app version changes. * Patch policy queries now refresh to match the currently active (or pinned) installer version, including changes driven by pinning, cron, and GitOps. * Improved behavior when pins are cleared or switched, ensuring the policy continues referencing the correct version-specific query. * **Tests** * Expanded integration coverage to verify version-pinned patch policy queries across scenario updates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
67c06a9820 | Mask team enroll secrets in team write responses (#49422) | ||
|
|
da3f30df79 |
Allow Microsoft conditional access on premium self-hosted (#49414)
Resolves #47699. - [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** * Microsoft Entra Conditional Access is now supported for self-hosted Fleet Premium instances. * Conditional Access is available only on the Fleet Premium license tier. * **Changes** * Removed the Microsoft Compliance Partner API key configuration and updated the proxy behavior accordingly. * Removed the managed-cloud indicator from license/config responses and adjusted related UI rendering and gating. * **Tests / Maintenance** * Updated fixtures and automated tests to reflect the new licensing gates and API/proxy behavior (including updated failure codes). <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d2210243fc |
Rejected empty and whitespace-only enroll secrets when creating or updating teams
Rejected empty and whitespace-only enroll secrets when creating or updating teams |
||
|
|
0d3a3bdc95 |
Added audit activities when secret variables are upserted
Added audit activities when secret variables are created or updated through the `PUT /api/latest/fleet/spec/secret_variables` endpoint. |
||
|
|
57bab9e5ec |
Allow Python script-only packages (#49070)
**Related issue:** Resolves #41470 Adds support for uploading Python (`.py`) script-only software packages — accepted as script-only (the file contents become the install script; advanced options and automatic install follow `.sh`/`.ps1`), assigned the new `py_packages` source, and installable on macOS and Linux hosts across the UI, REST API, and GitOps. Feature branch combining the backend (#48942) and frontend (#48946) sub-PRs. # Checklist for submitter - [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 * **New Features** * Added support for Python (`.py`) script-only software packages across UI uploads, API/self-service installs, and GitOps parsing. * Python installers now derive metadata correctly and render the proper Python icon, with install eligibility for macOS & Linux. * **Bug Fixes** * Improved installer-script validation and “supported file types” error messages to include `.py` (and consistent handling of related script fields/options). * **Tests** * Expanded unit, integration, and GitOps tests to cover Python package parsing, metadata derivation, platform/host eligibility, and UI rendering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
83cef5483f |
Extend support for all built-in
Relates to #38806 Extend host name templates beyond the three host-identity variables to also accept the IdP end-user variables, and re-enqueue the rename when a referenced variable's value changes. Re-enqueue on value change: - An IdP data change (SCIM user/group create/update/delete) re-queues only the affected hosts whose template uses the changed IdP variable — IdP values are per host, so the scope is the specific hosts mapped to that user/group. - A custom (secret) value change re-queues every eligible host in each team / "No team" whose template references the changed secret — secret values are global, so the scope is the whole team/No-team. Built-in variables intentionally NOT supported: - Certificate/CA variables — $FLEET_VAR_NDES_SCEP_CHALLENGE, _NDES_SCEP_PROXY_URL, _CUSTOM_SCEP_CHALLENGE_*, _CUSTOM_SCEP_PROXY_URL_*, _SMALLSTEP_SCEP_CHALLENGE_*, _SMALLSTEP_SCEP_PROXY_URL_*, _DIGICERT_DATA_*, _DIGICERT_PASSWORD_*, _SCEP_WINDOWS_CERTIFICATE_ID, _CERTIFICATE_RENEWAL_ID (and legacy _SCEP_RENEWAL_ID), _PSSO_DEVICE_REGISTRATION_TOKEN. These resolve to one-time SCEP challenges, proxy URLs, base64 PKCS12 cert data, or Fleet-minted tokens — meaningless as a device name, and resolving them has side effects (issuing certificates, consuming one-time challenges) and would leak secrets into a name that's broadcast on-device, in osquery, and in the UI. - Legacy $FLEET_VAR_HOST_END_USER_EMAIL_IDP — deprecated ("avoid in new replacements") and not a documented built-in variable, so it's excluded in favor of the supported IDP_USERNAME variables. |
||
|
|
5f95d683ff |
Speculative fix for iOS/iPadOS enrollment w/ required sw update (#49280)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49260 This fix is based on direct discussion with Apple and consultation of the Apple docs. We are not currently sure if this is actually issue the customer is running into but we have identified it as an issue with our enrollment process. As far as testing my iPad running 18.7 gets prompted to update every time now when I enroll it with updates turned on. If I back up and don't take the upgrade and try to enroll again I get an error but I believe this is an Apple bug which we've been told was fixed in 26+ # 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 during Android Device Enrollment where devices assigned a mandatory software update could incorrectly show a failure status. * Resolved cases where the required software update was not displayed correctly. * Improved Apple device enrollment update details by reporting the operating system version consistently. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e0edd46448 |
Windows MDM: accept discovery RequestVersion >= 4.0 (#49329) (#49380)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49329 ## What & why Fresh **Windows 11 25H2** (build 10.0.26200) devices failed Microsoft Entra / Autopilot MDM auto-enrollment during OOBE with error **80180006**. The device advertises an MS-MDE2 discovery `RequestVersion` of `"9.0"`, and Fleet's `IsValidDiscoveryMsg()` rejected it via an exact-match allow-list (`{"4.0","5.0","6.0","7.0"}`) that could only be changed by rebuilding the server. The discovery **response** already pins the protocol to `EnrollmentVersionV4` (`"4.0"`) and the client negotiates down, so the exact-match check was the only blocker. This PR implements the issue's preferred fix: **accept any `RequestVersion >= 4.0`**, which is forward-compatible with future Windows version bumps. - `server/mdm/microsoft/syncml/syncml.go`: replaced the `SupportedEnrollmentVersions` allow-list var with a `MinSupportedEnrollmentVersion` constant. - `server/fleet/microsoft_mdm.go`: added `enrollmentVersionAtLeast` (numeric component-wise compare, so `"10.0" > "9.0"`) and changed discovery validation to accept any version at or above the minimum. # 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 - [ ] 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 * **Bug Fixes** * Fixed MDM enrollment failures on fresh Windows 11 25H2 and other recent builds. * Discovery requests now accept supported MDE2 `RequestVersion` values at or above the minimum supported version (instead of requiring an exact match). * Invalid or outdated discovery versions now return more specific validation errors. * **Tests** * Added unit test coverage for minimum, equal, newer, and invalid enrollment version comparisons. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
4ce133cb26 | merge main | ||
|
|
b10642be3c |
44954 custom host vitals (#49334)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #44954 # 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Custom Host Vitals management (create/edit/delete, search) with copyable variable tokens and per-host values. * Show Custom Host Vitals on host details, including role-based editing. * Enabled Custom Host Vitals in host-vitals labels and the activity feed. * Extended GitOps to manage global Custom Host Vitals declaratively (including dry-run behavior). * Split Controls → Variables into Global Variables and Custom Host Vitals, including routing updates. * **Bug Fixes** * Improved validation and expansion of Custom Host Vital references across scripts, profiles, installers, and deployments, with clearer failures when values are missing or invalid. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a65af7461e | Merge remote-tracking branch 'origin/main' into feat/28108-multiple-custom-packages | ||
|
|
89ec4f3abb |
Support custom (secret) variables in host name templates
Relates to #38806 Host name templates previously accepted only built-in $FLEET_VAR_* variables and rejected custom $FLEET_SECRET_* (secret) variables. Allow secret variables so admins can embed an org-wide custom value in an Apple host's name. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [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 |
||
|
|
90857fe359 |
Fix multi-package host software details (#49335)
**Related issue:** Resolves #49208 Host software details now show the status and install details for the installer scoped to the host, for titles with multiple packages. No `changes/` file: this is an unreleased bug fix, and the multiple-packages feature PR carries the changes entry. # 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 |
||
|
|
18d3481604 |
Batch extension label-membership checks in GetOrbitConfig (#49154)
**Related issue:** Resolves #45320 # 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. ## Summary `filterExtensionsForHost` (called on every Orbit config fetch, ~30s per host) had an N+1 query pattern: it called `HostMemberOfAllLabels` once per extension in a loop, issuing a separate DB query for each. This PR replaces the N queries with a single batch query via a new `HostMembershipForLabels` datastore method that returns which labels (from a given list) the host belongs to. Extension filtering then happens in-memory. ### Changes - **New datastore method** `HostMembershipForLabels(ctx, hostID, labelNames) -> map[string]bool` -- single `SELECT l.name FROM labels l JOIN label_membership` query - **Updated `filterExtensionsForHost`** in `server/service/orbit.go` -- collects all unique label names across extensions, calls the new method once, filters in-memory - **No API, UI, CLI, agent, or schema changes** -- purely server-side internal optimization. Full backward compatibility: old agents work with new servers and vice versa (no protocol change). ## Benchmark Ran a local end-to-end benchmark against the live `POST /api/fleet/orbit/config` endpoint to measure the real-world impact. **Setup:** - MacBook (Fleet server + Docker MySQL 8.0 + Redis, all localhost) - 50 enrolled Orbit hosts (darwin), 5 label-scoped extensions, all hosts members of all 5 labels - 500 requests at concurrency 10, cycling through all 50 orbit_node_keys - Built Fleet binary from `main` (before) and this PR branch (after), same database and test data **Results:** | Metric | Before (main) | After (this PR) | Improvement | |--------|:---:|:---:|:---:| | Avg latency | 25.33 ms | 17.46 ms | **-31%, 1.45x faster** | | P50 latency | 24.55 ms | 16.52 ms | **-33%, 1.49x faster** | | P95 latency | 34.42 ms | 27.53 ms | **-20%, 1.25x faster** | | Throughput | 390.6 req/s | 564.2 req/s | **+44%** | ### Extrapolation to 100,000 hosts At 100k hosts with a 30-second check-in interval (3,333 req/s steady state): | Metric | Before | After | |--------|--------|-------| | Server host capacity (measured MacBook) | 11,718 | 16,926 (+44%) | | Label-check DB queries/sec | **16,665** (5/req) | **3,333** (1/req) | | **DB queries eliminated** | | **13,332/sec (80% reduction)** | The improvement scales linearly with extension count: | Extensions | DB queries eliminated/sec | Reduction | |:---:|---:|:---:| | 5 | 13,332 | 80% | | 10 | 29,997 | 90% | | 15 | 46,662 | 93% | | 20 | 63,327 | 95% | > **Note:** These are conservative localhost numbers. In production, where each DB round-trip includes real network latency, the per-request latency improvement would be more pronounced because each eliminated query saves a network hop. ## 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) ### Automated - New `testHostMembershipForLabels` MySQL integration test covering: empty input, full membership, partial membership, nonexistent labels, nonexistent host, host with no memberships - Existing `testHostMemberOfAllLabels` unchanged and unaffected ### Manual QA 1. Fleet Premium instance with 2+ Orbit-enrolled hosts 2. Configure 3+ osquery extensions with different label scoping 3. Verify each host receives only the extensions whose label requirements it meets 4. Verify extensions with no label scoping are included for all hosts <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Performance** * Improved Orbit configuration loading by batching host label membership checks into a single query for extension label filtering. * **Behavior** * Extension availability and filtering behavior remains the same, with more efficient processing when multiple extensions use labels. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f29ecfa09b | Fleet: Pin installer download token to a specific package (#49239) (#49263) | ||
|
|
d131518ba7 |
Fix mismatched package upload creating a new title instead of erroring (#49264)
**Related issue:** Resolves #49209 Adding a package to an existing software title (`POST /software/package` with `software_title_id`) now validates that the uploaded installer actually belongs to that title. Previously the `software_title_id` sent by the title page's "Add package" flow was ignored, so uploading mismatched software (e.g. a 1Password package onto a Zoom title) silently created a new separate title instead of erroring. It now returns a 400 with a clear message and writes nothing. When `software_title_id` is omitted (general "Add software" flow, GitOps), behavior is unchanged. # 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 |
||
|
|
82db4d5389 |
macOS & iOS/iPadOS: Rename hosts
Resolves #38806 Add an IT-admin naming convention for macOS/iOS/iPadOS hosts. An admin sets a name template (e.g. "iPad $FLEET_VAR_HOST_HARDWARE_SERIAL") under Controls > OS settings > Host names for a fleet or for "No team"; Fleet resolves it per host, delivers it via an Apple `Settings`/`DeviceName` MDM command, renames its own record on ACK, then verifies the name via osquery (macOS) or a DeviceInformation refetch (iOS/iPadOS). Clearing the template stops enforcement without renaming any host. Fleet Premium only, mirroring disk encryption. |
||
|
|
1318b3c017 |
Android certificates resend generate resent_certificate (#49249)
This `resent_certificate` activity is generated from the edit user flow in fleet server. **Related issue:** Resolves #49007 ## 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** * Device-to-identity-provider mapping changes can now generate certificate resend activities when applicable. * Certificate resend activities can now be marked as automated versus manual. * **Improvements** * Certificate resend details are produced when SCIM host-user mappings are added, updated, or removed. * If creating the associated resend activities fails, the mapping change still proceeds; errors are handled non-blockingly. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5e2b76a3ad |
Rename setup_experience_platforms to singular comma-separated setup_experience_platform (#49245)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** #43667 # Summary Renames the unreleased GitOps field `setup_experience_platforms` to singular `setup_experience_platform`, accepting a comma-separated string of `darwin`/`linux` (rejecting the `macos` alias) to match the query/policy/label `platform` convention. # Checklist for submitter - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] Added/updated automated tests - [ ] QA'd all new/changed functionality manually ## New Fleet configuration settings - [ ] Verified that the setting is exported via `fleetctl generate-gitops` - [ ] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [ ] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Updated software setup-experience platform configuration to use a single comma-separated `setup_experience_platform` value. * Platform values are normalized for casing and whitespace, deduplicated, and validated against supported platforms. * macOS setup selections now use the canonical `darwin` value; the `macos` alias is rejected. * GitOps-generated configurations now use the updated field name and platform format. * **Bug Fixes** * Improved validation messages for invalid setup-experience platform values. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3b329e49e7 |
Android certificates resent_certificate (#49171)
**Related issue:** Resolves #49007 # Checklist for submitter - [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** * SCIM user create/reactivation, replace, patch, and delete flows now automatically record certificate resend activities when applicable. * Certificate resend activities are generated alongside SCIM persistence, tied to the resulting “resent certificates”. * **Bug Fixes** * Improved reliability and synchronization of certificate resend activity recording during SCIM and Google Workspace reconciliation. * Failures to record individual resend activities no longer block the underlying SCIM operation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
74b10d8a0d |
Cache pack config JSON per team to reduce redundant marshaling (#48702)
**Related issue:** #21847 ## Summary `GetClientConfig` is called by every host every ~60 seconds. It rebuilds the full pack config (all scheduled query SQL text) from DB and JSON-marshals it on every request. For all hosts in the same team, the result is identical, yet we run 3-5 DB queries + `json.Marshal` of ~50KB per request. This PR adds an in-memory cache for the marshaled pack config JSON, keyed by `(teamID, queryReportsDisabled)` with a 1-minute TTL. The cache is invalidated when queries or AppConfig are modified. ### What changed - Extracted pack config building from `GetClientConfig` into a new `getPackConfig` method - Added `packConfigCache` field to Service struct using `go-cache` (1-minute TTL, 5-minute cleanup) - On cache hit (no legacy packs): returns cached `json.RawMessage` immediately, skipping all DB queries and JSON marshaling - On cache miss: builds pack config from DB, marshals, caches, and returns - Cache is flushed on any query mutation (`NewQuery`, `ModifyQuery`, `DeleteQuery`, `DeleteQueries`, `ApplyQuerySpecs`, `DeleteQueryByID`) and on `ModifyAppConfig` ### Expected impact at 100K hosts | Metric | Before | After | |--------|--------|-------| | Pack config marshals/second | ~1,667 | ~1 per minute per team | | DB queries for scheduled queries/second | ~5,000 | ~5 per minute per team | | CPU from JSON encoding | Dominant in pprof | Negligible | ### Known limitation `ListScheduledQueriesForAgents` supports label-scoped query filtering per host. The cache is keyed by team (not host), so when label-scoped scheduled queries exist, all hosts in a team receive the same query set from the cache regardless of their label memberships. This is an acceptable trade-off because: - Label-scoped scheduled queries are uncommon in most deployments - The cache TTL is 1 minute, so divergence is temporary - Running an extra query on a host is not harmful (just unnecessary work) - This can be refined in a follow-up to filter label-scoped queries from the cached result ## Testing ### Unit tests (9 tests, all pass) | Test | What it verifies | |------|-----------------| | `TestPackConfigCacheHit` | Second `GetClientConfig` call triggers zero DB calls for scheduled queries | | `TestPackConfigCacheInvalidationOnQueryCreate` | After `InvalidatePackConfigCache()`, new query appears in config | | `TestPackConfigCacheInvalidationOnQueryModify` | After invalidation, updated SQL is reflected in config | | `TestPackConfigCacheInvalidationOnQueryDelete` | After invalidation with empty query list, packs key is absent | | `TestPackConfigCacheInvalidationOnApplyQuerySpecs` | After invalidation simulating GitOps apply, new specs appear | | `TestPackConfigCacheTTLExpiration` | After 50ms TTL expires, fresh DB read occurs and new query appears | | `TestPackConfigCacheTeamIsolation` | Global, team-1, team-2 hosts get correctly isolated cached configs | | `TestPackConfigCacheLegacyPacksBypass` | Host with legacy pack triggers DB calls on every request (no caching) | | `TestPackConfigCachePerformance` | 1000 cached calls: 0 DB calls. 1000 uncached: 1000 DB calls. ~1.4x speedup with mock (real DB would be much larger) | ``` === RUN TestPackConfigCacheHit --- PASS (0.01s) === RUN TestPackConfigCacheInvalidationOnQueryCreate --- PASS (0.01s) === RUN TestPackConfigCacheInvalidationOnQueryModify --- PASS (0.01s) === RUN TestPackConfigCacheInvalidationOnQueryDelete --- PASS (0.01s) === RUN TestPackConfigCacheInvalidationOnApplyQuerySpecs --- PASS (0.01s) === RUN TestPackConfigCacheTTLExpiration --- PASS (0.11s) === RUN TestPackConfigCacheTeamIsolation --- PASS (0.01s) === RUN TestPackConfigCacheLegacyPacksBypass --- PASS (0.01s) === RUN TestPackConfigCachePerformance --- PASS (0.02s) Performance: cached=2.37ms, uncached=3.42ms, speedup=1.4x ``` Note: The 1.4x speedup is with mock datastore (no real DB/network). With real MySQL over network, the speedup would be orders of magnitude larger since cached calls skip 3-5 DB round-trips + ~50KB JSON marshal entirely. # 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) ## 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: Load test verification To validate the real-world impact, QA should run a load test before and after this change and compare: 1. Capture a CPU pprof profile **before** the change under load (e.g., 10K+ simulated hosts, 50+ scheduled queries) 2. Deploy the change and capture a **second** pprof profile under the same load 3. Compare the flamegraphs -- the `encoding/json.Marshal` and `GetClientConfig` CPU time should drop significantly 4. Monitor Fleet container CPU utilization -- expect a measurable reduction in steady-state CPU See #21847 for the original pprof showing `encoding/json` dominating CPU at scale. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved host config response performance by caching pack configuration data. * Query changes now automatically refresh cached host config so updates appear promptly. * **Bug Fixes** * Host configs now stay accurate after creating, updating, deleting, or applying queries. * Cached data is isolated correctly and falls back to fresh data when legacy packs are present. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
53c0ca8dda |
Use generated UUID for mdm_idp_account table on Linux and Windows (#49215)
Resolves #47626. - [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 - **Bug Fixes** - Fixed Fleet re-enrollment on Linux for end-user authentication SSO when the re-enrollment email differs from the original enrollment email. - Re-enrollment now remaps the device to the correct SSO account, with no SSO callback/login errors, and does not reuse the prior account UUID. - **Tests** - Added a regression test covering re-enrollment with the same device host UUID but a different IdP user/email, validating email updates and account UUID change. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c5575e9d9a |
Add PSSO end to end integration tests (#48589)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47171 Added integration tests for the fleet-psso feature and added PSSO functionality to our MDM test client - idea being it is so tightly integrated into the MDM side of things on the Apple side AND we ideall want osquery-perf to be able to exercise it(coming in the next PR) # 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] 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 Apple Platform SSO (PSSO) support for device registration, password login, key requests, and key exchange. * Added a simulator/test device for exercising the full PSSO workflow end-to-end. * Made PSSO AASA development app IDs configurable and enhanced macOS PSSO activity in performance testing (with new counters). * Improved local macOS Desktop packaging/signing configurability. * **Bug Fixes** * Strengthened PSSO token/crypto handling, including algorithm pinning, key ID canonicalization, encrypted assertion `typ` validation, and replay protection. * **Tests** * Added extensive crypto interoperability tests (including Apple known-answer vectors) plus new end-to-end integration coverage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Magnus Jensen <magnus@fleetdm.com> |
||
|
|
06863c4b37 |
Merge remote-tracking branch 'origin/main' into feat/28108-multiple-custom-packages
# Conflicts: # frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/LibraryItemAccordion/LibraryItemAccordion.tsx # frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx # pkg/spec/gitops.go # server/datastore/mysql/schema.sql # server/fleet/software_installer.go |
||
|
|
078fbc0f40 |
Add Targeted platforms column and platform filter to Policies page (#44125)
- @noahtalerman: For the following quick win: - https://github.com/fleetdm/fleet/issues/23737 ## Summary Adds a "Targeted platforms" column and a platform filter dropdown to the Policies page (`/policies/manage`), matching the pattern already used on the Reports page (`/queries/manage`, `ManageQueriesPage`). ### Frontend - New non-sortable **Targeted platforms** column rendered via `PlatformCell`, sourced from each policy's comma-separated `platform` field. - New platform filter dropdown (All / macOS / Windows / Linux / ChromeOS) wired as a `customControl` on the Policies table, alongside the existing automation filter. Selecting a value pushes a new URL (not a replace), resets `page` to 0, and updates the `platform` query param. - `ManagePoliciesPage` reads `location.query.platform` and threads it through to both `globalPoliciesAPI.loadAll` / `teamPoliciesAPI.loadAll` and the react-query keys, plus the count endpoints. The automation-filter and count "hide" conditions now include the platform filter so they remain visible when only a platform filter is active. - `frontend/services/entities/global_policies.ts` and `team_policies.ts` accept an optional `platform` param (with `"all"` normalized to `undefined`). - Added tests for the new column and dropdown in `PoliciesTable.tests.tsx`. ### Backend - Added `Platform string ` + `` `query:"platform,optional"` `` to `ListGlobalPoliciesRequest`, `CountGlobalPoliciesRequest`, `ListTeamPoliciesRequest`, `CountTeamPoliciesRequest`. - Extended datastore and service signatures (`ListGlobalPolicies`, `ListTeamPolicies`, `ListMergedTeamPolicies`, `CountPolicies`, `CountMergedTeamPolicies`, `ListGlobalPolicies`/`ListTeamPolicies` on the service) to accept a `platform string` arg. Mocks and all call sites updated. - Platform filtering in SQL uses a new helper `platformFilterClause`: ```sql AND (p.platforms = '' OR FIND_IN_SET(?, p.platforms)) ``` so policies targeting "all platforms" (empty `platforms` field) always match regardless of the selected filter. `FIND_IN_SET` uses a bound parameter (no injection risk). - Added a new MySQL integration test `testPoliciesPlatformFilter` covering empty-platform (match-all), per-platform filter, and team/merged paths. ### Docs - REST API docs for `GET /api/v1/fleet/global/policies`, `GET /api/v1/fleet/fleets/:id/policies`, and the corresponding `/count` endpoints now document the `platform` query param. - Added `changes/policies-targeted-platforms-filter`. ## Behavior - `platform=all` (or missing) returns all policies. - Selecting a specific platform returns policies whose `platforms` column is empty OR contains the selected token. - The dropdown only renders when the table is searchable (results exist OR any filter is active). - Changing the filter pushes a new URL and resets the page. # 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] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually Local verification: - `go build ./...` — clean - `go vet ./server/... ./cmd/... ./ee/...` — clean - `make lint-go-incremental` — 0 issues - Go service-level policy tests pass. MySQL integration tests compile but could not be run locally (no Docker); CI will exercise the new `testPoliciesPlatformFilter` test. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a "Targeted platforms" column with platform icons and an "All platforms" option. * Added a platform filter dropdown to scope policy lists; counts, last-updated, and controls adapt when a platform filter is active. Backend now honors an optional platform query parameter so filtering returns matching policies. * **Tests** * Added and updated unit and integration tests covering the new column, filter UI, and platform-filtered policy listings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: nulmete <nicoulmete1@gmail.com> |
||
|
|
2c9fa3767e | Fleet UI: Multi-package secondary UI — policy automation, setup experience, install-details hash (#49079) | ||
|
|
6cfc4a3611 |
Add GitOps support for macOS script-only packages in setup experience (#49089)
**Related issue:** Resolves #43667 # Summary Adds a `setup_experience_platforms` field to the GitOps software package spec so `.sh` script-only installers can be selected for macOS setup experience declaratively. Reconciles the cross-platform selection table on every batch apply. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## New Fleet configuration settings - [x] Verified that the setting is exported via `fleetctl generate-gitops` - [x] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [x] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added declarative `setup_experience_platforms` to software package definitions to control “setup experience” targets, including selecting script-only installers for macOS (mapped appropriately). * Batch uploads now propagate these cross-platform selections and reconcile installer cross-entries. * **Bug Fixes** * Improved platform normalization (trimming, casing, alias mapping), deduplication, and extension-specific validation. * Enhanced update behavior: omitting the field leaves existing selections unchanged; providing an empty list clears them, with correct setup/installation timing. * **Tests** * Added unit and integration coverage for normalization and batch re-apply/reconcile behavior (nil vs empty, idempotency, mixed updates, and validation failures). <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
790f457bf0 |
SAAD: GitOps for DDM assets (#49046)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48570 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. Added in a previous PR - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added end-to-end Apple DDM asset support in GitOps, including export and GitOps parsing for `macOS settings` assets. * Introduced Apple DDM asset management APIs (list/get/download/create/delete) plus a batch set operation with dry-run. * **Bug Fixes** * Improved Apple MDM/DDM reconciliation so referenced asset updates trigger re-delivery via asset-aware tokening. * Added safer validation around asset type changes and deletion conflicts when assets are still referenced. * **Tests** * Expanded unit and integration coverage for asset parsing, upload/apply behavior, reconciliation, and access control. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
307f9b3108 |
Add hash_sha256 field to host installer result and install software activity (#49085)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # - Adds hash_sha256 field to host installer result and install software activity so they can be used in combination to cover past activities with existing installers + all new activities even if their installer will get deleted # Checklist for submitter ## 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 * **New Features** * Software installation results now include the installer’s SHA-256 hash when available. * Installed-software activity records now include the corresponding `hash_sha256` value. * **Bug Fixes** * Hash values are retained in activity history after an installer is deleted, while live results correctly show the value as unavailable. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b4ce88645b |
SAAD: Support DDM assets in sync + reconciliation (#49016)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48568 second part # 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 ## Summary by CodeRabbit * **New Features** * Apple declarative management now supports asset-backed declarations, including device delivery of referenced DDM assets. * Added a new device-facing endpoint to fetch managed DDM assets by identifier (scoped to the device’s team). * **Bug Fixes** * Declaration/profile updates now refresh when referenced assets change (not just variables). * Device and host token/declaration matching now accounts for asset update timing to trigger redeploys reliably. * Improved validation to detect missing/invalid asset references before saving. * **Other** * Updated which configuration declaration types are blocked during user-provided validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5727de3b3a |
Android config profiles resend on IdP changes (#49068)
**Related issue:** Resolves #49003 ## 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** * Android configuration profiles now detect and track Fleet secret/template variables during creation, including when profiles are created or updated in batches. * **Bug Fixes** * When Fleet variables related to SCIM user identity change, affected Android MDM profile resend/delivery state is reset so the updated profile is re-delivered. * Android profile behavior has been aligned across creation, listing, and delete/upsert flows to maintain consistent variable-aware associations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a33481653d |
macos password sync feature branch (#47422)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45524 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [ ] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [ ] Setting(s) is/are explicitly excluded from GitOps If you didn't check the box above, follow this checklist for GitOps-enabled settings: - [x] Verified that the setting is exported via `fleetctl generate-gitops` - [x] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [x] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Apple Platform SSO (PSSO) for macOS with device registration, sign-in, and public discovery (JWKS + Apple app-site association) protected by single-use nonces. * Added Apple account provisioning (Platform SSO password sync) configuration with masked client-secret handling and GitOps support. * Added a host-scoped PSSO device registration token variable for Apple MDM profile generation. * **Bug Fixes** * Fixed macOS packaging to correctly build, embed, and sign the Platform SSO extension. * Resetting device Apple MDM data now also clears stored PSSO enrollment records. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Magnus Jensen <magnus@fleetdm.com> |
||
|
|
4f8677de3c |
Fix fleet_maintained_app_slug being allowed in a dynamic policy (#49034)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # Changes: - Adds an explicit error message when `fleet_maintained_app_slug` is set for a dynamic policy in a gitops file (fleetctl gitops client) - Adds the same error message if it's done through the API only - Checks if policy type == patch in case `install_software: true` is set to prevent an irrelevant "[!] fleet-maintained app slug without software title ID:" warning # 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** * Tightened policy validation so `fleet_maintained_app_slug` is only accepted for patch policies. * Dynamic or unspecified policy types now return a clear validation error when this field is set. * Improved GitOps policy handling so software details are only applied in supported cases. * **Tests** * Added coverage for accepted and rejected policy combinations involving `fleet_maintained_app_slug`. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a15d58e927 |
SAAD: Asset CRUD API (#49011)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48568 partly # 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. (Will add in followup) - [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 Apple DDM asset management endpoints: list, get, download (raw JSON), create, and delete. * Implemented datastore-backed Apple DDM asset CRUD with team-scoped and global access, plus configurable upload size limits. * Added strict asset JSON validation (including required fields, URI checks, and secret expansion rules). * **Bug Fixes** * Improved authorization handling by returning not-found responses for out-of-scope read/download/delete to avoid asset discovery. * Added clearer conflict and linked-profile error mapping for create/delete failures. * **Tests** * Added comprehensive authorization and validation test coverage for Apple DDM assets and policy behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
56a3c75155 | Fix macOS software titles mis-named from embedded helper bundles (#44199) (#47831) | ||
|
|
e1094096af |
Surface proxied Windows SCEP certificate failures (#45550) (#48842)
Windows configuration profiles that Fleet proxies SCEP for previously reported "verified" as soon as the device acknowledged the SyncML Exec command, even when the asynchronous SCEP exchange later failed and no certificate was ever issued. - Proxied SCEP profiles (custom SCEP proxy, NDES) now move to "verifying" on the device ACK and only reach "verified" once Fleet observes the matching certificate on the host, keyed by the renewal-ID marker (fleet-<profile_uuid>) in the certificate CN/OU. - When Fleet's SCEP proxy observes an upstream CA error during PKIOperation, it marks the profile "failed" with a detail naming the operation and upstream status. If the device's own retry later succeeds, the observed certificate flips the profile to "verified". - Unconfirmed profiles stay "verifying" (offline host, agent that cannot enumerate certificates, empty store, or a user-scoped profile before the user logs in); absence is never treated as failure. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45550 Demo: https://www.youtube.com/watch?v=WNGuFdeBmzA Docs: https://github.com/fleetdm/fleet/pull/48933/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] 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Added Windows SCEP failure tracking with clearer, categorized detail when upstream operations fail. * Added reconciliation backstops for “stuck” proxied SCEP profiles, including automatic recovery to verified when the expected certificate is observed. * **Bug Fixes** * Prevented proxied Windows SCEP installs from being marked “verified” until matching certificate evidence arrives. * Improved classification and persistence behavior for timeouts, connection/DNS issues, and HTTP error responses without disturbing existing retry state. * **Tests** * Expanded Windows SCEP scenarios to cover reconciliation, skipping conditions, and error classification. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6d1938b914 |
Fix test setting flag that caused further tests to fail (#48947)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # Moves `TestInstallAllSelfServiceSoftware` from the enterprise integration suite (`TestIntegrationsEnterprise`) to the MDM integration suite (`TestIntegrationsMDM`), because setting the `MDM.EnabledAndConfigured` flag in the enterprise suite was leaking into and failing other tests (`TestLinuxDiskEncryption`, `TestTeamEndpoints`, `TestTeamSpecs`, `TestMDMNotConfiguredEndpoints`, `TestVPPAppsWithoutMDM`, `TestOrbitSetupExperienceStatusChecksAuthBeforeMDM`). # Checklist for submitter ## 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 - checking this to avoid a CI failure, but there is nothing to actually manually check <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Expanded integration coverage for self-service software installs across team, label, category, and multi-host scenarios. * Added checks for install ordering, idempotency, queue consistency, and concurrent requests. * Included coverage for VPP-backed apps and mixed install queues to better validate real-world behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
003ab766d3 |
Filter cross-team memberships from user list responses (#48890)
From Lucas:
- [X] QA'd all new/changed functionality manually
## Summary
A team-scoped admin listing users of a team they administer (`GET
/api/latest/fleet/users?team_id=A`) received the full team membership —
team IDs, names, and roles — of any user also shared with other teams,
disclosing teams the requester has no role in.
The single-user `GET /users/{id}` endpoint already blocks this: its
authorization requires the requester to administer *every* team the
target belongs to. The list endpoint authorizes against a synthetic
single-team object (correct, so team admins can manage their members),
but then returned each user's complete team list as loaded by the
datastore.
This filters each returned user's teams down to the requester's scope at
the response layer. Requesters with any global role are unchanged
(they're authorized to see all teams).
## Why the response layer, not `Service.User`
`ModifyUser` and the password-reset flow reuse `Service.User` and read
`user.Teams` to compute write diffs. Filtering there would silently drop
team memberships on edits, so the filter is applied in
`listUsersEndpoint` only.
`GET /users/{id}` is intentionally not changed — it is not exploitable
(authz already requires admin-of-all-the-target's-teams), and its
legitimate readers should keep seeing the full team list.
## Testing
- `TestListUsersFiltersTeamsToRequesterScope` — team-1 admin listing
team 1 sees only team 1 for a user shared with {1,2}.
- `TestListUsersGlobalRequesterSeesAllTeams` — global admin sees all
teams.
- Existing `TestUserAuth` / `TestAuthorizeUser` pass unchanged (no authz
regression).
Fixes fleetdm/confidential#16691
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed user listing so returned team membership details are scoped to
the requesting user’s permissions, including fleet-scoped context.
* Team-scoped requesters now only see memberships for teams they’re
allowed to view; global-role requesters still see all memberships.
* When scoped viewer context is missing, team membership details are no
longer included in the response.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
|
||
|
|
19aac451e1 |
Fix Windows CSP bypass issue (#48843)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48752 Stacked PR. Needs 48349-windows-modify branch to merge first. # 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 a Windows MDM loophole where scope-less or differently formatted `LocURI` values could bypass Fleet restrictions. * Strengthened detection and enforcement for reserved Windows targets, including OS updates, remote wipe premium gating, and BitLocker restrictions. * Improved `LocURI` handling to be resilient to whitespace and alternate formatting, including more consistent SCEP profile processing. * **Tests** * Added regression coverage for reserved `LocURI` matching, OS-update targeting, and premium detection for wipe commands (including scope-less cases). <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4351f4cee5 |
escrow snapd TPM-backed FDE recovery keys from orbit (#48452)
**Related issue:** Resolves #44428 |
||
|
|
dfe0f1c871 |
Fix App Store picker 403 for non-admin roles (#48856)
**Related issue:** Resolves #46057 Authorize `GetVPPTokens` against `VPPApp` instead of admin-only `AppleCSR`, so maintainer/technician roles no longer get a 403 that broke the App Store picker. # Checklist for submitter - [x] Changes file added for user-visible changes in `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 the “Add software > App Store” picker so maintainer and technician roles no longer encounter access errors when browsing VPP tokens. * Improved VPP token visibility for team-scoped users by restricting listings to teams they can read, while including “all teams” tokens and excluding unassigned/unauthorized ones. * Ensured users without appropriate access receive the correct authorization response instead of broader token listings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4c79d6bddd |
Add user-scoped declaration support (#48796)
<!-- 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 * **New Features** * Added support for Apple declarative management declarations on both System and User channels. * User-scoped declarations are now delivered, reconciled, and acknowledged independently from device-scoped declarations. * **Bug Fixes** * Prevented scope-mixing so declaration items and status updates no longer affect the wrong channel. * Tightened reconciliation behavior for scope changes and missing user channels. * **Tests** * Expanded coverage for channel isolation, payload scope parsing/validation, and correct delivery payload behavior (including stripping the payload-scope field from delivered JSON). <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8f3624cf0a |
Fixed Windows profile modify batch (#48474)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48349, as well as a few other minor issues found during dev (such as canonical LocURI, ensuring we delete the CSP version actually on the device, etc.). Load tested the fix. # 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] 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] 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** * Windows profile edits and deletions now handle large environments more reliably, with faster processing and no size-based timeouts. * Removed profile content is now cleaned up asynchronously, improving the responsiveness of profile changes. * **Bug Fixes** * Fixed Windows profile edits so removed settings are deleted correctly even when profiles are updated instead of fully removed. * Improved matching for Windows configuration targets, making cleanup more consistent across profile versions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
724835658a |
Follow-up fix for FMA counts (#48818)
**Related issue:** Resolves #48528 Follow-up to #48783, which changed the Fleet-maintained apps "items" count from per-platform entries to per-app, dropping it from 1,263 to 1,023. This restores the count to `COUNT(DISTINCT fma.id)`: macOS and Windows entries are separately installable (each its own Add button), so each counts (1,263 / 960 macOS / 303 Windows). The token-based row-combining and pagination from #48783 are kept. # 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 * **Bug Fixes** * Corrected available-app counts in listings so pagination totals now match what users can actually add. * Improved pagination consistency for apps with multiple platform variants, reducing confusion where totals did not align with visible entries. * Updated team-based filtering so already-added apps are excluded more accurately from available results. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |