Commit Graph
5101 Commits
Author SHA1 Message Date
Victor Lyuboslavsky 251093f6b3 Setup experience software policy checks (#47075)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45309 

If software is linked to policies, we run the policy during setup
experience to determine if software should be installed. We install on
failing policies.

# 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

* **New Features**
* Windows/Linux setup experience installers can be gated by team
policies: setup will run a policy check and skip installing if the
policy already passes; if the policy fails, the installer runs as part
of setup.
* After gated setup completes, the host’s policy set is re-evaluated
promptly so subsequent policy actions run immediately.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 21:16:37 +01:00
Jordan Montgomery afbbc447bb Improve apple MDM parsing (#47344)
<!-- 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**
* Enforced request body size limit for Apple MDM operations (≈16 MiB
cap).

* **Improvements**
* Safer Apple MDM plist parsing with bounds and complexity checks to
reject malformed/oversized payloads.
* Decoder updated to more strictly accept XML check-in/command payloads.

* **Tests**
* Added unit tests covering bounded plist decoding and XML-only decoding
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 15:35:04 -04:00
Magnus Jensen 1b91bb08f5 validate label scoping on fleet free unassigned (#47265)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #47191

Opted for the following error message: `Scoping configuration profiles
with labels requires Fleet Premium license` since only showing `Requires
Fleet Premium license` made me think I'm unsure what part specifically
requires the license.

# Checklist for submitter

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


## 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
- [ ] Alerted the release DRI if additional load testing is needed


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

* **New Features**
* Enforced Fleet Premium license for MDM config profile label scoping
across Apple, Android, Windows, and batch operations.
* **Bug Fixes**
* License errors now include the specific feature cause in the message
when premium is required and are matchable with standard error checks.
* **Tests**
* Added and updated tests to verify premium-gating for profile label
scoping and related behaviors on free vs. premium tiers.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 17:22:52 +02:00
Carlo 0c820a67fc Fix GCS checksum flag derived from wrong endpoint key (#47145)
Fixes https://github.com/fleetdm/fleet/issues/47142
2026-06-09 13:55:25 -04:00
Carlo 1e9f341eb5 Narrow host lookup for iDevice URL auth (#47141)
# Summary

Adds a `HostByUUID` datastore method that matches on the `uuid` column
only, and uses it in the iOS/iPadOS device URL authentication path
(`AuthenticateIDeviceByURL`) instead of the broader `HostByIdentifier`
helper.
2026-06-09 13:13:37 -04:00
Scott GressandLucas Manuel Rodriguez ffbbb9e866 Validate SSO settings correctly for GitOps (#46487)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #43371 

# Details

* Ensures that if `enable_sso: true` is set in a global config, then all
required sso keys (`entity_id`, `idp_name` and one of
`metadata`/`metadata_url`) are provided
* Ensures that if `end_user_authentication: true` is set on a fleet,
then all required sso keys (`entity_id`, `idp_name` and one of
`metadata`/`metadata_url`) are provided, _even if the fleet's config
file is not provided in the gitops run_.
* Ensures that if `end_user_authentication: true` is set in a fleet
config in a gitops run, then all required sso keys (`entity_id`,
`idp_name` and one of `metadata`/`metadata_url`) are provided, _even if
the global config file is not provided in the gitops run_.

# 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
  ### Org SSO — gitops client validation (`fleetctl gitops`)
- [x] `enable_sso: true` with **empty `metadata` and `metadata_url`** →
fails (metadata-or-url)
  - [x] `enable_sso: true` with **empty `idp_name`** → fails (idp_name)
- [x] `enable_sso: true` with **empty `entity_id`** → fails (entity_id)
- [x] Multiple fields missing at once → **one error line per missing
field**
  - [x] `enable_sso: true` + complete IdP (`metadata_url`) → succeeds
- [x] `enable_sso: true` + complete IdP using inline `metadata` (no url)
→ succeeds
  - [x] `enable_sso: false` + empty IdP fields → succeeds
- [x] `sso_settings` key **omitted entirely** → succeeds, and apply
**clears** stored SSO
- [x] The literal `generate-gitops` output (`metadata: # TODO: ...`)
applied as-is → **rejected**

  ### MDM EUA — gitops group cross-file validation
- [x] Team file enables EUA **+** global file **omits** the EUA IdP
block → fails
- [x] **#43371 core repro:** stored team EUA on, file NOT in run,
global-only run blanks metadata → fails, names the team
- [x] Same but the team's file **is** in the run with EUA `false` →
succeeds
  - [x] EUA disabled everywhere + **empty** stored IdP → succeeds

  ### `--delete-other-fleets`
- [x] Run with `--delete-other-fleets` degrading the IdP while a stored
not-in-run team has EUA on → succeeds
  - [x] Confirm the omitted team is actually deleted on apply
- [x] Known corner: `--delete-other-fleets` + omitted ABM/VPP team with
EUA on + degraded IdP → fails at apply time

  ### Server-side backstop (REST API)
- [x] `PATCH /config` (overwrite=false), `enable_sso:true`, metadata
omitted, existing has metadata → **200**, metadata preserved
- [x] `PATCH /config?overwrite=true`, `enable_sso:true` + empty
metadata/url → **422** field `metadata`
- [x] `?overwrite=true`, metadata_url set, empty `entity_id`/`idp_name`
→ **422** both `required`
- [x] `?overwrite=true`, `enable_sso:false` → **200** (no IdP required
when disabled); `sso_settings` omitted entirely → clears (covered by
gitops POS-2)

  ### Server-side EUA (`euaStrict` keyed on incoming global flag only)
- [x] `?overwrite=true` + incoming **global** EUA enabled + incomplete
IdP → **422** `entity_id`/`idp_name`
- [x] `?overwrite=true` + global EUA **off** + stored team EUA + payload
degrades IdP → **succeeds** (via gitops #43371-OVERRIDE)
- [x] `?overwrite=true` + global EUA off + payload **fully clears** IdP
while a team has EUA → **422** `end_user_authentication` (IsEmpty guard)

  ### Regression / false-positive guards
- [x] Multi-file gitops `--dry-run` configuring IdP AND enabling team
EUA (empty stored IdP) → dry-run passes (EE dry-run skip)
- [x] A previously-working gitops run with a complete SSO/EUA config →
still applies cleanly

  ### End state verification
  - [x] After any **rejected** run, stored SSO/EUA config **unchanged**
- [ ] After a valid complete-IdP run, SSO login + ADE/EUA enrollment
works end-to-end (live device)



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

* **Bug Fixes**
* GitOps now validates SSO and MDM end-user authentication (EUA) configs
before applying changes, rejecting incomplete settings when SSO/EUA are
enabled globally or for any team. Overwrite (GitOps) mode enforces
stricter validation than standard updates; dry-run behavior adjusted to
avoid spurious EUA rejections.

* **Tests**
* Added comprehensive tests covering SSO/EUA validation, overwrite vs
patch semantics, cross-file EUA scenarios, and delete-other-fleets
behavior.

* **Refactor**
* Reorganized validation and config-parsing helpers for reuse in GitOps
checks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
2026-06-09 11:38:48 -05:00
Nico 097c82a337 Reorder org_logo migration to follow AddHostCertificatesOriginDeletedAtIndex (#47168)
Follow-up to #47099. Re-timestamps the `CreateOrgLogoTable` migration so
it can also ship in the **4.86.2** patch.

`CreateOrgLogoTable` must sort **immediately after**
`20260527215817_AddHostCertificatesOriginDeletedAtIndex` (the last
migration in 4.86.1).

## Testing

- Started server with latest `main` migrations applied. It failed.
- Ran `UPDATE migration_status_tables SET version_id = 20260527215818
WHERE version_id = 20260608173427;`.
- Started server, no crashes.

<img width="1458" height="628" alt="Screenshot 2026-06-09 at 10 19
40 AM"
src="https://github.com/user-attachments/assets/68d24712-78ae-42ca-8989-60c39647dd33"
/>


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

## Summary by CodeRabbit

* **Chores**
* Updated database migration infrastructure and corresponding tests to
maintain consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-09 12:00:55 -03:00
Allen HouchinsandNoah Talerman 3906398928 Schedule calendar remediation events next business day after policy failure (#42435)
This pull request updates the logic for scheduling calendar events to
always select the next business day (skipping weekends) instead of
scheduling on the next Tuesday. The test suite for this functionality
has also been rewritten to reflect the new behavior and to improve
clarity.

**Business logic update:**

* Changed `getPreferredCalendarEventDate` in `calendar_cron.go` to
return the next business day after the provided date, skipping weekends,
instead of always selecting the next Tuesday.

**Test updates:**

* Refactored the test cases in `calendar_cron_test.go` to use specific
`today` dates and expected results, ensuring coverage for weekday
transitions, weekend skipping, and month/year rollovers. The tests now
directly check the next business day logic rather than iterating over
ranges of days.

**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.

- [ ] 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)

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

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

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

## Database migrations

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

## New Fleet configuration settings

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

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

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

## fleetd/orbit/Fleet Desktop

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



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

* **Bug Fixes**
* Calendar events now schedule on the next business day (skipping
weekends) after a policy failure instead of a fixed weekly day.

* **Tests**
* Updated unit tests to validate the new next-business-day behavior with
explicit expected dates.

* **Documentation**
* Updated scheduling description to reflect next-business-day
remediation timing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com>
2026-06-09 09:15:47 -05:00
Dante Catalfamo 7ad95ac2c3 Fixed the host's Software UI showing a date decades in the past (#46779)
**Related issue:** Resolves #43622
2026-06-08 17:24:05 -04:00
Dante Catalfamo ad30812054 Speed up /vulnerabilities and filtered /software/versions queries (#45564)
Address 100% DB CPU spikes observed when paginating these endpoints with
filters. Two root causes: cve_meta and vulnerability_host_counts lack
indexes for the actual filter shapes, and ListVulnerabilities ran
correlated scalar subqueries on every row of vulnerability_host_counts
that matched the scope (1.1M rows examined per call).

Add three online indexes:
- cve_meta(cisa_known_exploit, cve) for the exploit filter
- cve_meta(cvss_score, cve) for the CVSS range filter
- vulnerability_host_counts(global_stats, team_id, host_count, cve) for
the scope filter on the vulnerabilities endpoint

Refactor ListVulnerabilities into a two-stage query: an inner query
filters, sorts, and paginates vulnerability_host_counts (with an
optional LEFT JOIN to cve_meta for sort/filter columns), and an outer
query enriches only the paginated page with the created_at and source
scalar subqueries. Net effect: the heavy subqueries run perPage times
(~20-100) instead of millions. Sort-by-created_at falls back to the
single-statement form since the sort key is itself the subquery result.

CountVulnerabilities drops the redundant DISTINCT (vhc.cve is already
unique within a (global_stats, team_id) scope via the existing UNIQUE
KEY) and only joins cve_meta when KnownExploit filtering is requested.

**Related issue:** Resolves #45415
2026-06-08 17:02:47 -04:00
Nico 3f5944626c Fix Fleet startup crash on read-only filesystem without S3 bucket (#47099)
**Related issue:** Resolves #47090

Fleet crashes into `CrashLoopBackOff` on startup when deployed on
Kubernetes with `readOnlyRootFilesystem: true` and **no** S3 software
installers bucket configured:

```
Failed to start: initializing filesystem org logo store: mkdir /tmp/org-logos: read-only file system
```

I realised I was calling `initFatal` when failing to create a directory
on the filesystem which doesn't match the pattern of `logging` +
`creating a "failing" store` (one that is initialized but fails all
operations) as we do for e.g. software title icons (see
NewFailingSoftwareTitleIconStore).

Per this slack conversation:
https://fleetdm.slack.com/archives/C084F4MKYSJ/p1780931127976389, we
decided to fall back to a database-backed storage:

<img width="737" height="114" alt="Screenshot 2026-06-08 at 3 16 28 PM"
src="https://github.com/user-attachments/assets/2a6ff75f-b382-40ba-81d9-3be3cfbd648a"
/>


# 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

Commented out this line to force filesystem usage:

<img width="615" height="71" alt="Screenshot 2026-06-08 at 1 18 53 PM"
src="https://github.com/user-attachments/assets/85043c88-5c8c-48a0-8145-098fba9513bd"
/>


#### Before

Server crashes

<img width="1278" height="124" alt="Screenshot 2026-06-08 at 1 18 17 PM"
src="https://github.com/user-attachments/assets/7b788a24-131a-47a3-8580-fcd9fda8b449"
/>


#### After

Server starts and logo upload works

- Without --dev_license



https://github.com/user-attachments/assets/58c5ebf9-cf52-4ba0-ac98-9675e7eef92c



- With --dev_license




https://github.com/user-attachments/assets/117bb812-31bd-4849-927c-93cafd1a71d7








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

## Release Notes

* **New Features**
- Organization logos now support database storage as the fallback option
when S3 software installers bucket is not configured, replacing local
filesystem storage for improved reliability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 17:15:14 -03:00
Steven Palmesano 20c0963331 Fix GitOps when using All fleets in VPP settings (#46855)
**Related issue:** Resolves #46824

# Checklist for submitter

- [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

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

* **Bug Fixes**
* Fixed an issue where volume purchasing program assignments failed when
"All fleets" was selected; validation and token assignment now treat the
"All fleets" label consistently, preventing errors during configuration
application.
* **Tests**
* Added an end-to-end GitOps test case verifying "All fleets" is
supported for volume purchasing program entries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 13:27:57 -05:00
Konstantin Sykulev 2570e25f0e Defer writing team_id on android check-ins (#46929)
**Related issue:** Resolves #44113

# 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

## Release Notes

* **Bug Fixes**
* Fixed an issue where Android device check-ins could revert admin team
transfers, ensuring team assignments persist correctly after
re-enrollment.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 11:55:26 -05:00
Jonathan Katz e34126ab3a Merge branch 'main' of github.com:fleetdm/fleet into feat/39018-self-service-categories
Bump migration, fix failing test and nilaway check
2026-06-08 12:12:33 -04:00
Allen Houchins 61064687e4 Add Python 3.13 & 3.14 as Windows FMAs and normalize versions (#46873)
This pull request improves the handling of version comparisons for
Windows application patch policies in the `winget` ingester,
specifically to support installers (like python.org) where the
registry's `DisplayVersion` does not match the package's marketing
version. It introduces a new option to compare against the
`DisplayVersion`, adds robust test coverage for this logic, and onboards
Python 3.13 and 3.14 as maintained apps with correct install/uninstall
scripts.

**Patch policy improvements:**

* Added a `UseDisplayVersionForPatch` field to `inputApp` and supporting
logic in the ingester to optionally compare patch policy versions
against the registry `DisplayVersion` instead of the package version,
with error handling if no display version is found.
[[1]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8R414-R434)
[[2]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8R566-R571)
* Introduced the helper function `firstDisplayVersion` and extended the
`appsAndFeaturesEntries` struct to include `DisplayVersion`.
[[1]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8R448-R458)
[[2]](diffhunk://#diff-eb6c4ae7be41e61a2292c4240de750809d40c0686fb01f80f52df056ebc9c2a8R612)

**Test coverage:**

* Expanded test cases in `ingester_test.go` to cover the new
`UseDisplayVersionForPatch` logic, including both positive and negative
scenarios.
[[1]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055R347)
[[2]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055R374-R424)
[[3]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055L410-R470)
* Updated test server config and fixtures to support `DisplayVersion`
for accurate test simulation.
[[1]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055R482)
[[2]](diffhunk://#diff-c68f0564df3c6e38ad333d4ca6e1040305eb079eb0d168d29c95b1b250463055L447-R503)

**New maintained apps:**

* Added onboarding for Python 3.13 and Python 3.14 as maintained apps,
each with a `use_display_version_for_patch` flag, install/uninstall
scripts, and appropriate configuration.
[[1]](diffhunk://#diff-8a640dba0d8cc9ee50cef0397c5efce6655957dde836df94e6d5fb536f422fecR1-R15)
[[2]](diffhunk://#diff-e25e77b6c53c5fcc80a6d7589547873b5007dbcca660decbff3c9579c057b0fbR1-R15)
[[3]](diffhunk://#diff-fca224dfb5a7262b0b4ad68061b06552dc5291aeb8e2409fd5c9c6f8d8022dacR1-R32)
[[4]](diffhunk://#diff-b2bd0383162063c7923532a2be6b7014310a79fe3b0c681d1647bcd0fa6e3fe8R1-R147)

These changes ensure that patch policies correctly flag outdated
installs for apps where the registry version format differs from the
package version, and Python installs are now robustly managed via Fleet.

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

# Checklist for submitter

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

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

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

## Testing

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

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

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

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

## Database migrations

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

## New Fleet configuration settings

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

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

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

## fleetd/orbit/Fleet Desktop

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


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

* **New Features**
* Added support for Python 3.13 and Python 3.14 on Windows Fleet,
including install/uninstall workflows and manifests
  * Option to use installer-displayed version for patch comparisons

* **Improvements**
* Normalized Windows-reported Python version strings for consistent
inventory and vulnerability matching
  * Added icons for Python 3.13 and 3.14 in the software catalog
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 10:51:32 -05:00
Magnus Jensen 47f5aa1c5d validate against old config for partial patches (#47069)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Follow up PR for extra validation for partial patches

# Checklist for submitter

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

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [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

* **Improvements**
* Refined macOS setup validation to correctly handle partial updates
when modifying team settings.
* Managed local account fields now update only when explicitly provided,
avoiding accidental overwrites.
* Validation now considers existing configuration when validating
updates to ensure consistent, context-aware checks.

* **Tests**
* Added comprehensive tests covering macOS setup validation, managed
account behaviors, and user account type rules.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 17:28:22 +02:00
Magnus Jensen 6a84d3a489 update apple query for profile verification with include all/any + exclude (#47079)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Follow up PR for the Include Any/All + Exclude label
story, since this was missed.

# Checklist for submitter

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

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

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

## Testing

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

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

* **Bug Fixes**
* Improved Apple MDM profile verification to more accurately determine
expected configuration profiles, including correct handling of mixed
include/exclude label combinations and exclusion edge cases.

* **Tests**
* Updated unit and integration tests to reflect the expanded Apple
include+exclude scenarios and to run Apple-only profile reconciliation
flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 17:24:23 +02:00
Victor Lyuboslavsky cd5c44db72 MDM Windows push perf fixes (#46917)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46567 

Loadtest feedback: reducing the number of `UPDATE
mdm_windows_enrollments e SET e.has_pending_commands` writes.

# Checklist for submitter

## Testing

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

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

## Database migrations

- [x] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [x] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.

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

* **Bug Fixes**
* Fixed Windows MDM enrolled devices to correctly track pending
commands. Acknowledged commands are now properly removed from the
pending list, and the system accurately reflects command status after
device acknowledgment. Command cleanup for processed requests is now
more efficient.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 15:34:35 +01:00
Jonathan Katz a471b6f641 List categories device endpoint (#46938) 2026-06-08 09:15:17 -05:00
Lucas Manuel Rodriguez 863363561b Fix fleet-scoped host vitals labels (#46953)
**Related issue:** Resolves #46869

- [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**
* Host vitals labels based on identity-provider group membership now
correctly apply to both global and team-scoped hosts, preventing
cross-team leakage.

* **Tests**
* Added and updated tests to validate IdP-group-backed vitals label
membership across global and per-team hosts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 10:46:56 -03:00
Victor Lyuboslavsky 89965f4f9a Extract platform-neutral MDM reconcile label primitives (#47032)
Pure refactor, no behavior change. First step for #45635 (Windows
batched in-memory reconciler).

- New server/mdm/reconcile package holds the include/exclude label
handlers and the team+label applicability dispatcher. The Apple platform
gate stays in the Apple wrapper since platform eligibility is
platform-specific.
- New platform-neutral fleet types (MDMProfileLabelRef,
MDMProfileIncludeMode, MDMLabeledEntity); the Apple names are now type
aliases so existing code and tests are unchanged.
- BulkGetHostLabelMemberships moves from apple_mdm_batched.go to a
neutral file; it was already platform-agnostic.
- The existing Apple label-scenario tests keep covering the shared logic
through the delegating wrappers; the shared package also gets its own
handler/dispatcher tests.

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

# Checklist for submitter

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

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

## Testing

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

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

* **Refactor**
* Moved MDM profile include/exclude label logic into a shared,
platform-neutral reconciliation flow for consistent behavior across
platforms.
* Consolidated Apple MDM label handling to reuse the shared
reconciliation primitives and improved host label membership lookup
behavior.

* **Tests**
* Added and reorganized unit tests covering MDM label-based profile
reconciliation, include/exclude rules, and Apple-specific wrapper
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 12:28:27 +01:00
CarloandJonathan Katz fb9e4c4701 Auth in-house iOS app downloads with install tokens (#46819)
# 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.
- [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

  ## 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

## Release Notes

* **New Features**
* In-house iOS app manifest and package downloads now use secure
per-install tokens embedded in the URL path instead of query parameters
* Installation tokens are bound to specific devices and teams, enhancing
security
  * Installation tokens automatically expire after 6 hours
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Jonathan Katz <yehonatankatz@gmail.com>
2026-06-05 16:34:20 -04:00
Dante Catalfamo e90bcfeaae Add rules to deal with some python CVE false positives (#46673)
**Related issue:** Resolves #35148

## What was added

| CVE | Rule | Reason |
|-----|------|--------|
| **CVE-2017-17522** | `IgnoreAll` | DISPUTED by Python maintainers; not
exploitable (`webbrowser.py` uses `subprocess.Popen` with
`shell=False`). Broad NVD CPE matched modern Python. |
| **CVE-2023-36632** | `IgnoreAll` | NVD-DISPUTED — Python states it's
"neither a vulnerability nor a bug" (intentional `RecursionError` in
`email.utils.parseaddr`). |
| **CVE-2024-3219** | `IgnoreIf target_sw != "windows"` | Only affects
platforms lacking AF_UNIX (Windows). Linux/macOS unaffected, but
NVD/VulnCheck CPE uses `target_sw=*`. |

**Files touched:**
- `cpe_matching_rules.go` — three new rules
- `cpe_matching_rule_test.go` — assertions covering all three (incl.
Windows-vs-macOS/Linux distinction for CVE-2024-3219)
- `changes/35148-python-cve-false-positives` — changelog

**Correctness note:** `target_sw` derives from software *source*
(`apps`/`homebrew_packages` → `macos`, `programs` → `windows`), so the
CVE-2024-3219 rule suppresses on macOS while preserving the genuine
Windows
positive.

## What was skipped, and why

| CVE | Why skipped |
|-----|-------------|
| **CVE-2024-12718** | Conflicting evidence: getvictor confirmed it's a
**true positive** (3.9.22 < fixed 3.9.23), contradicting the customer's
"only 3.12+ affected" reasoning. Needs a product/security ruling, not a
code change. |
| **CVE-2025-1795** | Likely a VulnCheck patch-level miss (customer says
3.10.17 has the backported fix). Needs the actual VulnCheck version
range to fix safely. |
| **CVE-2023-32681** | Affects `python:requests` and is **correctly
matched**; the customer dismissed it on deployment grounds ("corporate
servers only"). Not a detection bug. |
| **CVE-2007-4559** | Real tarfile path-traversal (CVSS 9.8, **not
disputed**); the customer labeled it "Other issue," not a false
positive. Suppressing it would hide a genuine vulnerability. |
2026-06-05 16:21:09 -04:00
Dante Catalfamo 49db931ffb Auto-clean duplicate Okta CA SCEP cert after profile install (#46172)
**Related issue:** Resolves #42757

## Summary

Resending or renewing the Okta conditional access profile leaves an
orphaned SCEP certificate in the per-user macOS keychain, accumulating
duplicates with every renewal. This PR auto-runs an existing
keychain-cleanup script after a successful `InstallProfile` ack for the
Okta CA profile, so admins no longer have to find and run the script
manually.

## Root cause

Investigation in the issue thread isolated the trigger:

- The Okta CA `.mobileconfig` bundles `com.apple.security.scep` with
`com.apple.security.identitypreference` in a single profile (macOS
rejects the alternative — `Identity payload not found in same profile as
identity preference payload`).
- The Identity Preference payload creates a keychain-resident preference
item that keeps the *old* cert pinned across profile replacement, even
though the rewritten Identity Preference now points to the fresh SCEP
enrollment.
- EAP-TLS Wi-Fi profiles renew cleanly because they reference the cert
via SystemConfiguration (`PayloadCertificateUUID`), not the keychain —
so this isn't a generic SCEP-bundling issue.

The team decision in the issue (`@sharon-fdm`) was to delete the
duplicate certificate rather than restructure the profile. A standalone
cleanup script already shipped at
`docs/solutions/macos/scripts/delete-duplicate-scep-certificates.sh` and
was linked from the Okta CA guide; admins had to find and run it.

## Approach

Hook the existing Apple MDM `InstallProfile` ack path in
`MDMAppleCheckinAndCommandService.CommandAndReportResults`, parallel to
the existing ACME `CertificateList` follow-up. When the ack is for the
Okta CA profile and status is `verifying`, enqueue an internal host
script run that executes the cleanup script targeting the host's
per-user MDM enrollment short name.

Key properties:

- **Single hook, three paths covered.** Admin "Resend" nulls the profile
status and the reconciliation cron re-enqueues an `InstallProfile`; the
SCEP renewal cron also re-issues `InstallProfile`. Both flow through the
same ack handler this hook attaches to.
- **Idempotent.** The cleanup script no-ops when only one matching cert
is present, so triggering on initial installs (not just renewals) is
safe and removes the need to distinguish "is this a renewal".
- **Tightly gated.** Single indexed lookup keyed on `(host_uuid,
command_uuid, profile_identifier, platform='darwin')`. Other
SCEP-bearing profiles do not trigger the script. No work happens for
hosts with no per-user enrollment.
- **Internal-script semantics** (matches lock/unlock/wipe prior art).
Runs even when scripts are globally disabled. Does not appear in the
user-facing host activity feed.
- **Failure-isolated.** Enqueue errors are logged but do not break the
ack path; the renewal itself is what matters.
- **Defense in depth on the shell call.** The macOS short name is
validated against a strict regex (`^[A-Za-z0-9_][A-Za-z0-9_.-]*$`, ≤31
chars) before being interpolated, and POSIX single-quote-escaped on the
way through.

## Files

**New**
- `server/service/conditional_access_cleanup.go` — `//go:embed` of the
cleanup script, the hook helper `maybeRunOktaCACleanupScript`, the
validated shell-wrapper builder, and the POSIX single-quote escape
helper.
- `server/service/conditional_access_cleanup_test.go` — unit coverage
for username validation, shell escaping, the routing decisions of the
hook helper (mock-based), and an embed-sync assertion against the docs
copy.
-
`server/service/embedded_scripts/delete-duplicate-scep-certificates.sh`
— embed source-of-truth copy, byte-for-byte equal to the public
`docs/solutions/macos/scripts/` script.
- `changes/42757-okta-conditional-access-duplicate-scep-cert-cleanup` —
user-visible changes note.

**Datastore**
- `server/datastore/mysql/mdm.go` —
`OktaCACleanupTargetForInstallCommand`: single SQL lookup that returns
`(host_id, user_short_name, ok)` for the new hook. Returns `ok=false`
for non-Okta profiles, non-darwin hosts, or hosts without a user-channel
enrollment.
- `server/datastore/mysql/scripts.go` —
`NewInternalHostScriptExecutionRequest`: thin wrapper that routes
through the existing internal-script codepath (`isInternal=true`) used
by lock/unlock/wipe. Refactored the existing public method to share an
internal helper.

**Interface / mocks**
- `server/fleet/conditional_access_idp.go` — exported
`ConditionalAccessOktaProfileIdentifier`,
`ConditionalAccessOktaCertificateCN`, and the new `OktaCACleanupTarget`
struct, so both the template-render path and the SQL lookup can
reference the same source of truth.
- `server/fleet/datastore.go` — `OktaCACleanupTargetForInstallCommand`
and `NewInternalHostScriptExecutionRequest` added to the `Datastore`
interface.
- `server/mock/datastore_mock.go` — regenerated (additions only).

**Wiring**
- `server/service/apple_mdm.go` — call into
`maybeRunOktaCACleanupScript` from the InstallProfile
`MDMDeliveryVerifying` branch, alongside the existing ACME
`maybeQueueCertificateListForACMEProfile` follow-up. Warns on error
rather than failing the ack.
- `server/service/conditional_access_idp.go` — use the new
`fleet.ConditionalAccessOktaCertificateCN` constant when rendering the
profile template, eliminating the magic string duplication.

**Tests touched**
- `server/datastore/mysql/mdm_test.go` — integration test
`testOktaCACleanupTargetForInstallCommand` covering the happy path,
non-Okta profile, device-only enrollment, and unknown command.
- `server/datastore/mysql/scripts_test.go` —
`testNewInternalHostScriptExecutionRequest` confirming the internal flag
is set correctly and the new entry only appears under the internal-only
listing filter.
- `server/service/apple_mdm_test.go` — added the new mock stub for
`OktaCACleanupTargetForInstallCommandFunc` to
`TestMDMCommandAndReportResultsProfileHandling` so the existing test
continues to pass with the new hook in the codepath.
- `server/service/conditional_access_idp_test.go` — the rendered-profile
assertion now also pins on the shared
`ConditionalAccessOktaProfileIdentifier` and
`ConditionalAccessOktaCertificateCN` constants so the template can't
drift from the SQL lookup.
2026-06-05 16:20:32 -04:00
Konstantin Sykulev b02fa180b2 Preserve android device team assignment (#46868)
**Related issue:** Resolves #45263

# Checklist for submitter

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

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.

## Testing

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



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

* **Bug Fixes**
* Android devices no longer lose team assignments or certificate
configuration when a host is deleted and the device re-enrolls.
* Re-enrollment restores a device’s previously known team when
available, preserving certificate templates and team-specific settings.
* Team transfers for Android devices now reliably update device records
so certificates and access remain consistent.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 14:18:16 -05:00
Jonathan Katz d6b56d81bd Self service categories - install all (#46865)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46393 

# Checklist for submitter

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

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

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

## Testing

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

- [x] QA'd all new/changed functionality manually
2026-06-05 13:43:51 -04:00
Andrew MellorandCopilot Autofix powered by AI 244cdd5558 45178 cpie reconciler query updates (#46889)
**Related issue:** Resolves #45178

# Checklist for submitter

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

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.


## Testing

- [x] Added/updated automated tests
- [x] 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. _Note: Only windows
and Mac OS. Android required by someone with a device._


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

* **New Features**
* Improved MDM profile applicability on Android, Windows, and Apple to
handle combined include-all, include-any, and exclude-any label rules,
yielding more accurate install/remove decisions.

* **Tests**
* Added cross-platform tests covering combined include/exclude label
scenarios to verify correct profile selection, installation, and removal
behavior.
<!-- 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-06-05 13:36:52 -04:00
Juan Fernandez f19c9a6696 Optimize ListLabels host-count query
Fixes #4890

* Optimized listing labels query by refactoring correlated subquery.
* Optimized aggregate that counts host's labels to executed once, and
skip the join to hosts entirely when the team filter allows all hosts.
2026-06-05 12:29:30 -04:00
Dante Catalfamo 8cb7f8af67 Add macos_applications filter for host software list (#46223)
Adds a `macos_applications` boolean query parameter to the list host
software endpoint (`GET /api/_version_/fleet/hosts/{id}/software`). When
true, results are restricted to apps installed at the top level of the
macOS /Applications folder, hiding helper apps, system apps,
command-line tools, and user-local apps. The filter applies only to
macOS hosts and is ignored on other platforms.

The filter is applied by pruning the in-memory software maps in
ListHostSoftware down to the title IDs that have a top-level
`/Applications` bundle, so the count and paginated queries stay
consistent and the filter applies uniformly across regular, VPP, and
in-house apps. Top-level is determined from
`host_software_installed_paths` via
`installed_path LIKE '/Applications/%' AND NOT LIKE '/Applications/%/%'
on source 'apps'`.

**Related issue:** Resolves #39017
2026-06-05 11:59:43 -04:00
Josh RoskosandScott Gress 49b86438bb feat: replace osquery column with agent column on hosts page (#44811)
for #44846
for #43458 

- UPDATE: @noahtalerman: For the following story:
  - https://github.com/fleetdm/fleet/issues/44846

---

# 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

## 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

## Release Notes

* **New Features**
* Added a new Agent column on the Hosts page displaying Orbit version
with tooltips showing Osquery, Orbit, and Fleet Desktop versions for
comprehensive version visibility.

* **Improvements**
* Updated default column visibility on the Hosts page—Issues and Private
IP columns are now hidden by default for a cleaner view.

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

---------

Co-authored-by: Scott Gress <scott@fleetdm.com>
2026-06-05 09:18:02 -05:00
edwardsbandCarlo bb1d09fc90 Add GCS IAM authentication for S3-compatible storage (#40303) (#40374)
Closes #40303


### Summary
Adds support for Google Application Default Credentials (ADC) bearer
token authentication when using GCS's S3-compatible endpoint. This
allows Fleet deployments on GCP to use workload identity instead of
static HMAC keys.
 Changes
- Add `s3_software_installers_gcs_iam_auth` config option for software
installer storage
- Add `s3_carves_gcs_iam_auth` config option for file carving storage  
- Implement OAuth2 bearer token auth in S3 client via middleware
(removes AWS SigV4 signing)
- Add validation to ensure GCS IAM auth requires endpoint URL containing
`storage.googleapis.com`
- Add Helm chart values and deployment env vars for both options
- Add documentation for new configuration options
- Add tests for GCS IAM auth validation and integration

### Usage
Enable GCS IAM auth by setting the endpoint URL to Google's
S3-compatible endpoint and enabling the IAM auth flag:

```yaml
s3:
  software_installers_endpoint_url: https://storage.googleapis.com
  software_installers_gcs_iam_auth: true
  software_installers_bucket: my-bucket
  software_installers_force_s3_path_style: true
```
Or via environment variables:
```
FLEET_S3_SOFTWARE_INSTALLERS_ENDPOINT_URL=https://storage.googleapis.com
FLEET_S3_SOFTWARE_INSTALLERS_GCS_IAM_AUTH=true
FLEET_S3_SOFTWARE_INSTALLERS_BUCKET=my-bucket
FLEET_S3_SOFTWARE_INSTALLERS_FORCE_S3_PATH_STYLE=true
```

### Testing
- Unit tests validate configuration requirements (GCS endpoint, no HMAC
keys, no STS role)
- Integration test verifies bearer token is correctly injected into
requests
**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.

## Testing

- [X] Added/updated automated tests

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

## New Fleet configuration settings

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

> [!NOTE] 
These are infrastructure-level server settings (env vars/config file),
not app-level settings managed via GitOps YAML.

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

## Summary by CodeRabbit

* **New Features**
* Added Google Cloud Storage (GCS) IAM authentication support for file
carving and software installer storage using Google Application Default
Credentials

* **Configuration**
* New authentication configuration option available for both carving and
software installer S3 storage in Helm deployments and configuration
files

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/40374)

<!-- review_stack_entry_end -->

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

Co-authored-by: Carlo <1778532+cdcme@users.noreply.github.com>
2026-06-05 09:04:35 -05:00
Magnus Jensen 7bcc79da0c Decrease lock state cleanup time to 1 minute (#46730)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44440

# 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
^ I verified if within 1 minute it's still locked, after 1 minute it
removes the Locked state

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

* **Bug Fixes**
* Reduced the delay for Apple MDM unlock status updates so recently
unlocked hosts are reflected as unlocked much faster (cleanup window
shortened from ~5 minutes to ~1 minute), improving Fleet responsiveness
and accuracy.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 15:41:03 +02:00
Jordan MontgomeryandCopilot Autofix powered by AI 6d8ec7a1d0 Fix restoration of DEP hosts when a duplicate exists (#46815)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45192 

# 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**
* Deleting one of multiple duplicate Apple DEP hosts now properly
resolves the duplicate and prevents recreation of a pending host when
another host with the same serial and platform still exists.

* **Tests**
* Added unit tests covering deletion behavior for duplicate DEP hosts to
ensure correct resolution and no unintended pending-host restoration.
<!-- 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-06-05 08:30:56 -04:00
Magnus Jensen cfcca6a6ac Handle not found bootstrap package in GitOps flows (#46802)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45441 

The issue is when hitting the `svc.DeleteMDMAppleBootstrapPackage` via
the API/UI, it only clears the row in `mdm_apple_bootstrap_packages`.
However when GitOps runs the next time, it compares the old team config,
which has a stale `macos_setup.bootstrap_package` config value. Which
forces it to call the same Delete method again. This PR adds the
defensive approach to gracefully handle a not found bootstrap package
when GitOps wants to delete it.
The reason the second run works, is that we only attempt to delete the
bootstrap package after we called SaveTeam with the new empty
`bootstrap_package` value. So next run sees it as empty and avoid
calling the Delete method.

_One question is if we want to add a more active approach on the delete
service method, which also handles updating the team config clearing out
this value? That would have prevented the cause, I think either keeping
only this layer, or doing both solutions is a good approach._

# 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**
* GitOps automation no longer fails on its first run after a bootstrap
package is deleted via the UI.
* Clearing a macOS bootstrap package (team or app config) now succeeds
even if the underlying package record is already missing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 11:48:13 +02:00
Magnus Jensen 07129edc66 Clean up Apple reconciler queries, no longer used (#46712)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Final part of Optimize apple reconciler queries.

It does include a slight logic change, when cleaning up for the setup
experience status and release DEP worker, checking for pending profiles.

🤑🤑🤑
<img width="106" height="35" alt="image"
src="https://github.com/user-attachments/assets/68498b1c-31cb-494c-9643-ed5da2602615"
/>


# Checklist for submitter

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

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

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

## Testing

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


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

* **Refactor**
* Move Apple MDM profile and declaration reconciliation to
batched/scheduled processing.
* Stop immediate bulk-updating of pending host profiles after
creating/editing profiles or declarations; Android remains synchronous
while Apple/Windows are deferred.

* **New Features**
* Added targeted per-host pending-profile detection for Apple devices to
improve reconcile accuracy.

* **Tests**
* Reworked and expanded Apple MDM reconciliation tests; removed
legacy/obsolete batch tests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 11:43:16 +02:00
Victor Lyuboslavsky 02d1738d0e Fixes from Konstantin's code review (#46701)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #41683



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

* **Refactoring**
* Replaced ad-hoc string checks with standardized enrollment-status
constants across platforms.
  * Centralized Android wipe validation into a single reusable check.

* **Bug Fixes**
* Updated Apple lock and wipe validations to use standardized
enrollment-status values.
* Fixed pending-device handling during Apple device sync to rely on the
centralized status representation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 01:13:27 -05:00
3c4bcee202 Fix "400 bad request" from SCEP PKIOperation when base64 message contains "+" (#43319)
Closes #45291

**Related issue:** none

## Problem

Apple MacOS devices fail SCEP enrollment with a 400. The proxy sees the
request arrive with `+` signs in the base64 payload:

```
request_uri: /mdm/apple/scep?operation=PKIOperation&message=MIA...MokYg+nl4TGkZi...k0+BJ/...
```

Fleet logs show those `+` signs are interpreted as spaces, and the
decode fails:

```
component=http-mdm-apple-scep method=GET status=400
err="failed to base64 decode message: illegal base64 data at input byte 375:
     ...MokYg nl4TGkZi...k0 BJ/..."
```

## Root cause

`message()` in `server/mdm/scep/server/transport.go` reads the query
parameter via `r.URL.Query()`, which internally calls
`url.QueryUnescape` and converts every `+` to a space.

The bug is present on `main` as of 2026-04-09.

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

* **Bug Fixes**
* Fixed SCEP PKIOperation handler so base64 payloads with `+` characters
are decoded correctly (no longer treated as spaces).
* **Tests**
* Added regression tests ensuring GET PKIOperation works with literal
`+` and percent-encoded `+` in the query message.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/43319?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Sharon <sharon@fleetdm.com>
2026-06-04 20:21:26 -04:00
Sharon Katz 1b42e2276c Fix ListVulnerabilities cursor pagination with ambiguous column names (#45983)
Closes #45843

## Summary

- Table-qualify column names in `vulnerabilitiesAllowedOrderKeys` so
they resolve correctly in both `ORDER BY` and cursor `WHERE` clauses
- `cve` was ambiguous between `vhc.cve` and `cm.cve`
- `hosts_count` and `cve_published` were SELECT aliases not valid in
WHERE scope
- Also fixed `host_count_updated_at` / `hosts_count_updated_at` which
had the same alias issue

## Reproduction

### Bug (before fix)

The `ListVulnerabilities` query joins `vulnerability_host_counts vhc
LEFT JOIN cve_meta cm`. When cursor pagination appends `WHERE <column> >
?`, three order keys fail:

| `order_key` | Old column value | MySQL error |
|-------------|-----------------|-------------|
| `cve` | `cve` | `Error 1052: Column 'cve' in where clause is
ambiguous` (exists on both `vhc` and `cm`) |
| `hosts_count` | `hosts_count` | `Error 1054: Unknown column
'hosts_count' in 'where clause'` (SELECT alias, not a real column) |
| `cve_published` | `cve_published` | `Error 1054: Unknown column
'cve_published' in 'where clause'` (SELECT alias for `cm.published`) |

Reproduced locally by running the raw SQL the old code would generate:

```sql
-- BUG 1: ambiguous
... WHERE vhc.host_count > 0 AND cve > 'CVE-2023-0002' ORDER BY cve ASC;
-- ERROR 1052 (23000): Column 'cve' in where clause is ambiguous

-- BUG 2: alias not valid in WHERE
... WHERE vhc.host_count > 0 AND hosts_count > 10 ORDER BY hosts_count ASC;
-- ERROR 1054 (42S22): Unknown column 'hosts_count' in 'where clause'

-- BUG 3: alias not valid in WHERE
... WHERE vhc.host_count > 0 AND cve_published > '2020-01-01' ORDER BY cve_published ASC;
-- ERROR 1054 (42S22): Unknown column 'cve_published' in 'where clause'
```

### Fix

Changed the allowlist values from bare names/aliases to table-qualified
actual column names:

| `order_key` | Before | After | Why |
|-------------|--------|-------|-----|
| `cve` | `cve` | `vhc.cve` | Ambiguous: both `vhc` and `cm` have a
`cve` column |
| `cve_published` | `cve_published` | `cm.published` | SELECT alias, not
a real column; invalid in WHERE |
| `hosts_count` / `host_count` | `hosts_count` | `vhc.host_count` |
SELECT alias for `vhc.host_count`; invalid in WHERE |
| `hosts_count_updated_at` / `host_count_updated_at` |
`hosts_count_updated_at` | `vhc.updated_at` | SELECT alias for
`vhc.updated_at`; invalid in WHERE |

Table-qualified names work in both `ORDER BY` and `WHERE` clauses.

### Manual verification (after fix)

Started a local Fleet server (`--dev --dev_license`), seeded 6
vulnerability entries, and hit all three previously-broken API calls:

```
GET /api/v1/fleet/vulnerabilities?order_key=cve&order_direction=asc&per_page=3&after=CVE-2023-0002
--> 200 OK, returned CVE-2023-0003, CVE-2023-0004, CVE-2023-0005 (correct ascending order)

GET /api/v1/fleet/vulnerabilities?order_key=hosts_count&order_direction=asc&per_page=3&after=10
--> 200 OK, returned hosts_count=20, 30, 50 (correct ascending order)

GET /api/v1/fleet/vulnerabilities?order_key=cve_published&order_direction=asc&per_page=3&after=2020-01-01
--> 200 OK, returned 3 CVEs with publish dates after 2020-01-01
```

Regression checks (no breakage):
- `order_key=cvss_score` cursor pagination still works
- Page-based pagination (`page=0&per_page=3`) still returns correct
results with `has_next_results: true`

## Test plan

- [x] Added `testListVulnerabilitiesCursorPagination` integration test
covering all three broken order keys (`cve`, `hosts_count`,
`cve_published`)
- [x] Existing tests pass: sort, page-based pagination, team filter,
known exploit filter, count
- [x] Manual verification on local Fleet server (see above)

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

## Summary by CodeRabbit

## Bug Fixes

* Fixed cursor pagination for the vulnerabilities endpoint when sorting
by CVE, host count, or CVE publication date to prevent SQL errors and
ensure reliable result navigation.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45983?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 20:17:28 -04:00
Lucas Manuel Rodriguez 339af293be Fix tight install loop on continous automations feature (#46823)
**Related issue:** Resolves #45149 (adds to)

## 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**
* Throttle continuous policy automations to avoid repeated install
attempts within the policy update interval.

* **New Features**
* Install records now include an updated timestamp for accurate cooldown
decisions.
* Added tracking of recently verified VPP app installs to avoid
redundant re-installs.

* **Tests**
* New and updated unit and integration tests covering cooldown behavior
and VPP verification lookups.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 17:48:26 -03:00
Scott Gress 07df7c5cfd Track software deletions in GitOps (#46764)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #43729

# Details

Adds output to GitOps runs indicating which custom/FMA software packages
would be deleted. This involves adding a `deleted_packages` key to the
`/software/batch/:request_uuid` ("Get status of software batch-apply
request") API, which will be documented separately.

# 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
- [X] verified that a GitOps dry run produces one "would've deleted"
line per custom package / fma that would be deleted
- [X] verified that a GitOps real run produces one "deleted" line per
custom package / fma that was deleted
  - [X] verified that adding software is unaffected



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

* **New Features**
* GitOps batch software operations now report packages pending deletion:
dry-runs show "would've deleted" warnings and real runs show deletions;
apply flows surface per-package deletion messages.
* Empty payload dry-run now still reports pending deletions when
applicable.

* **Tests**
* Added integration and datastore tests validating deletion-warning
output, pending-deletion detection, and related result handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 13:11:49 -05:00
Scott Gress 10f65595f8 Update error message for GitOps exceptions violations (#46700)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45306 

# 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
<img width="1470" height="19" alt="image"
src="https://github.com/user-attachments/assets/726b1efe-176f-4460-a140-a1f571990010"
/>


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

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
* Enhanced GitOps exception enforcement error messages for labels,
secrets, and software to include a direct link to the Fleet settings
page where exceptions can be disabled. Users now receive actionable
guidance when enforcement is triggered, improving troubleshooting
efficiency and reducing time spent resolving configuration issues.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 09:50:04 -05:00
Noah Talerman 4b191314a9 Display names for API endpoints are inconsistent w/ API reference (#45721)
- Add @rachaelshaw as reviewer to every PR against the API endpoints
YAML
- "fleet-level X" v. "a fleet's X" 
  - Up to @rachaelshaw
2026-06-04 10:31:59 -04:00
Tim Lee 81807dd5a3 Fix TestTranslateCPEToCVE: replace deferred Docker CVE (#46807) 2026-06-04 07:45:02 -06:00
Konstantin Sykulev e8bd1d525a Android provision certificates before dependent profiles (#46759)
**Related issue:** Resolves #45022

# 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**
* Prevented intermittent Android profile failures during host/team
transfers by ensuring pending Android certificates are created for
transferred devices before dependent profiles are applied. Profiles now
apply reliably, including when devices are moved off a team.
* **Tests**
* Added and updated tests to cover Android certificate provisioning
during host transfers.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 20:46:08 -05:00
Victor Lyuboslavsky e20cedc8a0 fleetd Windows MDM wake (push vs poll) (#46594)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46567 and Resolves #46737 

Solution for the agressive polling:
- no WNS (although we could add it later as another avenue for
notifications)
- fleetd advertises a sync capability, persisted as
`mdm_windows_enrollments.fleetd_sync_capable`
- The management session relaxes the DMClient poll
(`poll_schedule_relaxed`)
- When an MDM command is queued, `has_pending_commands` flips, the next
orbit check-in returns `WindowsMDMSyncRequest`, and fleetd runs
`deviceenroller` to deliver it immediately
- older fleetd versions keep the 1-minute poll

Docs: https://github.com/fleetdm/fleet/pull/46780

Changes to osquery_perf and any additional changes after loadtesting
will be done in a separate PR.

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

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

## Database migrations

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

## fleetd/orbit/Fleet Desktop

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


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

* **New Features**
* On-demand Windows MDM sync: servers can request immediate delivery of
queued MDM commands to Windows clients; Orbit triggers client-side sync
on Windows.

* **Enhancements**
  * Orbit throttles per-device on-demand sync to avoid excessive runs.
* Server reconciles and persists device poll schedule (fast vs relaxed)
and exposes consolidated host MDM state (awaiting-configuration +
has-pending-commands).

* **Tests**
* Added tests covering host config state, pending-command flows,
poll-schedule toggling, and on-demand sync behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 17:38:14 -05:00
Jonathan Katz a3338d032e Self service categories - GitOps support (#46671)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46392 
A few things in this PR:
- updated the conversion from old default category to the new ones with
the emoji included that was introduced in the feature branch. It takes
into account what exists in the database now so if an admin wants to add
for example "Productivity" without the emoji as a category it won't get
overwritten.
- updated a few places to ignore missing categories rather than error
(what we do for adding a single FMA currently)
- updated permissions for "gitops" users 
- added everything needed for gitops, generate-gitops support using the
existing endpoints from the last PR.

Didn't add logs like "[+] applied X self service categories" since it
wasn't mentioned in the docs, but wouldn't be too hard to add.


# Checklist for submitter


## Testing

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

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

## 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)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
    - Currently missing, at least on this branch
2026-06-03 15:23:44 -04:00
Jordan Montgomery 356caea6fd 42508 Rename abm to ab in API (#46657)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #42508 

Renames abm/apple_business_manager to ab/apple_business in API and
fleetctl. Uses existing renameto logic with a slight twist: added
"inline" option to handle cases particularly where a single object tree
has renames in multiple versions so that we don't break backwards
compatibiility since the default behavior when you have multi-level
renames is a new/old split at the top level

# 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**
* Canonical Apple Business (AB) API endpoints and CLI:
/api/v1/fleet/ab_tokens, /api/v1/fleet/mdm/apple/ab_public_key, plus new
fleetctl get mdm-ab and fleetctl generate mdm-ab
  * New GitOps/config key: mdm.apple_business
* Admin UI updated to show Apple Business tokens with fleet-based
associations and updated labels

* **Deprecations**
* Legacy ABM endpoints, CLI aliases, and config keys remain supported
but emit deprecation warnings pointing to the new AB equivalents
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 14:58:17 -04:00
Lucas Manuel RodriguezandCopilot Autofix powered by AI 441e31c705 Move targets and secret variables to server/fleet/ (#46196)
Resolves #36087 (one of several PRs).

## Testing

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

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

* **New Features**
  * Dry-run support when creating secret variables.

* **Improvements**
* Standardized API models for secret-variables and targets for more
consistent behavior.
  * List secret variables now includes pagination metadata.
* More consistent error reporting across secret-variables and targets
APIs.
* Target search/count behavior refined: pre-selected built-in labels are
omitted as expected.

* **Tests**
* Integration tests updated to validate the new request/response
behavior and target-selection logic.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/46196?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

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

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-03 15:07:54 -03:00
Nico 956425613d Add icon_url to policy software automations (#46645)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46722

This PR modifies both the FE and BE so that we do not fire a single
request for each software policy automation row. Instead, we build the
custom icon url (if any) into the main `policies` endpoint response.
This also prevents 404ing when there's no custom icon uploaded for the
associated software title.

## Testing

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

#### Before (main branch)



https://github.com/user-attachments/assets/fa358e90-dc08-45e0-8c4d-b8a8b57a6c98

#### After



https://github.com/user-attachments/assets/4ca7b931-a10b-4d57-96b1-ba5a88e04de5



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

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

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

* **New Features**
* Policy automations now show software icons when available (custom
installer icons, VPP app icons, and patch icons), sourced from the
server with graceful fallback when missing.
* **Tests**
* Added/updated tests to verify icon propagation and rendering behavior
across policy lists and automation views.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 14:48:28 -03:00
Andrew Mellor d7d9a96aa3 Add combined include/exclude label targeting for MDM profiles (API and GitOps) (#46437)
**Related issue:** Resolves #45180

# 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

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

- [x] Confirmed that the fix is not expected to adversely impact load
test results


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

* **New Features**
* MDM profiles can combine label inclusion (include-all/include-any)
with exclusion (exclude-any) so you can target hosts by labels while
excluding specific labeled hosts.
* Profile validation now enforces a single include-mode and explicitly
rejects any label used in both include and exclude lists.

* **Bug Fixes**
* Deleting a label that’s referenced by an MDM configuration profile or
declaration is blocked and returns an error to prevent broken targeting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 15:24:33 +01:00