Commit Graph
4367 Commits
Author SHA1 Message Date
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 CatalfamoandNoah Talerman 48fe442da0 Update CVE documentation to list Linux distributions supported (#46828)
**Related issue:** Resolves #45110


---------

Co-authored-by: Noah Talerman <noahtal@umich.edu>
2026-06-05 16:22:39 -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
Juan Fernandez eb42b22230 Fix custom variable modal clearing when switching browser focus
Fixes #44805

Fixed a bug where the "Add custom variable" modal would clear entered
values when switching focus to another browser tab or application window
due to network refetches.
2026-06-05 16:11:30 -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
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
Nico 99ebcf31f0 Stop 1Password autofill icon from interfering with Fleet UI form fields (#46808)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44854

This PR explicitly enables the 1Password autofill icon for credential
fields, such as the ones in the login form.
Made the decision to have `ignore1password=true` by default (less LOC
changed since the vast majority of inputs aren't credential fields).

Note: even though the Certificate Authority input fields contain some
kind of secret or credentials, I feel like these differ enough from one
another (+ these are usually admin-pasted values) that it didn't make
sense to have the 1PW autofill on them.

# 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



https://github.com/user-attachments/assets/c8539d8f-e0e3-4499-ae67-16cfd0f59e3a



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

* **Bug Fixes**
* Prevented the 1Password autofill icon from appearing on non-credential
inputs.
* Ensured explicit 1Password autofill handling for email/password fields
across login, registration, password reset, and account forms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 09:15:04 -03:00
Nico 2460ff63a2 Fix resizable read-only installer command in Add host modal (#46806)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44901

# 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

<img width="826" height="427" alt="Screenshot 2026-06-04 at 9 00 40 AM"
src="https://github.com/user-attachments/assets/a0b1d2fb-3077-4883-a69a-c37e6e81d3d7"
/>


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

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed the Add host modal so read-only installer command fields can no
longer be resized.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 09:09:00 -03: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
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
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
Scott Gress 9cf20fbab3 Fix preview config (#46677)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46560 

# 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
- updated preview test. This won't run in CI right now b/c we didn't
update fleetctl, but I ran it successfully locally
- [X] QA'd all new/changed functionality manually
- [x] on main, did `fleetctl preview` with the 4.86.0 tag and verified
that charts were disabled
  - [x] on this branch, did the same and verified charts were enabled 



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

* **Bug Fixes**
* Dashboard chart data collection (Hosts online and Vulnerability
exposure) is no longer disabled when starting preview mode.

* **Chores**
* Software inventory config moved to the current features flag so
historical chart data is preserved.

* **Tests**
* Added regression checks to ensure uptime, vulnerabilities, and
host-users historical data remain enabled in preview.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 09:49:47 -05:00
Kevin M. Cox 025c5b10a1 Dashboard: show each platform's percentage of total hosts in the "Hosts enrolled" tooltip (#46477) 2026-06-04 08:19:12 -05: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
RachelElysia 1d44256b17 Fleet UI: Allow DataSet value to wrap, apply to policy (#46733) 2026-06-03 15:17:27 -04:00
RachelElysia 6635bb7b27 Fleet UI: Script action buttons now keyboard accessible (#46720) 2026-06-03 15:15:55 -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
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
Juan Fernandez 7cf8190552 Changed semantics around api_endpoints init.
Fixes #46190

- Added a package init() to load the catalog from the embedded YAML
once.
- Init() now no longer runs any initialization logic just validation, so
it was renamed to Validate.
2026-06-03 10:13:11 -04:00
Juan Fernandez ad4ef6c309 Fix logout/login redirects in subpath deployments (#46715)
Fixes #46639

Hard-coded "/" and "/login" strings bypassed the URL prefix when Fleet
is deployed behind a reverse proxy at a subpath. Replaced with
PATHS.ROOT / PATHS.LOGIN, which embed URL_PREFIX, so redirects now land
at the correct subpath.
2026-06-03 10:12:48 -04:00
Juan Fernandez d246865a2a Fix root URL 404 in subpath deployments
Fixes #46640

The root IndexRedirect used an absolute path ("/dashboard"), causing
React Router to push /dashboard to history regardless of the URL prefix.
This made the app fall through to the 404 route when Fleet was deployed
at a subpath (FLEET_SERVER_URL_PREFIX). Removing the leading slash lets
React Router resolve the redirect relative to the mounted route.
2026-06-03 10:12:18 -04:00
Nico c0d39f7690 Easier-to-manage policy automations with continuous retry option (#46056)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #42651 

# 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

## 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 "Continuous" option for policy automations to re-run
script/software automations on every subsequent failure.
* Editable automations available directly from policy create, edit, and
details pages.
* New modal and field flows for managing automations (webhook/ticket,
calendar, conditional access) and a Patch automation CTA for patch
policies.

* **Improvements**
* Redesigned automations UI, table cell rendering, and list/footer
messaging for clarity.
* Various styling and layout refinements for consistent behavior and
overflow prevention.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 09:22:54 -03:00
Magnus Jensen d5e0c5d352 resend config profiles on no device mapping user (#46623)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #34668 

# Checklist for submitter

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

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

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

## Testing

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


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

* **Bug Fixes**
* Fixed profile resend behavior so configuration profiles are retried
using available identity attributes when a host has no linked IdP user
or the referenced IdP user is missing.
* Ensured profile resend markers are cleaned so pending resends behave
correctly after identity changes.

* **Tests**
* Improved test coverage to validate profile resend and status reset
when device mappings or identity links change.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 10:18:34 +02:00
Victor Lyuboslavsky fa7d928235 Remove unenroll pending and add Android COBO wipe to Free (#46653)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #41683 

Unenroll/wipe Android on Fleet Free:
https://www.youtube.com/watch?v=JvsD3WBcDgE

# 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**
* Android Lock, Wipe, and Clear passcode commands supported; Lock and
Clear for both personal (BYO) and company-owned (COBO) devices, Wipe for
COBO only.
  * Android COBO Wipe exposed in Fleet Free (UI and API).

* **Bug Fixes**
* Personal Android unenroll now removes only the work profile (personal
data preserved) and no longer shows a transient “wiping” status in the
UI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-02 18:59:13 -05:00
Victor Lyuboslavsky 59a673bc15 Added trace sampler to use OTEL in prod. (#46595)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44652 

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

# 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

## Database migrations

- [x] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).

## New Fleet configuration settings

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

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

* **New Features**
* Route-aware OpenTelemetry trace sampling with tiered default ratios
(very low for select high-volume routes, reduced rate for admin reads,
full sampling otherwise).
* Admin-only GET/PATCH /debug/trace_sampler to view and update sampling
ratios and a runtime "force full" toggle.
* Liveness probe endpoints (/healthz, /version, /metrics) are excluded
from tracing; settings propagate to replicas at runtime without restart.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-02 18:53:00 -05:00
Scott Gress 6d004b98bc Update error message in GitOps when unknown env vars are encountered (#46476)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44053

# 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**
* Error messages for undefined environment variables in GitOps
configurations now include clearer, actionable guidance with examples of
how to escape literal dollar-sign syntax (e.g., showing escaped forms).
This improves clarity when a variable is missing and helps users
distinguish between intended variable references and literal values,
reducing confusion.

<!-- 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/46476?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-02 14:48:06 -05:00
Nico a335b3e6d4 Fix VPP API retry recursion causing server OOM (#46659)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46656

`server/mdm/apple/vpp.do` retried transient Apple errors by **calling
itself recursively**, with the rate-limit branch nesting `retry.Do`
inside `retry.Do`.

This change replaces the recursion with a single retry loop (respecting
the prior 1 initial attempt + 3 retries), closes each response before
retrying, honors Apple's `Retry-After` capped at 30s so that a
multi-minute value can't block a synchronous request, and threads
`context` through the VPP calls so the backoff is cancellable. The retry
timings are otherwise unchanged from before.

Following @sgress454 suggestion, I considered routing this through the
shared `retry.Do` helper (a single attempt wrapped in `retry.Do` + an
error filter) but figured out that:
- retry.Do` owns its own wait schedule and its error filter returns an
outcome enum rather than a duration, so it can't honor Apple's
per-response `Retry-After` value.
- also, I'd have to change the `retry` package to receive an extra `ctx`
param so that the backoff is context-aware (which IMHO is more blast
radius than this incident fix should carry).

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`.
- [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

**What was verified.** The new automated test cannot run against `main`
(the fix changes the VPP function signatures and adds the retry knobs),
so to confirm the actual failure mode I checked out `main` and ran a
small repro that drives the VPP client against an Apple endpoint that
always returns the rate-limit error. On `main`, the call **never
returns** — `do()` recurses without bound — and the repro times out:

```
--- FAIL: TestReproUnboundedRecursionOnMain (10.00s)
    zz_repro_main_test.go:30: AssociateAssets did NOT return within 10s — unbounded retry recursion in do() on main
FAIL
FAIL	github.com/fleetdm/fleet/v4/server/mdm/apple/vpp	10.642s
```

On this branch the same scenario returns a bounded error promptly. That
behavior is covered by the new `TestDoRetryIsBoundedAndNonRecursive`
(bounded rate-limit retries, `Retry-After` honored-but-capped, and
context cancellation), and the full `server/mdm/apple/vpp` package
passes.
**I did not perform an end-to-end QA against a live Apple endpoint**.


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

* **Bug Fixes**
* Fixed a server out-of-memory crash that occurred when Apple VPP API
repeatedly returned transient errors during VPP operations, including
app installs, user registration, and license seat releases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-02 16:18:02 -03:00
Carlo cbf2be25ed Fix host software label scope after FMA replacement (#46649)
Resolves #43863
2026-06-02 15:09:21 -04:00
Magnus Jensen a4d1cfab1f CSUD: Add validation for OS Update profiles and OS updates being configured (#46545)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45282

# 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

* **New Features**
* Deploy custom OS update configuration profiles for Apple
(macOS/iOS/iPadOS) and Windows; tracks and enforces one custom OS‑update
profile per scope.

* **Improvements**
* Prevent changing OS update settings when a custom profile exists;
returns guidance to remove the custom profile first.
* Batch upload now detects OS‑update payloads and enforces license
requirements.
  * UI error handling surfaces API-specific messages.
* FileVault control separated from OS updates and gated behind a
configurable flag/license.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-02 17:28:58 +02:00
Victor LyuboslavskyandKonstantin Sykulev ea5b15699e windows_mdm: link enrollment row via DevDetail at first management session (#46268)
Closes the race after Windows BYOD MDM enrollment (Settings > Access
work or school > Connect) where mdm_windows_enrollments.host_uuid stayed
empty for ~10s while osquery's distributed-read cycle ran
directIngestMDMDeviceID Windows. During that gap any server-side lookup
keyed on host UUID via MDMWindowsGetEnrolledDeviceWithHostUUID returned
NotFound.

processIncomingMDMCmds now inspects unlinked enrollments on every
management session: it parses any incoming Results for
./DevDetail/Ext/Microsoft/SMBIOSSerialNumber, looks up the Windows host
by hardware_serial, and updates host_uuid. If still unlinked after
processing the incoming message, it appends a Get for that LocURI to the
response so the device replies on the next round-trip. The Get is
idempotent and reinjected each session until linkage succeeds.

The post-link UPN/SCIM/DEP bookkeeping previously inlined in
directIngestMDMDeviceIDWindows is extracted into a shared helper
(osquery_utils.LinkWindowsHostMDMEnrollment) so both the new SyncML path
and the osquery direct-ingest backstop run it exactly once per linkage.

New datastore method WindowsHostLiteByHardwareSerial does a Windows-only
serial lookup and returns NotFound when two Windows hosts share a
serial, so we never mis-link on virtualization-shared SMBIOS values.

For Autopilot and Entra-during-OOBE the host record does not exist until
fleetd installs later in ESP, so the osquery backstop and the name-based
fallback in setup_experience.go remain in place for those flows.

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

# 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**
* Immediately link Windows BYOD MDM enrollments to host records during
the first management session when a device serial is present, and prompt
the device to resend serial info if missing.
* Detect and ignore placeholder/ambiguous hardware serials to avoid
incorrect host linking.
  * Reduce noisy warnings for internal-sync command IDs.

* **Bug Fixes**
* Resolve a race causing Windows MDM enrollments to remain unlinked for
several seconds.

* **Tests**
* Added coverage for serial-based linkage, retry behavior, placeholder
detection, and internal-command ID handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konstantin Sykulev <konst@sykulev.com>
2026-06-02 09:41:07 -05:00
Victor Lyuboslavsky 0858580ff5 Refactored ListHostSoftware and ModifyAppConfig for nilaway (#46555)
Refactored `ListHostSoftware` and `ModifyAppConfig` into smaller helpers
so nilaway can analyze them for nil-pointer dereferences

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

Refactoring. No functional 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.

## Testing

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


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

* **Refactor**
* Improved host software listing by consolidating assembly, merging,
deduplication, and out-of-scope filtering into dedicated helpers for
more reliable and maintainable results.
* Streamlined app configuration updates by extracting conditional-access
(Okta) validation into a focused helper, improving validation
consistency and error reporting.

* **Chores**
* Updated static analysis configuration: bumped a pinned plugin version
and removed a suppression rule that hid certain internal lint messages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-02 08:48:56 -05:00
Juan Fernandez 923d1a2e3d Fix FK constraint failure in RecordPolicyQueryExecutions when policy deleted mid-flight (#46587)
Fixes #40362

Use INSERT IGNORE in the sync path so that a policy deleted between
distributed query dispatch and result ingestion is silently skipped,
matching AsyncBatchInsertPolicyMembership which already handles this
race with the same approach.
2026-06-02 08:45:51 -04:00
5955a6f594 43116 fix Fedora wipe btrfs snapshots (#45704)
**Related issue:** Resolves #43116

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

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

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


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

* **Bug Fixes**
* Fedora/Linux wipe now removes Btrfs snapshots (including read-only)
before wiping so snapshots won’t persist.

* **UI**
* Linux-specific guidance and external links added to wipe dialogs and
wiped/failed-wipe activity items; wipe status tags suppressed for Linux
hosts.
* Activity entries include host platform to enable platform-specific
messaging.

* **Tests**
* Updated tests to cover Linux-specific wipe messaging, links, and
activity payloads.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Jordan Montgomery <elijah.jordan.montgomery@gmail.com>
Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com>
2026-06-02 10:14:02 +01:00
Victor Lyuboslavsky 56fe9ed6e1 Fixed the mdm_unenrolled activity not appearing in host details page (#46573)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46119 

New activities visible on host details page:
<img width="482" height="424" alt="image"
src="https://github.com/user-attachments/assets/8b8b33b2-c135-4061-b258-473fcc109d89"
/>

# 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**
* MDM unenrollment events now appear on the host activity timeline in
host details.

* **New Features**
* Host activity entries for MDM unenroll show platform- and actor-aware
messaging and appropriate action/icon visibility.

* **Tests**
* Added tests to verify rendering and messaging for various platforms
and actor presence.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-01 18:01:15 -05:00
Victor Lyuboslavsky 1072c852e8 Added support for validating Microsoft Entra v2 access tokens (#46416)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46388 

Video demo: https://www.youtube.com/watch?v=t3yuGh0kwP8
Docs PR: https://github.com/fleetdm/fleet/pull/46483

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

## New Fleet configuration settings

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**
* UI to add/remove Entra application (client) IDs for Windows automatic
enrollment; add/delete modals and list management.

* **Enhancements**
  * Activity feed entries for added/removed Entra client IDs.
* Entra client ID allowlist surfaced in GitOps and persisted config;
client IDs normalized (trim/lowercase) and de-duplicated.

* **Documentation**
* Note: from July 1, 2026 new on‑prem Windows MDM apps receive Entra v2
tokens with aud = client ID; v1 tokens remain supported.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-01 17:58:51 -05:00
Sharon Katz 7fb464abc4 Clean up policy query to use parameter binding for platform filter (#46604)
## Summary
- Refactored the conditional access policy query to use `CONCAT('%', ?,
'%')` with a bound parameter instead of string concatenation for the
platform `LIKE` clause, consistent with how other queries in this file
handle string filters.

## Test plan
- [ ] Verify conditional access policy lookup still returns correct
results for macOS/Windows hosts.
- [ ] Confirm no regression in policy filtering behavior.

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

## Summary by CodeRabbit

* **Chores**
* Improved platform filtering in conditional access policy queries to
enhance query reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-01 18:15:02 -04:00
Konstantin Sykulev 19f14c1c8c Corrected configuration profiles endpoint handler (#46580)
**Related issue:** Resolves #46283

# 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**
* Fixed an error in the "Get host's OS settings" API so it no longer
fails when only Android MDM is enabled.
* Configuration profiles endpoint now correctly responds when Android or
Windows MDM is the active platform, in addition to Apple MDM.

* **Tests**
* Added tests covering configuration profiles behavior across Apple,
Windows, and Android MDM configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-01 15:23:20 -05:00
Steven Palmesano b993da7967 Use new MDM status on hosts page and show tooltip; show "Not supported" for Linux (#46377)
**Related issue:** Resolves #46066

# 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**
* Corrected MDM status label in the hosts table so enrollment states
display accurately.
* Fixed platform handling so "Not supported" appears appropriately for
Chrome and Linux hosts.

* **New Features**
* Added a hover tooltip on the MDM status in the hosts table to show
additional context.

* **Style**
* Improved tooltip text wrapping to keep status names on a single line.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-01 13:16:56 -05:00
Konstantin Sykulev f619655a61 Certificate template duplicate name error (#46414)
**Related issue:** Resolves #44821

# Checklist for submitter

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

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

## Testing

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



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

* **Bug Fixes**
* Fixed inline validation to show duplicate certificate name errors even
when the conflicting certificate is on a different page.
* Improved server-side error handling during certificate creation to
better detect name conflicts and present clearer, focused feedback on
the Name field.

<!-- 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/46414?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-01 10:01:47 -05:00
Lucas Manuel Rodriguez 9032883b47 Fix fleetctl get fleets to use source of truth (DB) for software (#46480)
Resolves #44970 (1/2).

---

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [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**
* `fleetctl get fleets` / `get teams` now display software and setup
experience from authoritative software endpoints.
* Preserve literal setup_experience fields (avoid erroneous macos_setup
renames) when applying and when transmitting JSON for software entries.
* **Tests**
* Added regression tests and test helpers to ensure
software/setup_experience are sourced correctly and to prevent nil
panics in related tests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-01 11:41:34 -03:00
Juan Fernandez 66667c3248 Fix S3 carve cleanup never running and panic on empty carves (#43045) (#46462)
Resolves #43045 

Fixed a bug where the carve cleanup cron job called the MySQL
implementation instead of the S3-aware implementation on S3-configured
deployments, meaning expired carves were never marked as expired in S3.
Also fixed a panic in S3 carve cleanup that occurred when there were no
non-expired carves.
2026-06-01 10:11:49 -04:00