Commit Graph
4576 Commits
Author SHA1 Message Date
Nico bfb0f297db Fix Policies automations filter disappearing for the Unassigned fleet (#49224)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44624

Switching to the "Unassigned" fleet with an automation filter already
set kept the filter's value in the URL, but the filter dropdown's option
list silently collapsed to only "All automations" and "Webhooks or
tickets" — the same restricted set used for "All fleets" — because the
"Unassigned" fleet's team ID (0) is falsy and was treated the same as
the undefined team ID used for "All fleets". This made the filter appear
to disappear from the UI.

# 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 (issue's video)



https://github.com/user-attachments/assets/a2bca626-5700-4174-beb2-94aadf847a6c



#### After



https://github.com/user-attachments/assets/a5912056-02ef-4827-8110-29ad4d629fa8




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed the automations filter on the Policies page so it remains
visible when viewing the Unassigned fleet.
  * Preserved the selected automation filter when switching views.
* Updated available options for Unassigned fleets by excluding Calendar
while retaining supported automation types.
* Improved the empty-state experience when no policies match the
selected filters.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 15:58:53 -03:00
Sharon KatzandClaude Opus 4.6 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>
2026-07-13 13:51:02 -04:00
Lucas Manuel Rodriguez 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 -->
2026-07-13 14:43:39 -03:00
Dante Catalfamo 93fa75ec45 Update Windows 10 CIS benchmark policies to v4.0.0 (#48986)
**Related issue:** Resolves
2026-07-13 12:52:38 -04:00
Rahul Raghunathan 9f8caea025 Fix tables losing row selection on window focus (#48742)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48542

## Description

The `QueryClient` was created with `new QueryClient()` and no default
options, so every query inherited React Query's default
`refetchOnWindowFocus: true`. On pages like `/policies` and `/users`,
queries are refetched every time the browser window regains focus. Those
focus refetches re-rendered the table with fresh data, tripping
react-table's `autoResetSelectedRows` and `autoResetPage` (both default
`true`), so the table appeared to "reload," clearing the user's row
selection and jumping back to the first page when they clicked away and
back.


## Screen recording demonstrating the fix


https://github.com/user-attachments/assets/eabf30a5-65d3-420d-a8d3-5a529fa06089


# 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] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Prevented users and policies tables from unexpectedly reloading when
switching back to the browser window.
* Preserved table state such as selected rows and current pagination
instead of resetting to the first page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 13:10:33 -03:00
Marko Lisica fb3932f37a Update CustomLink styles (#48838)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #35328

# 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

* **Bug Fixes**
* Improved link hover and `:focus-visible` underline/outline behavior
for more consistent accessibility across tables, buttons, and modals.
  * Fixed script name hover underline clipping in the run script modal.
* **Style**
* Refreshed `CustomLink` styling with an emphasized variant and improved
underline behavior, plus updated related link/table/button styling for a
unified look.
* Updated “Connect Fleet” info-banner messaging and CTAs for calendar
and conditional access automations; refreshed “No scripts available”
empty state.
* **Tests**
  * Updated modal tests to match revised link text and accessible names.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 17:07:39 +02:00
Josh Roskos 9539535321 Supress install all for all/undefined software category (#48999)
**Related issue:** Resolves #49013

# 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

* **Bug Fixes**
* Hid the **Install all** button on the unfiltered **All** software
view.
  * Kept **Install all** available when a specific category is selected.
* Updated install-all behavior so the correct category is used when
launching installs.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 10:51:12 -04:00
Allen Houchins 29bef37837 Add macOS app filter to My device software (#48637)
Expose the existing "Applications" / "Full inventory" software filter on
the Fleet Desktop My device Software tab for macOS hosts. The filter now
defaults to Applications for macOS, sends `macos_applications` to the
device software API, and keeps that query param during pagination.
Updated table tests cover rendering and URL behavior on My device and
non-macOS hosts.

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48636

# 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

- [ ] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [ ] QA'd all new/changed functionality manually

For unreleased bug fixes in a release candidate, one of:

- [ ] Confirmed that the fix is not expected to adversely impact load
test results
- [ ] Alerted the release DRI if additional load testing is needed

## Database migrations

- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).

## New Fleet configuration settings

- [ ] Setting(s) is/are explicitly excluded from GitOps

If you didn't check the box above, follow this checklist for
GitOps-enabled settings:

- [ ] Verified that the setting is exported via `fleetctl
generate-gitops`
- [ ] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [ ] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled

## fleetd/orbit/Fleet Desktop

- [ ] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [ ] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [ ] Verified that fleetd runs on macOS, Linux and Windows
- [ ] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added the **Applications / Full inventory** software filter to the
**My device > Software** tab for macOS devices.
* The selected filter is now preserved when navigating through software
results.

* **Bug Fixes**
* Corrected software filtering behavior across device pages and
platforms.
* Prevented the macOS filter parameter from being added for non-macOS
devices.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 09:08:26 -05:00
Sharon KatzandClaude Opus 4.6 a1531e6752 Fix CPE matching for python3-prefixed packages on Ubuntu/Debian (#48599)
Closes #43328

## Summary

- On Ubuntu/Debian/RHEL, `pythonPackageFilter` in osquery.go prepends
`python3-` to Python package names (e.g., `geopandas` becomes
`python3-geopandas`) to match OVAL definitions
- However, the CPE database uses the bare package name (e.g.,
`geopandas`, not `python3-geopandas`), so CPE matching fails and no
vulnerabilities are reported
- This fix adds the stripped name (without `python3-` prefix) as an
additional product variation during CPE lookup, so both
`python3-geopandas` and `geopandas` are tried
- The original prefixed name is preserved so packages genuinely named
`python3-*` on PyPI (e.g., `python3-openid`, `python3-saml`) still match
correctly on non-Ubuntu platforms

## How I reproduced

Used the `nvdvuln` tool to simulate CPE matching:

**Before fix** (on main branch):
```
$ go run --tags=fts5 tools/nvd/nvdvuln/nvdvuln.go \
    --software_name python3-geopandas \
    --software_source python_packages \
    --software_version 1.0.1
Translating software to CPE...
Unable to match a CPE for the software...
```

**After fix:**
```
$ go run --tags=fts5 tools/nvd/nvdvuln/nvdvuln.go \
    --software_name python3-geopandas \
    --software_source python_packages \
    --software_version 1.0.1
Translating software to CPE...
Matched CPE: 0: cpe:2.3:a:geopandas:geopandas:1.0.1:*:*:*:*:python:*:*
Translating CPEs to CVEs...
CVEs found for python3-geopandas (1.0.1): CVE-2025-69662
```

Also verified with `python3-django` (version 3.2.12) -- correctly finds
CVE-2024-24680 and other CVEs.

## How I tested

- Unit tests: added test cases for `productVariations` covering:
- `python3-geopandas` (source: `python_packages`) -> produces both
`python3-geopandas` and `geopandas` variations
- `python3-django` (source: `python_packages`) -> produces both
`python3-django` and `django` variations
- `requests` (source: `python_packages`, no prefix) -> no extra
variations added
- Manual: ran `nvdvuln` tool for both packages from the issue, confirmed
CPE match and CVE detection
- Lint: `make lint-go-incremental` passes clean


🤖 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**
* Improved vulnerability detection for Python packages on Ubuntu/Debian
by handling package names with or without the `python3-` prefix.
* Added additional matching variations derived from sanitized names,
ensuring both full and stripped forms are considered.
* Ensured existing non-Python package matching behavior remains
unchanged.
* **Tests**
* Expanded NVD sanitization and product variation test coverage for
`python_packages` scenarios (including cases with and without the
`python3-` prefix).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-07-13 09:46:49 -04:00
+3 c9803c2a8f Docs: non-proxied cert renewal (#45695)
**Related issue:** Resolves #44348

**Base branch:** `docs-v4.86.0` (not `main`) per the docs release
process.

## What this PR does

Updates four customer-facing guides and adds a release-notes entry for
Phase 2's opt-in cert renewal feature (shipped via #45696). Frames the
marker as an opt-in enhancement: profiles without it continue to work as
in 4.85; profiles with it activate auto-renewal.

| Guide | Change |
|-------|--------|
| `connect-end-user-to-wifi-with-certificate.md` | Migrated 11 legacy
`\$FLEET_VAR_SCEP_RENEWAL_ID` refs to the preferred name; added
back-compat callout. |
| `okta-conditional-access-integration.md` | Removed "Automatic renewal
coming soon" line; added one-time upgrade-redeploy callout for existing
customers. |
| `enable-okta-verify-on-macOS-with-configuration-profile.md` | Added
marker to example profile OU; added opt-in note and CA-side
OU-preservation verification step. Coordinated with the earlier
example-profile update from #43293 already on `docs-v4.86.0`. |
| `enable-okta-verify-on-windows-using-a-scep-configuration-profile.md`
| Replaced manual-redeployment narrative with auto-renewal guidance.
Kept the policy-based expiry-monitoring SQL as an optional safeguard. |

Release-notes entry (`changes/40639-non-proxied-cert-renewal`)
consolidates Phase 2 customer-visible behavior in three bullets.

## Dependencies

The Conditional Access guide's "new setups: no extra action needed"
framing assumes #45662 (the Fleet-side template marker addition) has
landed — it has, merged into the feature branch and onward into main via
#45696.

# Checklist for submitter

- [x] Changes file added for user-visible changes

## Testing

- [x] Doc review only — no code changes

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Automatic certificate renewal is now supported for SCEP and ACME
certificates from external certificate authorities, enabled by default
for new deployments with an opt-in path for existing customers
* macOS devices with ACME-bearing configuration profiles will now
surface hardware-bound certificates in device vitals

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Rachael Shaw <r@rachael.wtf>
Co-authored-by: Marko Lisica <83164494+marko-lisica@users.noreply.github.com>
Co-authored-by: kilo-code-bot[bot] <240665456+kilo-code-bot[bot]@users.noreply.github.com>
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: melpike <79950145+melpike@users.noreply.github.com>
Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com>
Co-authored-by: Jordan Montgomery <elijah.jordan.montgomery@gmail.com>
Co-authored-by: Jonathan Katz <44128041+jkatz01@users.noreply.github.com>
Co-authored-by: Victor Lyuboslavsky <2685025+getvictor@users.noreply.github.com>
Co-authored-by: Magnus Jensen <magnus@fleetdm.com>
Co-authored-by: RachelElysia <71795832+RachelElysia@users.noreply.github.com>
Co-authored-by: Scott Gress <scottmgress@gmail.com>
2026-07-10 17:37:50 -05:00
Andrew MellorandJordan Montgomery 2eb1cba2dd 46959 Add Account Provisioning settings to UI for FPSSO configuration (#47655)
**Related issue:** Resolves #46959

# 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 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 account provisioning configuration UI in integrations
settings with token URL, client ID, and client secret fields.
  * Added activity tracking for Apple account provisioning changes.

* **Documentation**
* Renamed integration settings labels for clarity: "Ticketing",
"Calendar events", "Certificate enrollment", "User mapping",
"Authentication (SSO)", and "Host status alerts".

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Jordan Montgomery <elijah.jordan.montgomery@gmail.com>
2026-07-10 16:19:47 -04:00
Jordan Montgomery 91971a3637 Add better index to nano_enrollment_queue (#48865)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48883

# 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`).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Improved performance for retrieving the next Apple MDM command, making
queue lookups faster and more reliable.
* Added a new database index to better support ordering and selection of
pending commands.
* **Tests**
* Added coverage to verify the new indexing behavior is applied
correctly during database updates.
* **Chores**
* Updated database schema and migration records to include the new
index.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 15:51:14 -04:00
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>
2026-07-10 13:32:16 -05:00
Carlo 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 -->
2026-07-10 13:52:48 -04:00
Tim Lee 945a4d1518 Filter Add certificate CA dropdown to custom SCEP only (#49020) 2026-07-10 11:14:28 -06:00
Jonathan Katz aa5813e4eb Fix invisible hover state in dark mode (#49001)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48531

# 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

- [ ] 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
Checked all the places according to this list:
```
Rule 1 — modal secondary buttons (Cancel / Done / Clear all)
`body.dark-mode .modal__modal_container .button--inverse:hover, …`
Affects any modal opened from *inside a card* (the only modals where the card-leak made hover invisible). There are **4 such surfaces**, all reachable from the Dashboard or Self-service:

1. **Dashboard → the chart card (Hosts online / vulnerability exposure) → Settings cog → the Settings modal** — hover **Cancel** and **Clear all**. *(issue #48531)*
2. **Dashboard → Activity card → click any activity's details link** — the details modal's footer button (Done/Cancel). This is 12 different activity-detail modals (script details, software install/uninstall details, VPP install, MDM command, etc.).
3. **Dashboard on a fresh instance (fewer than 2 hosts) → "Welcome to Fleet" card → click a policy row** — the policy modal.
4. **Fleet Desktop "My device" → Self-service tab → "Install all" button** — the Install-all-in-category modal's Cancel.

## Rule 2 — button `DropdownWrapper` hover
`body.dark-mode .card .dropdown-wrapper__button .react-select__control:hover`
Exactly **1 place** in the whole app:

5. **Software → click a software title → title details page → the "Actions ▾" dropdown** at the top-right of the summary card. *(Admin/maintainer only — it's gated behind "can manage software".)*

## Rule 3 — `ActionsDropdown` hover
`body.dark-mode .card .actions-dropdown-select__control:hover`
Exactly **2 places**:

6. **Host details → Reports tab → each report card header → "Actions ▾"**. *(The confirmed repro.)*
7. **Fleet Desktop "My device" → Self-service tab → a software row → "More ▾"** dropdown.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed dark-mode hover styling for buttons and dropdowns inside card
components.
* Restored the correct hover appearance for inverse buttons in modal
containers.
* Updated hover behavior for select-style dropdown controls so they
match the card surface in dark mode.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 12:48:12 -04:00
Magnus Jensen 2b2a5991a4 handle client error decoding errors in ACME urls (#49137)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46282

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Malformed ACME URLs and resource identifiers now return a clear **400
Bad Request** response instead of a **500 Internal Server Error**.
* Error details were improved to more accurately distinguish malformed
client requests.
* **Tests**
* Added an integration test covering invalid ACME endpoint path IDs
across resource types, verifying **400** responses with the expected
malformed error type.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 12:31:17 -04:00
Sharon Katz 2f0c1b338a Restrict SCIM endpoints to global admin only (#48858)
**Related issue:** N/A

# 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

## Summary

Restricts SCIM endpoint access to global admin users only. Previously,
global maintainers also had access, which is broader than necessary.

### Changes
- **`server/authz/policy.rego`**: Removed `maintainer` from the SCIM
authorization rule, leaving only `admin`.
- **`ee/server/integrationtest/scim/scim_test.go`**: Updated auth tests
to verify maintainers now get 403, and that only admins can access SCIM
endpoints.

> **Breaking change for 4.89**: Customers using a global maintainer API
token for SCIM will need to update to a global admin token before
upgrading.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Restricted SCIM endpoint access to global administrators only.

* **Bug Fixes**
* Prevented unauthorized observer and maintainer users from accessing
SCIM reads, writes, and details.
* Improved authorization error tracking for denied SCIM requests
(including recorded request status and details).

* **Tests**
* Updated SCIM authorization integration tests to reflect the tightened
admin-only access rules.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 11:53:48 -04:00
Magnus Jensen 240ae88408 inconsistent font size tooltip (#49121)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48229

<img width="465" height="151" alt="image"
src="https://github.com/user-attachments/assets/af282c1a-af0d-4184-831d-cb7a98fc6bc8"
/>



# 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] 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 the “Require BitLocker PIN” tooltip could render
with an inconsistent font size.
* Kept the Windows instructions content the same while adjusting the
tooltip layout/line breaks for consistent display.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 15:46:42 +02:00
Magnus Jensen f5531fdf1b Tooltips not always showing for full name (IdP) (#49116)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48125

Side effect is that we will no longer show the "Connect IdP" tooltip.


https://github.com/user-attachments/assets/303836fb-a1c3-4d5e-9c2b-3fddd0dfb4d1


# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Resolved an issue in the device Details → Users area where tooltips
for a person’s full name and related IdP fields could fail to appear.
* Tooltips now render reliably and show the correct help text when
hovering the affected fields.

* **Tests**
* Expanded automated coverage to confirm tooltip visibility and the
displayed tooltip content for the user details card.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 15:42:39 +02:00
Magnus Jensen 05867fe955 Stop premium calls on Fleet free (#49118)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #47943

It no longer calls `ab_tokens` and `vpp_tokens` on fleet free
<img width="1317" height="561" alt="image"
src="https://github.com/user-attachments/assets/6556f91e-a7e4-487c-9961-3a22104329d3"
/>


# 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

- [ ] 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 Fleet Free accounts could trigger premium MDM
calls.
* Restricted premium token retrieval to eligible premium-tier accounts.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 15:42:15 +02:00
Magnus Jensen 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 -->
2026-07-10 14:47:23 +02:00
Tim Lee 9a24cb1d5d Fix long certificate name overflow in delete certificate modal (#48948) (#49019) 2026-07-10 06:40:30 -06:00
Andrew Mellor 4922289610 48917 Show a deleted state instead of a generic error for stale MDM command (#49012)
**Related issue:** Resolves #48917

# 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

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

## Summary by CodeRabbit

* **Bug Fixes**
* The MDM command details modal now shows **“This command has been
deleted.”** instead of a generic error when a command result is removed
after the host is wiped and re-enrolled.
* The modal now uses additional stored activity context (like host
display name and request type) to render more accurate, host-specific
details for deleted commands.

* **Tests**
* Updated and added coverage to confirm the deleted-message UI and that
the generic error text no longer appears.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 10:07:30 +01:00
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>
2026-07-09 14:57:48 -04:00
Jonathan Katz 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 -->
2026-07-09 13:17:03 -04:00
Dante Catalfamo 374aa7e612 LUKS key escrow validate against any keyslot (#48815)
**Related issue:** Resolves #46227
2026-07-09 13:04:31 -04:00
Tim Lee 56a3c75155 Fix macOS software titles mis-named from embedded helper bundles (#44199) (#47831) 2026-07-09 10:01:27 -06:00
Magnus Jensen bfc986df7e update missed ABM references (#49027)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48314 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Updated Apple Business Manager references across admin and host device
flows to use the shorter “AB” wording.
* Improved user-facing copy in enrollment, status, tooltip, and error
messages for consistency.
* Adjusted the automatic enrollment button label to match the updated
terminology.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-09 18:00:06 +02:00
Lucas Manuel Rodriguez 703dcf0b4f Update go to 1.26.5 (#48993)
Resolves #48988.

I ran `make update-go version=1.26.5`.

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.

## Testing

- [X] QA'd all new/changed functionality manually

Fleet:
<img width="301" height="102" alt="Screenshot 2026-07-09 at 8 41 49 AM"
src="https://github.com/user-attachments/assets/baf76ce7-6192-4506-a9db-52f5318939ee"
/>
fleetctl:
```
fleetctl --version
fleetctl - version orbit-v1.57.0-402-ge3d0c005dc
  branch:       48988-update-go-1.26.5
  revision:     e3d0c005dc6698c024ad47a124c99e4f264855a0
  build date:   2026-07-09
  build user:   lucas
  go version:   go1.26.5
```
Also verified orbit in Linux:
<img width="582" height="121" alt="Screenshot 2026-07-09 at 8 51 55 AM"
src="https://github.com/user-attachments/assets/65672676-8010-45a1-8c28-9f9959e72134"
/>


## fleetd/orbit/Fleet Desktop

- [X] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [X] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
  * Updated the project and all included tooling modules to Go 1.26.5.
* Refreshed build images used by desktop Linux, load testing, and
related utilities to the newer Go toolchain.
  * Updated change log entries to reflect the Go version bump.

* **Bug Fixes**
* Improved the automation that refreshes Go-pinned Docker image
references to resolve and apply correct digests, helping prevent broken
build images.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-09 11:20:45 -03:00
George Karr 69fa5ca435 Fix VPP/in-house app install on manual-profile BYOD iOS hosts (#48879) (#48916)
**Related issue:** Resolves #48879

# 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 (parameterized queries only).
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes — N/A,
no endpoint/path changes.

## Summary

Installing an App Store (VPP) or in-house app on an iOS/iPadOS host
enrolled via the **manual (profile-driven) BYOD** enrollment profile
failed: Fleet routed the install down the **Account-Driven User
Enrollment (user-scoped)** licensing path, tried to look up/register a
VPP user keyed on the host's Managed Apple ID, and returned _"Fleet
hasn't received a Managed Apple ID for this host yet."_ — which never
resolves, because a device-channel host has no Managed Apple ID.

### Root cause

The device-vs-user licensing decision keyed off
`host_mdm.is_personal_enrollment`. That flag is set for **both**:
- **Account-Driven User Enrollment** — user channel, backed by a Managed
Apple ID → user-scoped licensing (correct).
- **Manual-profile BYOD** — device channel, no Managed Apple ID → must
install **device-scoped**, exactly like company-owned manual enrollment.

### Fix

Branch on the actual enrollment **channel** — the presence of a
user-channel `nano_enrollments` row (`type='User' AND enabled=1`), the
same signal the MDM profile reconcile cron already uses
(`GetNanoMDMUserEnrollment`). This is timing-robust: the user
nano-enrollment exists from enrollment time, whereas the Managed Apple
ID only arrives minutes later via `TokenUpdate` (so `managed_apple_id`
emptiness is deliberately **not** used as the discriminator).

Three sites updated:
| File | Change |
|---|---|
| `ee/server/service/software_installers.go` |
`InstallVPPAppPostValidation` routes on `GetNanoMDMUserEnrollment`
instead of `is_personal_enrollment` |
| `server/datastore/mysql/vpp.go` | InstallApplication builder derives
`IsUserEnrollment` (ChangeManagementState omission) from a user-channel
`nano_enrollments` row |
| `server/datastore/mysql/activities.go` | same, for in-house `.ipa`
installs |

## Testing

- [x] Added/updated automated tests:
- `ee/server/service`:
`TestInstallVPPAppPostValidation_AssociateAssetsRouting` — added a
regression subtest asserting manual-profile BYOD (personal flag set,
device channel) routes via `serialNumbers` and performs **no** VPP user
lookup; repointed routing to the user-channel signal.
- `server/datastore/mysql`: new
`TestVPP/VPPInstallEnrollmentChannelRouting` — manual BYOD includes
`ChangeManagementState` despite `is_personal_enrollment=1`;
account-driven User Enrollment omits it.
- [x] Automated tests simulate multiple hosts and test for host
isolation (two distinct hosts, device- vs user-channel).
- [ ] QA'd all new/changed functionality manually — pending (draft).

For unreleased bug fixes in a release candidate:

- [x] Confirmed that the fix is not expected to adversely impact load
test results (adds one indexed lookup per install enqueue; removes a
`host_mdm` join).

## Database migrations

- N/A — no schema changes. The fix reads existing `nano_enrollments`
rows.

## fleetd/orbit/Fleet Desktop

- N/A

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed app installation for manually enrolled BYOD iPhone and iPad
devices so App Store and in-house apps install correctly on the device.
* Improved enrollment handling so device-scoped installs no longer fail
when a device is marked personal in one place but uses device-channel
enrollment.
* Account-Driven User Enrollment continues to use user-scoped licensing
and installs.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-09 07:32:37 -05:00
Steven Palmesano 89e653ce2b Update Windows MDM end user experience language (#47635)
**Related issue:** Resolves #43379

# 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

* **Style**
* Updated Windows MDM enrollment option labels from “Automatic/Manual”
to “Fleet agent-driven/End user-driven” and refreshed the related
on-page description/help text.
* Adjusted radio help-text spacing and added styling for label
formatting on the Windows MDM settings page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-09 06:07:30 -05:00
Victor Lyuboslavsky 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 -->
2026-07-09 07:38:47 +01:00
Nico 4c6aa754e0 Time ago timestamps: use days instead of months when under 90 days (#48964)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46965

Relative "time ago" timestamps switched to months at ~30 days, so a
timestamp 45 days ago read "about 2 months ago" (even 89 days showed "3
months ago"). This centralizes the day/month cutoff in a new `timeAgo`
helper and routes existing call sites through it, so anything under 90
days is shown in days.

# 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

* **Bug Fixes**
* Relative “time ago” timestamps now keep values in **days** for items
under **90 days**, switching to **months** later for more accurate
wording.
* Improved consistency of relative time labels across status modals,
activity feeds, host details, and management screens (including “last
updated,” “uploaded,” and “added” text).
* **Tests**
* Added/updated coverage for the shared relative-time cutoff and
formatting behavior to prevent regressions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-08 15:07:48 -03:00
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>
2026-07-08 13:43:14 -03:00
Steven Palmesano c759f92f14 Include mobile hosts by default in "Hosts online" chart (#48769)
**Related issue:** Resolves #47661

# 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 / Improvements**
* The “Hosts online” chart now includes mobile platforms
(iOS/iPadOS/Android) by default, alongside desktop platforms.

* **Bug Fixes**
* Initial load no longer shows a default “Filtered” badge; the chart
reflects the full default platform selection.

* **Documentation**
* Updated the “Hosts online” tooltip to clarify how locked iOS/iPadOS,
lid-closed Mac, and locked Android states affect the online count.

* **Tests**
* Updated chart card tests to match the new default platform behavior
and initial chart request parameters.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-08 11:38:26 -05:00
Rahul Raghunathan c92b848919 Return to previous page when the last policy on a page is deleted (#48683)
**Related issue:** Resolves #48641

## Description

Deleting the only policy on a paginated page (e.g., 21 policies, with 1
on page 2) left the user stranded on a now-empty page showing the "No
policies" empty state. The policies list now steps back to the previous
page when a delete empties the current page.

**Before:** delete last policy on page 2 → empty state.
**After:** delete last policy on page 2 → list returns to page 1.

### Screen recording demonstrating the fix


https://github.com/user-attachments/assets/ae106a50-7f9b-4080-a19c-53e0c60fff48


# 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

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Server-side paginated tables now recover from empty states after
deleting the last row on a page by redirecting to the last page that
still has data.
* Improved empty-state pagination handling for out-of-range pages,
loading states, and cases where the total row count is known (including
zero), avoiding unnecessary or repeated navigation.
* Simplified the empty-state pagination UI to render only the empty
component.
* **Tests**
* Expanded regression test coverage for server-side pagination edge
cases and page-correction behavior to prevent future regressions.
* **Style**
* Removed unused empty/previous-button styling rules in the table
container.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-08 13:14:14 -03:00
Tim Lee 496d4f5e24 Controls > OS settings > Certificates: View certificates (#48460) 2026-07-08 09:59:20 -06:00
Victor Lyuboslavsky 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 -->
2026-07-08 14:38:10 +01:00
Dante Catalfamo 4351f4cee5 escrow snapd TPM-backed FDE recovery keys from orbit (#48452)
**Related issue:** Resolves #44428
2026-07-07 16:25:20 -04:00
Dante Catalfamo 57dc28991a Add resolved-in-version override for CVE-2025-63389 on Ollama (#48525)
**Related issue:** Resolves #44800
2026-07-07 16:24:41 -04:00
Carlo 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 -->
2026-07-07 16:15:58 -04:00
Jonathan Katz 7b950c64a6 Add duplicate patch policy check to GitOps (#48896)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46193 

Adds a client-side check for duplicate patch policies, similar to the
existing policy name and label duplicate checks.

# 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
Adding two patch policies for the same fma slug results in this error:
```
Error: 1 error occurred:
	* Couldn't add multiple policies with type "patch" for "fleet_maintained_app_slug": "google-chrome/darwin".
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added validation to GitOps application checks to prevent multiple
patch policies from targeting the same app slug.
* Improved error reporting when patch policy slugs are duplicated or
missing from the configured app list.

* **Bug Fixes**
* Prevented duplicate patch policies from being silently accepted,
reducing the risk of one policy overwriting another.
* Existing valid combinations, such as different patch slugs or certain
mixed policy types, continue to work as expected.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 16:08:23 -04:00
Victor Lyuboslavsky 4608e82481 Added anonymous usage statistics reporting the number of macOS and Windows hosts enrolled in Fleet's MDM (#48840)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48685

# 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
- Tested `ShouldSendStatistics` method manually against our DB, which
covers all our changes.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **New Features**
* Added anonymous usage statistics for the number of macOS and Windows
hosts currently enrolled in Fleet’s MDM.

* **Bug Fixes**
* Improved statistics accuracy by counting only actually enrolled,
non-server macOS and Windows hosts that are using Fleet’s MDM.

* **Tests**
* Updated and extended statistics tests to verify the new enrollment
counts are computed and reported correctly.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 19:22:31 +01:00
Jordan Montgomery 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 -->
2026-07-07 13:15:14 -04:00
Jordan MontgomeryandCopilot Autofix powered by AI 3b7c88fb87 Fix dupe profile enqueue bug (#48652)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48633

# 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**
* Prevented duplicate profile enqueueing for hosts that share the same
hardware UUID.
* Reconcile processing now consistently picks the highest matching host
record when duplicates exist.
* Duplicate enrollment IDs are now filtered out before queueing,
reducing repeated work and avoiding queue conflicts.

* **Tests**
* Added regression coverage for duplicate-host and duplicate-enqueue
reconcile scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-07 13:08:26 -04:00
Steven Palmesano 5f3ea66ca0 Enable "Turn off MDM" button for offline macOS devices (#46651)
The original implementation (#8206) explicitly disabled this for offline
hosts until MDM command queueing was supported. That work has since been
completed, so offline macOS hosts now behave the same as iOS/iPadOS: the
unenroll command is queued and delivered when the device comes back
online.

**Related issue:** Resolves #25217

# 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**
* The "Turn off MDM" action is now enabled for offline macOS hosts.
Unenroll commands can be queued while a device is offline and will be
delivered automatically when it reconnects, matching the behavior for
iOS and iPadOS.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 11:20:45 -05:00
Steven Palmesano 1d1be298a9 Add /enroll URL for macOS in Add hosts modal (#47528)
**Related issue:** Resolves #38874

# 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**
* Added macOS enrollment details in the “Add hosts” flow, including a
clearer choice between **Personal (BYOD)** and **Company-owned**
devices.
* Shows a copyable macOS enrollment URL when MDM is configured, updating
the URL based on the selected device type.
* Keeps the macOS setup experience aligned with the enrollment method,
including packaging guidance when MDM isn’t enabled.
* **Tests**
* Added coverage for macOS enrollment URL rendering and device-type
switching in the “Add hosts” modal.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 11:18:45 -05:00
Carlo d85dd50166 Add onURLBlur handler for InputField (#48854)
**Related issue:** Resolves #40410

  # 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 (webhook Destination URL is now
validated on blur, matching the other URL fields in the app).

  ## Testing

  - [x] QA'd all new/changed functionality manually


[qa-40410.webm](https://github.com/user-attachments/assets/eefdddf0-a6dd-47d0-b819-89e9ac99c6f1)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved “Destination URL” validation by checking the URL when the
field loses focus and surfacing invalid webhook URLs immediately.
* Validation and error display are now suppressed when vulnerability
automations are disabled or when GitOps mode is enabled, preventing
confusing blur-time errors.
* **Tests**
* Added automated coverage for blur-time URL validation, including
typing/clearing behavior, valid vs empty states, and GitOps mode
scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 11:52:35 -04:00
Victor Lyuboslavsky 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 -->
2026-07-07 16:29:53 +01:00