Commit Graph
4220 Commits
Author SHA1 Message Date
Lucas Manuel Rodriguez 04d773f10f Fix get policy by id endpoint and unify access in UI (#45048)
**Related issue:** Resolves
https://github.com/fleetdm/fleet/issues/44949.

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

## Testing

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

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

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

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

* **Bug Fixes**
* Policy retrieval now correctly enforces team authorization, preventing
unauthorized cross-team access and ensuring team policies are returned
properly.

* **New Features**
* UI uses a unified policy access path for viewing/editing policies,
improving consistency for inherited/team-scoped policies,
back-navigation, and fleet-name display (All fleets / No team).

* **Tests**
* Added unit and integration tests covering cross-team access rules and
that policy automation fields are populated when policies are returned.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-11 09:39:52 -03:00
Jonathan Katz d439cb1690 Fix missing deleted_policy activity for auto-cleaned patch policies (#45045)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44286

Unset `patch_software_title_id` rather than deleting the policy in
`BatchSetSoftwareInstallers`, so the orphaned policy gets picked up by
the `policiesToDelete` loop in `server/service/client.go:3121`. As a
result, the `deleted_policy` activity is now created properly, and
gitops dry/real runs also report the deletion:

```
dry run:
[-] would've deleted policy macOS - 010 Editor up to date
[-] would've deleted 1 policy

real run:
[-] deleting policy macOS - 010 Editor up to date
[-] deleting 1 policy
[-] deleted 1 policy
```

# Checklist for submitter

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

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

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

## Testing

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

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


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

* **Bug Fixes**
* Fixed missing deletion activity logs when patch policies are removed
via GitOps so policy deletion events are now recorded.

* **Behavior Changes**
* Batch-updating installers now retains obsolete patch policies but
clears their patch installer reference instead of deleting the policy.

* **Tests**
* Added integration coverage to verify deletion activities are emitted
and installer batch behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-09 00:33:00 -04:00
Magnus Jensen c85d40636e Fix gitops controls set criteria (#45007)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #NA

Found this while just browsing the codebase and testing some gitops
stuff.

# Checklist for submitter

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

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

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

## Testing

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

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

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed GitOps controls detection to correctly identify when controls
are set with specific configurations, including BitLocker PIN
requirements.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-08 22:43:09 +02:00
RachelElysia d2033df253 Fleet UI: Fix export button dependencies (#45020) 2026-05-08 15:32:37 -04:00
Juan Fernandez f60ce942f8 Make activity list end-date filter consistent (#38437)
Resolves #38437 

The list activities endpoint applied an implicit `created_at <= now` cap
only when `start_created_at` was set, leaving the upper bound unbounded
in every other case, this was changed so that we now apply that cap
unconditionally and override only when the caller passes an explicit
`end_created_at` (as peer the REST docs).
2026-05-08 15:29:59 -04:00
99babf436a Don't write the secret.txt when the secret is the dummy placeholder value (#45041)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44826

# 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

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

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


## fleetd/orbit/Fleet Desktop

- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [x] Verified that fleetd runs on macOS, Linux and Windows

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

* **Bug Fixes**
* Windows MSI builds now correctly exclude placeholder secret values
during installation, preventing unnecessary dummy configuration files
from being created.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-05-08 15:26:33 -04:00
Magnus Jensen ea3513a1e7 always assign profile to missing devices due to replica lag (#45008)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44980

# 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
- [ ] QA'd all new/changed functionality manually (Not, outside of tests
due to exercising replica lag is difficult)

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

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
* Improved reliability of device profile assignment by ensuring all
devices receive profiles consistently, even when replica lag affects
device synchronization from Device Enrollment Program services.

* **Tests**
* Added test coverage validating device profile assignment behavior
under replica lag scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-08 15:33:36 +02:00
Magnus Jensen 034691966f check push cert staleness after 5 minutes of in-memory cache time (#44919)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44376 

I opted for an in-memory cache here, as it's not a critical cache piece,
we are fine with the cache being different times on different containers
(just means some might rotate to the correct cert faster than 5
minutes).
It's also a small piece of work, rather than pulling in redis etc.

Verified that it now logs, if the cert is stale after a 5 minute
in-memory cache.
```
ts=2026-05-07T11:30:08Z level=info msg="push certificate is stale after re-checking" topic=com.apple.mgmt.External.34c4a9b0-6501-4ce6-afc6-32eac6420ee7 staleToken="\x90C\xe4K\xc6a\x97\xb5?\x1b\x9a\x04'\xe7b\x8d" newHash=".fP\xc7O7\xab\xab\x9d\x92\xd5#\xe4u\xe0\xf6"
ts=2026-05-07T11:30:08Z level=info component=apple-mdm-push msg="retrieved push cert" topic=com.apple.mgmt.External.34c4a9b0-6501-4ce6-afc6-32eac6420ee7
```

# 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**
* APNs push certificates now refresh in-memory when rotated; staleness
is detected using certificate checksums with a short grace window.

* **Tests**
* Added tests for certificate retrieval, staleness detection/refresh
behavior, and push-cert storage error handling.

* **Documentation**
* Updated docs to describe the APNs push-certificate refresh and
staleness behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-08 11:02:22 +02:00
Sharon Katz f3f830bd9d Fix GitOps failure when moving labels from global to fleet scope (#44983)
Closes #44950

## Local reproduction

Reproduced locally using a MySQL integration test against the local test
database. The test simulates the exact GitOps scenario from the issue:

1. Create a label and associate it with an MDM profile
2. Delete the label (FK `ON DELETE SET NULL` sets `label_id = NULL`)
3. Create a new label with the **same name** (simulates moving from
global to fleet scope)
4. Call `batchSetProfileLabelAssociationsDB` with the profile
referencing the new label

**Before fix** (code from `main`, unfixed):
```
$ MYSQL_TEST=1 go test -run "TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated" -v -count=1 ./server/datastore/mysql/...

=== RUN   TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_darwin
    Error: selecting existing profile labels: sql: Scan error on column index 1, name "label_id": converting NULL to uint is unsupported
=== RUN   TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_windows
    Error: selecting existing profile labels: sql: Scan error on column index 1, name "label_id": converting NULL to uint is unsupported
--- FAIL: TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_darwin (0.02s)
--- FAIL: TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_windows (0.02s)
FAIL
```

**After fix:**
```
$ MYSQL_TEST=1 go test -run "TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated" -v -count=1 ./server/datastore/mysql/...

=== RUN   TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_windows
=== RUN   TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_darwin
--- PASS: TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_windows (0.03s)
--- PASS: TestMDMShared/TestBatchSetProfileLabelAssociations/same_label_name_recreated_after_deletion_darwin (0.03s)
PASS
ok  github.com/fleetdm/fleet/v4/server/datastore/mysql  2.761s
```

## Code changes

When a label is deleted, MySQL's `ON DELETE SET NULL` foreign key
constraint automatically sets `label_id = NULL` in the profile-label
association row. The Go code then crashes trying to scan that NULL into
a `uint` field.

- **`server/datastore/mysql/mdm.go`** — Added `COALESCE(label_id, 0)` to
the SELECT in `batchSetProfileLabelAssociationsDB`, so that NULL
`label_id` values are returned as 0 instead of causing a scan error when
Go tries to read NULL into a `uint`.
- **`server/datastore/mysql/apple_mdm.go`** — Same `COALESCE(label_id,
0)` fix in `batchSetDeclarationLabelAssociationsDB`. Also added `OR
label_id IS NULL` to the DELETE statement to clean up broken rows,
matching the profile labels behavior from #42637.

Other queries in the same codebase (e.g.,
`listProfileLabelsForProfiles`) already use `COALESCE(label_id, 0)` —
these two were missed.

## Testing

- `same_label_name_recreated_after_deletion_{darwin,windows}` —
reproduces the exact bug: associates a profile with a label, deletes the
label (NULL label_id), creates a new label with the same name, and
verifies `batchSetProfileLabelAssociationsDB` succeeds, the broken row
is cleaned up, and the correct label association exists
- Full MDM test suite passes: `MYSQL_TEST=1 go test -run "TestMDM"
./server/datastore/mysql/...` (76s)
- `make lint-go-incremental` passes
2026-05-08 07:49:23 +02:00
Konstantin SykulevandCopilot Autofix powered by AI e15f37d4e0 Optimize OSV vulnerability scanning (#44684)
**Related issue:** Resolves #44391

# 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


I tested this locally 
number of ubuntu hosts: 6,252
average software per host: 2,302
distinct software items: 61,213
host_software rows: 14.4M
generates software_cve rows 305,826
OS sub-versions: 25

The time before my optimization **10m53s** down to **4m26s** the
optimization.

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

* **Chores**
* Optimized OSV vulnerability scanning to aggregate work by OS version
and batch lookups, reducing redundant queries for faster scans.

* **Refactor**
* Restructured scanning flow to process OS versions in batched chunks
with clearer logging and early exits when no work is required.

* **Tests**
* Added tests for querying, batching, source filtering, deduplication,
and empty-input behaviors.
<!-- 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-05-07 22:21:22 -06:00
Konstantin Sykulev 361a5a402e Creating product index to speed up vulnerability scanning (#44910)
**Related issue:** Resolves #44391

# 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

* **Documentation**
* Added release notes documenting vulnerability scanning performance
improvements

* **Refactor**
* Optimized vulnerability scanning performance through enhanced CVE
product matching efficiency

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-07 22:20:58 -06:00
Tim Lee dc0c7bd72f Recover stuck SCEP managed-cert state via matcher extension (#44691) 2026-05-07 11:52:25 -06:00
Juan Fernandez 2c7bb2f6eb Fix SSO invite acceptance error when accepting invitation (#34103)
Resolves #34103 

The SSO invite acceptance page submitted a create-user request without
the invitee's email, because it read `email` from the URL query string
which the invite email link never populates. To resolve this the email
was loaded by calling GET /api/_version_/fleet/invites/{token} endpoint.

As part of this fix, the ConfirmSSOInvite components were refactored
from 'classical' components to functional components.
2026-05-07 12:25:24 -04:00
Allen Houchins 83b746cc15 Create fleetctl pkg asset every release (#35089) 2026-05-07 10:04:07 -05:00
Juan Fernandez 292bab32f6 Clarify SMTP TLS error and surface STARTTLS toggle (#34104)
Resolves #34104 

When saving SMTP settings with SSL/TLS off, STARTTLS on, and SSL cert
verification on, the test-email send produced an opaque Go cert error
that gave users no actionable hint. The two TLS-related toggles also
live on different settings cards with no cross-reference, which made the
conflict hard to spot before hitting Save.
2026-05-07 10:24:18 -04:00
Andrew Mellor 119feeda02 42218 updated ios version number to include supplemental extra (#44727)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #42218

# 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

Note: Sim update included and validated with and without supplemental,
screen shots attached

<img width="760" height="87" alt="Host List"
src="https://github.com/user-attachments/assets/c55f0ace-a205-4242-95da-510e8e6ec4ad"
/>
<img width="1511" height="523" alt="Standard"
src="https://github.com/user-attachments/assets/74a42e57-9391-4ce0-8b0a-ad3de6ab4745"
/>
<img width="1505" height="526" alt="Supplimental"
src="https://github.com/user-attachments/assets/392fc603-c7a2-4d6f-8ae0-87767cab7e3c"
/>


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

* **New Features**
* iOS/iPadOS devices managed via MDM now include reported supplemental
OS version text (e.g., Rapid Security Response suffixes) in the
displayed OS version string.
* **Bug Fixes**
* Supplemental extras are validated; invalid values are ignored.
Combined version strings are length-limited and safely truncated.
* **Tests**
* Added tests for supplemental handling, validation, fallback, and
truncation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-07 15:16:31 +01:00
Nico d8a1ffae81 Clear stale broken label rows on profile batch upsert (#44847)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #42637

# 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

### Reproduction steps:

- Created Label X and Label Y as manual labels in the UI.
- Applied gitops referencing the labels. The specified profile
referenced Label X:

```yaml
macos_settings:
    custom_settings:
      - path: ../repro-42637-profile.mobileconfig
        labels_exclude_any:
          - "Repro Label X 42637"
```

- Manually ran a SQL query to update `label_id` to NULL.

<img width="712" height="46" alt="Screenshot 2026-05-06 at 6 19 51 PM"
src="https://github.com/user-attachments/assets/32f386c7-adf3-48e8-adee-03102831e556"
/>


- Re-ran gitops referencing Label Y in the profile config.

```yaml
macos_settings:
    custom_settings:
      - path: ../repro-42637-profile.mobileconfig
        labels_include_any:
          - "Repro Label Y 42637"
```

- Old row was preserved AND a new one was created (association to Label
Y):

<img width="709" height="68" alt="Screenshot 2026-05-06 at 6 22 07 PM"
src="https://github.com/user-attachments/assets/fe2c4644-eb95-45a0-a582-994ad88e45be"
/>

### Testing steps

- Re-built fleetctl with the fix applied and re-ran gitops, still
referencing Label Y for the profile.
- Confirmed the orphan row was deleted.

<img width="740" height="212" alt="Screenshot 2026-05-06 at 6 24 43 PM"
src="https://github.com/user-attachments/assets/da9e9461-c352-4266-80b8-625a98e055ec"
/>


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

## Summary by CodeRabbit

## Bug Fixes
* Fixed an issue where MDM configuration profiles would remain enforced
on hosts after their associated labels were deleted during fleetctl
gitops apply operations. Label associations are now properly cleared
when profiles are reapplied with updated targeting.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-07 16:10:15 +02:00
Juan Fernandez 0147f6cde2 Fix IdP department host vital missing when SCIM PATCH carries extra attrs (#41996)
Resolves #41996 

Some IdPs push SCIM PATCH operations that bundle `department` with other
RFC 7643 §4.3 enterprise attributes that Fleet does not store. Before
this change the SCIM library rejected those payloads with a 400 because
the schema only declared 'department'.

An environment variable was added (FLEET_DEBUG_SCIM_PAYLOADS) for aiding
in further debugging this if the issue persist.
2026-05-07 08:34:36 -04:00
Magnus Jensen 9d96d6c76a add script output to GitOps (#44728)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44082

# 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**
* Enhanced GitOps script logging: reports how many scripts would be
applied in dry‑run mode or were actually applied, with per-team and
per-fleet breakdowns.

* **Tests**
* Added test coverage validating logging output for both dry‑run and
real execution, ensuring reported script counts and per-team/fleet
messages are accurate.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-07 09:38:25 +02:00
Scott Gress 917ce99324 Allow disabling chart datasets: frontend (#44797)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** For #44077 

# 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.
n/a, unreleased

## Testing

- [X] Added/updated automated tests
- [ ] QA'd all new/changed functionality manually
### Manual QA — Chart disabling (frontend)

  Setup notes:
  - Test as a global admin and (where indicated) a fleet admin
  - Need a Premium deployment to test per-fleet behavior
  - Have at least one fleet (e.g. "Engineering") for fleet-scoped checks
- Be able to flip
`appConfig.features.historical_data.{uptime,vulnerabilities}` and the
equivalent per-fleet keys (via API or settings UI)

  #### Advanced settings page — `/settings/organization/advanced`

  - [ ] "Activity & data retention" subheading appears on the page
  - [ ] Section contains a "Disable hosts online" checkbox
  - [ ] Section contains a "Disable vulnerabilities" checkbox
  - [ ] Section is visible on Free tier
  - [ ] Section is visible on Premium tier
- [ ] With `historical_data.uptime = true` in appConfig, "Disable hosts
online" loads **unchecked**
- [ ] With `historical_data.uptime = false` in appConfig, "Disable hosts
online" loads **checked**
- [ ] With `historical_data.vulnerabilities = false` in appConfig,
"Disable vulnerabilities" loads **checked**
- [ ] Saving with "Disable hosts online" checked sends
`features.historical_data.uptime = false` in the `PATCH
/api/v1/fleet/config` payload (verify in network tab)
- [ ] Saving with "Disable vulnerabilities" unchecked sends
`features.historical_data.vulnerabilities = true`

  #### Per-fleet settings page (Premium only)

  - [ ] Fleet settings page shows an "Activity & data retention" section
- [ ] Section contains "Disable hosts online" and "Disable
vulnerabilities" checkboxes scoped to the active fleet
- [ ] On **Free** tier, the per-fleet TeamSettings page is not reachable
(and therefore the section is not visible)
  - [ ] On **Premium** tier, the section is visible to fleet admins
- [ ] Saving with "Disable vulnerabilities" checked sends
`features.historical_data.vulnerabilities = false` in `PATCH
/api/v1/fleet/teams/{id}` (verify in network tab)

  #### Per-fleet checkbox locks when global is disabled

- [ ] With global `historical_data.uptime = false`, fleet's "Disable
hosts online" is **disabled / non-interactive**
- [ ] Hovering the locked fleet checkbox shows the tooltip "Disabled
globally"
  - [ ] **Stored value preserved across lockout**:
    - [ ] Set fleet `historical_data.uptime = false` (saved)
- [ ] Then set global to `false` — fleet checkbox renders **checked but
disabled**
- [ ] Flip global back to `true` — fleet checkbox renders **checked and
interactive** (fleet's `false` survived the round trip)

  #### Confirmation modal on Save (both global and per-fleet)

- [ ] Loading with `uptime = true`, then checking "Disable hosts online"
and clicking Save → modal opens listing **"Hosts online"**
  - [ ] No PATCH is issued until the user confirms
- [ ] No-op save (page loaded with `uptime = false`, no changes, click
Save) → modal does **not** open
- [ ] Re-enable (page loaded with `uptime = false`, uncheck "Disable
hosts online", Save) → modal does **not** open; PATCH is issued
- [ ] Disabling **both** datasets at once → modal lists **both** "Hosts
online" and "Vulnerabilities"
- [ ] Modal "Save and disable" button issues the PATCH and modal closes
once it resolves successfully
- [ ] Modal Cancel closes the modal, no PATCH is issued, checkboxes
remain checked (form state unchanged, ready to retry or revert)

  #### Confirmation modal copy by scope

- [ ] Modal opened from Advanced page → body describes the change as
affecting the **entire Fleet deployment**
- [ ] Modal opened from fleet "Engineering" settings → body **references
"Engineering" by name** and describes the change as affecting **only
that fleet**

  #### GitOps mode lockout

  - [ ] With GitOps mode enabled, on `/settings/organization/advanced`:
    - [ ] "Disable hosts online" is disabled with the GitOps tooltip
    - [ ] "Disable vulnerabilities" is disabled with the GitOps tooltip
  - [ ] With GitOps mode enabled, on a fleet's settings page:
    - [ ] "Disable hosts online" is disabled with the GitOps tooltip
    - [ ] "Disable vulnerabilities" is disabled with the GitOps tooltip
- [ ] When **both** GitOps mode and "Disabled globally" would apply, the
fleet checkbox shows the **GitOps tooltip** (GitOps wins)

  #### Dashboard chart card — empty state

- [ ] With `appConfig.features.historical_data.uptime = false`, viewing
dashboard in "All teams" with the **uptime** dataset selected →
visualization area shows the **"Data collection disabled"** empty state
- [ ] Dataset selector, time range selector, and filter gear remain
visible **and functional** while the empty state is shown
- [ ] With global `vulnerabilities = true` but the active fleet's
`historical_data.vulnerabilities = false`, viewing the dashboard scoped
to that fleet with a vulnerabilities-driven dataset selected → empty
state shown
- [ ] With both global and fleet sub-keys `true` (or fleet sub-key
absent in All-teams scope) → visualization renders normally; empty state
does **not** appear
- [ ] Switching from a disabled dataset (A) to an enabled dataset (B)
replaces the empty state with B's visualization
- [ ] A dataset whose internal name has no `DATASET_CONFIG_KEY` mapping
renders normally (no empty state — implicitly enabled)

  #### Empty-state content

- [ ] When the empty state is rendered for the "Hosts online" dataset,
"Hosts online" appears as the dataset name
- [ ] Link text describes re-enabling collection (e.g. "Manage data
collection in Advanced settings")
- [ ] Empty state includes a link to `/settings/organization/advanced`
when viewing All Fleets as a global admin
- [ ] Empty state includes a link to the correct Fleet settings page
when viewing a specific fleet as a global or team admin
- [ ] Empty state includes no link or call to action when viewed as a
non-admin

  #### Activity feed rendering

- [ ] `enabled_historical_dataset` with `dataset = "uptime"`, `fleet_id
= null` → renders **"Enabled data collection for Hosts online."**
("Hosts online" bolded)
- [ ] `disabled_historical_dataset` with `dataset = "vulnerabilities"`,
`fleet_id = null` → renders **"Disabled data collection for
Vulnerabilities."**
- [ ] `enabled_historical_dataset` with `dataset = "uptime"`, `fleet_id
= 7`, `fleet_name = "Engineering"` → renders **"Enabled data collection
for Hosts online for the Engineering fleet."**
- [ ] `disabled_historical_dataset` with `dataset = "vulnerabilities"`,
`fleet_id = 7`, `fleet_name = "Engineering"` → renders **"Disabled data
collection for Vulnerabilities for the Engineering fleet."**
- [ ] `disabled_historical_dataset` with an **unknown** `dataset =
"policy_compliance"` → does **not** throw; renders **"Disabled data
collection for Policy compliance."** (raw key sentence-cased — `_` →
space, first letter capitalized)

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

* **New Features**
* Org- and team-level controls to enable/disable historical data
collection for "Hosts online" and "Vulnerabilities."
  * Updated chart label: "Hosts active" → "Hosts online."
* Confirmation modal and a disabled-state UI when data collection is
turned off; per-team confirmation flow to prevent accidental data loss.
* Activity feed now records enable/disable actions for historical
dataset collection with readable dataset labels and scope.

* **Tests**
* Added comprehensive tests for controls, confirmation flows, disabled
states, chart headings, and activity items.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-06 16:28:37 -05:00
Magnus JensenandLucas Manuel Rodriguez d3775bda86 Check device auth token individual before querying host tables on auth (#44817)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
Resolves #44816.

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

## Summary by CodeRabbit

* **Performance**
* Improved device authentication efficiency by optimizing token
resolution, reducing database load for both valid and invalid token
scenarios in Fleet Desktop.

* **Tests**
* Added comprehensive test coverage for device authentication fast-fail
scenarios, including handling of non-existent tokens, expired tokens,
and edge cases.

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

---------

Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
2026-05-06 16:55:35 -03:00
Victor Lyuboslavsky c79d33a3a6 Add support for SAN in Android certificate templates. (#44690)
2/3rds of this PR is OpenSpec and tests. Use OpenSpec files as a
reference (if needed). They're there to help the review, and not to be a
review surface themselves.

- Backend implementation for `subject_alternative_name` in certificate
templates.
- Includes schema migration, variable expansion, GitOps support.
- Limits SAN types to `DNS`, `EMAIL`, `UPN`, `IP`, and `URI`.

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

# 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] Checked schema for all modified table for columns that will
auto-update timestamps during migration.

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


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

* **New Features**
* Android certificate templates support Subject Alternative Name (SAN)
with validation (DNS, EMAIL, UPN, IP, URI), Fleet-variable substitution,
runtime expansion, and delivery; SAN use is gated by Premium license
  * GitOps now validates and includes SAN in Android certificate flows

* **Chores**
  * Database schema updated to store SAN on certificate templates
  * Changelog entry added

* **Tests**
* Added unit and end-to-end tests covering SAN validation, variable
expansion, and GitOps behavior
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-06 14:43:09 -05:00
Marko LisicaandCarlo e988dd4756 Support VPP apps from non-US App Store regions (#44368)
**Related issue:** Resolves #43846

---------

Co-authored-by: Carlo <1778532+cdcme@users.noreply.github.com>
2026-05-06 12:01:07 -04:00
Nico 55d63e9100 Dark mode tweaks: error pages text contrast, dropdown borders, table corners (#44771)
**Related issue:** N/A — ad-hoc dark-mode polish (revives fixes from the
closed #43675)

## Summary

- **Error pages (403/404/500)**: replaced hardcoded `#333` body text
with `$core-fleet-black` so the copy adapts to dark mode.
- **Dropdown menu border**: added border to `ActionsDropdown` ONLY in
dark mode (light mode already has a box-shadow which in dark mode is
basically not visible so it's hard to distinguish what's in front and
what's behind when opening a dropdown).
- **Table bottom-right corner**: tables such as UsersTable have the
Actions dropdown in the last cell, and I think this made the
bottom-right corner to be cut because of a missing border-radius on the
inner cell that matches the table's border radius.

# 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

| # | Before | After |
  |---|--------|-------|
| Not found page | <img height="700" alt="Screenshot 2026-05-06 at 3 43
44 PM"
src="https://github.com/user-attachments/assets/c52b7bf8-6c5e-4e2e-8635-6f660c59ee90"
/> | <img height="700" alt="Screenshot 2026-05-06 at 3 35 03 PM"
src="https://github.com/user-attachments/assets/e92c324f-92a9-4e5e-a048-ab2b1d3c87a3"
/> |
| Access denied page | <img height="700" alt="Screenshot 2026-05-06 at 3
43 58 PM"
src="https://github.com/user-attachments/assets/9093f51a-e8ce-495b-9820-37ab5a7ff4cf"
/> | <img height="700" alt="Screenshot 2026-05-06 at 3 34 54 PM"
src="https://github.com/user-attachments/assets/3b9fe930-0ba1-4d48-824b-1b2cda713211"
/> |
| ActionsDropdown border + Table bottom corners (*) | <img height="700"
alt="Screenshot 2026-05-06 at 3 46 35 PM"
src="https://github.com/user-attachments/assets/c16b5a52-4746-4603-9f26-92be82f24225"
/> | <img height="700" alt="Screenshot 2026-05-06 at 3 31 33 PM"
src="https://github.com/user-attachments/assets/0a77cc95-40c4-43d2-9c6b-24c81782b275"
/> |
  
(*) Note that in the Users table, which has the Actions dropdown, the
right bottom corner is cut because the inner element doesn't respect the
table's border radius. Fixed this by adding the same border-radius to
that cell.

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

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed a display issue where data table bottom-right corners were being
cut off, ensuring complete visibility of table content.
* Improved dark mode contrast and readability on error pages (403, 404,
and 500 errors).

* **New Features**
* Added visual borders to dropdown menus for improved clarity and user
interaction feedback.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-06 16:41:46 +02:00
Nico fd3ec5a9aa Add SVG support for custom organization logos (#44748)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Follow-up to #44390 (BE/FE) and #44550 (GitOps).
Parent story #39016.

## Summary

Accepts `.svg` for organization logo uploads in addition to
PNG/JPEG/WebP, with strict server-side validation since SVGs can carry
scripts.

# 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/318d320e-ff78-41fe-ad3a-55d6dace8dc0



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

* **New Features**
* Organization logos now accept SVG in addition to PNG, JPEG, and WebP.
  * Stored SVG logos are re-validated when served.

* **Security**
* Server applies strict SVG sanitization to block scripts, unsafe
elements, event handlers, and unsafe URL schemes.
* SVG logo responses include headers to prevent content-type sniffing
and restrict execution.

* **Tests**
* Added tests covering SVG detection, validation, allowed/rejected
cases, and serving behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-06 15:20:53 +02:00
Magnus Jensen 7e8994d6db CSAH: clear state on ABM re-enrollment (#44722)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #43945 

# 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**
* Configurable option to preserve past host activity history during
Apple Business Manager re-enrollment.
* Re-enrollment can perform a targeted reset of host MDM state and
upcoming activities when preservation is disabled.
* Token-update flow now conditionally triggers the reenrollment reset
based on device/migration state and the preserve flag.

* **Bug Fixes**
* Host vitals and host-scoped data are cleared on ABM re-enrollment when
preservation is disabled.
* Reset is skipped during specific migration scenarios to avoid
disruption.

* **Tests**
* Added tests and mocks validating reset behavior, the preservation
flag, and migration-based skip logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-06 09:57:58 +02:00
Carlo b9933f45a2 Fix gitops 500 when software title icon bytes are missing (#44735)
Fixes #43511
2026-05-05 18:47:16 -04:00
Lucas Manuel RodriguezandCopilot Autofix powered by AI e9334bc666 Update changelog for fleetd 1.55.0 release (#44733)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved error handling for Windows registry enumeration to prevent
failures from malformed entries.

* **Chores**
* Removed debugging symbols from Orbit and Fleet Desktop executables for
optimized builds.
* Updated macadmins/osquery-extension dependency to v1.4.1, adding
network_quality table support.
  * Updated Go runtime to version 1.26.2.
<!-- 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-05-05 19:18:08 -03:00
Sharon Katz 1c522097d0 Fix missing GitOps label validation for invalid field combinations (#44410)
**Related issue:** Closes #34229

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

---

`fleetctl gitops` silently accepted labels with invalid parameter
combinations (e.g. manual labels with query/criteria/platform). Added
per-type field validation in a centralized
`fleet.ValidateLabelMembershipFields` function, called from the GitOps
parser, `ApplyLabelSpecs`, and `NewLabel`.

| Type | Allowed | Now rejects |
|------|---------|-------------|
| `manual` | `name`, `description`, `hosts` | `query`, `criteria`,
`platform` |
| `dynamic` | `name`, `description`, `query`, `platform` | `criteria`,
`hosts`; validates platform value |
| `host_vitals` | `name`, `description`, `criteria` | `query`,
`platform`, `hosts` |

### Automated tests

- `TestLabelInvalidFieldCombinations` in `pkg/spec/gitops_test.go` — 17
sub-tests covering every invalid combination per label type, plus 3
valid happy-path cases.
- `TestNewLabelFieldValidation` in `server/service/labels_test.go` — 4
cases for NewLabel validation.
- `TestApplyLabelSpecsManualLabelNilHosts` — 10 sub-cases for
ApplyLabelSpecs field validation.
- `TestWhenCreatingNewLabelsPlatformIsValidated` — platform validation
across NewLabel and ApplyLabelSpecs.

All existing `pkg/spec` and `server/service` label tests pass.

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

* **Bug Fixes**
* Labels now reject invalid field combinations for manual, dynamic, and
host_vitals types with clear error responses instead of failing
silently.
* **Tests**
* Added comprehensive tests covering valid and invalid label
configurations across membership types.
* **Documentation**
  * Changelog entry describing the behavioral fix.  
* **Chores**
* Removed an unnecessary platform constraint from a label configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---

### Manual test results

Ran against a local Fleet server with the built binary.

**API - NewLabel (POST /api/latest/fleet/labels)**

| Test | Input | Expected | Result |
|------|-------|----------|--------|
| 1 | manual + platform=darwin | 422, field=`platform` | PASS |
| 2 | dynamic + platform=invalidplatform | 422, field=`platform` | PASS
|
| 3 | dynamic + platform=darwin + query | 200 | PASS |
| 4 | manual (no platform) | 200 | PASS |
| 5 | host_vitals + platform=darwin | 422, field=`platform` | PASS |
| 6 | dynamic + whitespace-only query | 422, field=`query` | PASS |

**API - ApplyLabelSpecs (POST /api/latest/fleet/spec/labels)**

| Test | Input | Expected | Result |
|------|-------|----------|--------|
| 7 | manual + query | 422, field=`query` | PASS |
| 8 | dynamic + hosts | 422, field=`hosts` | PASS |
| 9 | valid dynamic | 200 | PASS |

**Round-trip: get labels --yaml then apply**

| Test | Scenario | Result |
|------|----------|--------|
| 10 | Legacy manual label with platform=darwin in DB | Platform
stripped from YAML, re-apply succeeds — PASS |
| 11 | Dynamic label with platform=darwin | Platform preserved in YAML,
re-apply succeeds — PASS |

**GitOps parser (fleetctl gitops --dry-run)**

| Test | Input | Result |
|------|-------|--------|
| 12 | manual + query + platform + criteria | All 3 errors surfaced at
once — PASS |
| 13 | valid manual label | No validation errors — PASS |
| 14 | dynamic + invalid platform | Error surfaced — PASS |

---

### Code walkthrough

**`server/fleet/labels.go`** — Added
`ValidateLabelMembershipFields(*LabelSpec) *InvalidArgumentError`. This
is the single source of truth for label field validation, returning
field-specific errors (`platform`, `query`, `criteria`, `hosts`). Lives
here because this package defines the label types both callers import.
Also uses `strings.TrimSpace` to reject whitespace-only queries.

**`server/service/labels.go`** — Three changes: (1) Removed the early
blanket platform check from `NewLabel` that ran before the membership
type was known. (2) Added `ValidateLabelMembershipFields` call in
`NewLabel` after type inference, so the API rejects invalid combos at
creation time. (3) Replaced three incomplete inline checks in
`ApplyLabelSpecs` with a single call to the centralized function, using
`err.WithStatus(422)` to preserve field-specific error shape in the API
response.

**`pkg/spec/gitops.go`** — Replaced the inline validation switch and a
standalone `ValidLabelPlatformVariants` check with a call to
`ValidateLabelMembershipFields`. Unwraps the returned errors
individually into `multiError` so all validation problems are reported
to the user at once.

**`cmd/fleetctl/fleetctl/generate_gitops.go`** — Gated platform emission
on `LabelMembershipTypeDynamic` so legacy manual/host_vitals labels with
a stored platform don't produce YAML that fails re-import.

**`cmd/fleetctl/fleetctl/get.go`** — Added `stripMismatchedLabelFields`
which clears type-inappropriate fields (query, platform, criteria,
hosts) per membership type before YAML output. Called in both code
paths: listing all labels and fetching a single label by name. Ensures
the `get labels --yaml` → `apply` round-trip works for legacy data.

**`server/datastore/mysql/labels.go`** — Added missing `l.criteria`
column to `GetLabelSpec` SELECT, matching `GetLabelSpecs`. Without it,
host_vitals labels fetched by name lost their criteria in the YAML
output, causing re-import to fail with the new validation.
2026-05-05 16:19:41 -04:00
Juan Fernandez 7088dfa32c Add include_all label scope to GitOps and fleetctl (#41566)
Resolves #41566 

Wires labels_include_all to GitOps and fleetctl for policies and reports.
2026-05-05 15:13:22 -04:00
Scott Gress e72c38ad60 Allow GitOps user to list software (#44721)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44696

# 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
- [X] reproduced issue on main branch (with software exceptions on and
policies with software automation, `fleetctl gitops` failed for a gitops
user with a 403)
- [X] verified issue fixed on this branch -- `fleetctl gitops` synced
successfully

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**
* Expanded GitOps permissions to read and list software inventory,
software titles, installable software, and maintained apps at both
global and team scopes; adjusted related read behaviors and
capitalization in messaging.
* **Tests**
* Updated and added authorization and integration tests to reflect the
new GitOps read/list behavior across software-related and maintained-app
endpoints, including team-scoped scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-05 13:27:57 -05:00
Magnus Jensen b6ffd30c6f fix UI elements in script library not respecting GitOps mode (#44743)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44196 



https://github.com/user-attachments/assets/4a013290-0089-4b98-86a6-544ca26d1896


# Checklist for submitter

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

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

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

## Testing

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

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

* **Bug Fixes**
* Script library UI now respects GitOps mode: editor is read-only and
save actions are disabled when enabled.
* Action buttons no longer inadvertently propagate clicks, preventing
unintended interactions in the script list.

* **Tests**
* Added tests verifying GitOps-mode behavior for edit/delete/download
actions and download handling without external calls.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-05 18:56:18 +02:00
Nico f2b2e23b0a GitOps changes for custom org's logo uploads (#44550)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44333

# 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. Also added some integration tests
as a follow-up of the first PR
(https://github.com/fleetdm/fleet/pull/44390).

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

#### generate-gitops

- Branched off to main, no URLs set, then ran generate-gitops on this
branch. Deprecated keys gone, new keys present.

<img width="447" height="170" alt="nourls_new"
src="https://github.com/user-attachments/assets/61931615-d61b-44d3-8095-f7a2b9bd8871"
/>

- Branched off to main, set external URLs for both light and dark modes,
then ran generate-gitops on this branch. Deprecated keys gone, new keys
set with the external URLs.

<img width="637" height="471" alt="externalurl_main"
src="https://github.com/user-attachments/assets/c3782756-acc2-4b99-812d-86e145f11ad5"
/>

<img width="459" height="168" alt="externalurl_new"
src="https://github.com/user-attachments/assets/aa2d8825-3c47-40ba-ab91-bb8202afe81a"
/>

- Within this branch, after uploading a custom logo for light mode, ran
generate-gitops. The logo was saved in lib/org_logo/light.webp

<img width="1510" height="639" alt="Screenshot 2026-05-04 at 4 06 59 PM"
src="https://github.com/user-attachments/assets/13318c24-8fa4-4e29-b629-ff723d4afe5a"
/>
<img width="786" height="172" alt="Screenshot 2026-05-04 at 4 07 30 PM"
src="https://github.com/user-attachments/assets/b46bd1df-7dcd-4489-b7da-4cbad77b25b8"
/>


#### gitops

- Applied gitops with two external URLs. Verified in the UI that those
are still present

<img width="944" height="189" alt="Screenshot 2026-05-04 at 7 54 53 AM"
src="https://github.com/user-attachments/assets/a34813ca-beb1-403e-9793-d42cc9c72f8b"
/>
<img width="637" height="259" alt="Screenshot 2026-05-04 at 8 01 04 AM"
src="https://github.com/user-attachments/assets/74c2cd56-ab1d-4ddd-9b8e-22c49e9ae9d5"
/>

- Applied gitops with "" as the URLs to clear them. Verified the default
fleet logo is shown.

<img width="460" height="201" alt="Screenshot 2026-05-04 at 8 15 11 AM"
src="https://github.com/user-attachments/assets/dcbafea3-b4ea-44aa-9045-08c4f5a64e98"
/>
<img width="648" height="269" alt="Screenshot 2026-05-04 at 8 15 50 AM"
src="https://github.com/user-attachments/assets/451a28f9-e929-4b84-93d3-a7dd9afd5eca"
/>

- Applied gitops with a custom logo for light theme, using
**org_logo_path_light_mode**:

<img width="948" height="207" alt="Screenshot 2026-05-04 at 4 10 05 PM"
src="https://github.com/user-attachments/assets/b1418cd4-31cc-4e53-b566-9af11ec21970"
/>
<img width="774" height="168" alt="Screenshot 2026-05-04 at 4 10 35 PM"
src="https://github.com/user-attachments/assets/63f596eb-308f-4122-ad86-e1d718e9b525"
/>



## 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)
- See https://github.com/fleetdm/fleet/pull/43808.
- [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**
* GitOps support for uploading custom org logos (dark/light) via local
files.
* `fleetctl generate-gitops` exports Fleet-hosted logos as local files
and inserts path references.
  * New API endpoints to upload, delete, and fetch org logos.

* **Deprecated**
* Legacy logo keys consolidated into mode-specific URL keys
(`org_logo_url_dark_mode`, `org_logo_url_light_mode`).

* **Bug Fixes / Validation**
* Validation/error when both a path and URL are provided for the same
mode; file size and image-format checks enforced.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-05 18:18:08 +02:00
227e94de5b 🤖 Chore: remove deprecated appendListOptionsWithCursorToSQL (#44385)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44723

# Checklist for submitter

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

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

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

## Testing

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

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


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

* **Bug Fixes**
* Strengthened validation of sorting/order parameters across many list
and cursor-based endpoints — unsupported sort keys now return explicit
errors and prevent unsafe queries.
* Labels listing: label-list pagination query name changed; ordering by
host_count is rejected when host counts are disabled (validated at
request parsing).

* **Tests**
* Added/expanded tests covering allowed order keys, rejection of unknown
keys, and pagination behavior for multiple listing APIs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Lucas Manuel Rodriguez <lucas@fleetdm.com>
2026-05-05 10:26:47 -04:00
RachelElysia 0448ac1f95 Fleet UI: Fix dataset text alignment (#44659) 2026-05-05 08:50:18 -04:00
Nico b4a207fb5a Add ability to upload custom org logos (#44390)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44330, Resolves #44331

# 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. (I'd defer integration tests to a
separate PR since this one is pretty large already.)

- [x] QA'd all new/changed functionality manually. I've tested this on
both the setup flow and the organization settings page. I haven't had
the time to test this on other places where we render the logo (macOS
setup experience / MDM migration dialog).


https://github.com/user-attachments/assets/95d4eae5-3da6-40f4-98a1-8575b97d96b3

## New Fleet configuration settings

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

Will handle GitOps in a separate PR.

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

* **New Features**
  * Organizations can upload custom logos for light and dark modes.
* Registration and Org Settings support logo file upload, preview,
per-mode replace/delete, and validation (size & image formats).
* Activity feed records logo changes/deletions; site nav displays
uploaded logos per theme.
* File uploader/preview adds a Fleet logo graphic option and improved
logo validation.
  * Config/GitOps outputs now include separate dark/light logo fields.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-05 14:42:52 +02:00
Tim Lee 8d37ec690c Revert "Fix SCEP autorenew failing for offline hosts (#44250)" (#44535) 2026-05-04 13:33:42 -06:00
Sharon Katz beca71e674 Fix gitops dry-run to catch manual_agent_install + macos_script conflict (#44432)
**Related issue:** Resolves #34464

# Checklist for submitter

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

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

## Testing

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

---

## What

GitOps `--dry-run` was succeeding when `macos_manual_agent_install` was
set to `true` and a `macos_script` was configured under
`setup_experience`, but the actual GitOps run would fail with:

```
Couldn't add setup experience script. To add script, first disable macos_manual_agent_install.
```

## Why

The `manual_agent_install` conflict validation only existed server-side
in `ee/server/service/setup_experience.go:SetSetupExperienceScript()`.
The script upload call (`uploadMacOSSetupScript()`) was gated by
`!opts.DryRun` in `server/service/client.go`, so during dry-run the
upload was skipped entirely and the validation never fired.

## Fix

Added client-side validation in `server/service/client.go` at the point
where the YAML-parsed `MacOSSetup` struct is processed — before the
script file is validated and loaded. This check runs for **both dry-run
and real runs**, catching the conflict early. Two code paths were fixed:

1. **Team path** (~line 803): Checks `setup.ManualAgentInstall.Value`
when `setup.Script.Value` is set
2. **No-team path** (~line 2603): Checks
`macOSSetup.ManualAgentInstall.Value` when `macOSSetup.Script.Value` is
set

## How I reproduced the issue locally

### Prerequisites
- MySQL and Redis running via Docker: `docker compose up -d mysql_test
redis`

### Steps
1. Wrote an integration test
(`TestDryRunMacOSSetupScriptWithManualAgentInstallConflict`) that:
   - Creates a GitOps user and fleetctl config
   - Creates a bootstrap package server serving `testdata/signed.pkg`
   - Creates a `.sh` script file with `echo "setup script"`
   - Creates a **global config** YAML (minimal server settings)
- Creates a **team config** YAML with `macos_manual_agent_install:
true`, `macos_script: <path>`, and `macos_bootstrap_package: <url>`
   - Runs `fleetctl gitops --dry-run` and asserts it fails
   - Runs `fleetctl gitops` (no dry-run) and asserts it fails

2. Ran the test **before the fix** — confirmed the bug:
   ```
Dry-run error: <nil> ← BUG: should have failed
Real run error: ...status 422...first disable macos_manual_agent_install
← correctly fails
   ```

3. Applied the fix and re-ran — **both dry-run and real run now fail**
with the `macos_manual_agent_install` conflict error.

### Test command
```bash
MYSQL_TEST=1 REDIS_TEST=1 go test -v \
  -run TestIntegrationsEnterpriseGitops/TestDryRunMacOSSetupScriptWithManualAgentInstallConflict \
  ./cmd/fleetctl/integrationtest/gitops/... -count=1 -timeout 600s
```

Both sub-tests (team and no-team paths) pass. All related existing tests
continue to pass:
- `TestMacOSSetup`, `TestMacOSSetupScriptWithFleetSecret`,
`TestDeletingNoTeamYAML`, `TestDisallowSoftwareSetupExperience`

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

* **Bug Fixes**
* GitOps dry-run now correctly fails when a macOS setup configuration
combines manual agent installation with a provided setup script,
preventing false-positive dry-run success.

* **Tests**
* Added unit and integration regression tests to verify dry-run and
real-run rejection of conflicting macOS setup configurations for both
team-scoped and unassigned host scopes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-04 15:32:21 -04:00
Konstantin SykulevandCopilot 779cdd663b Periodic background job to cleanup Windows MDM command queue (#44458)
**Related issue:** Resolves #44190

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

## Testing

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

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

* **New Features**
* Added a periodic cleanup job that removes aged, acknowledged Windows
MDM command-queue entries to reduce write pressure during ACK
processing.

* **Bug Fixes**
* Pending-command detection now excludes already-ACKed commands from
dispatch; queue rows are retained after ACK and cleaned later.

* **Tests**
* Added and updated tests to validate cleanup behavior and revised
ACK/queue semantics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-04 11:32:45 -05:00
Jordan MontgomeryandCopilot c713ce6a65 Allow returning x509 PEM cert instead of PEM-encoded PKCS7 envelope from request_certificate endpoint (#44541)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44533 

Adds an option to return a PEM certificate from the request_certificate
endpoint, rather than the PKCS7 envelope an EST server returns. This
allows it to be more easily used in scripts without conversions, at the
(small) cost of among other things dropping the PKCS7 envelope which
could be signed by the server, etc(though the PEM cert itself should
also be)

# 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

* **New Features**
* The "Request a Certificate" endpoint can optionally return the issued
certificate as a PEM-encoded X.509 CERTIFICATE block instead of a
PEM-encoded PKCS#7 envelope.

* **Tests**
* Added comprehensive tests covering PEM conversion, tolerance for
base64 whitespace/newlines, error handling for malformed PKCS#7, and
multi-certificate envelope cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-04 09:51:50 -04:00
Juan Fernandez 2ee5404ed3 Validate label platform during gitops --dry-run (#42477) (#44594)
Resolves #42477 

Move the platform check into pkg/spec parseLabels so both --dry-run and
apply hit the same validation and surface the same error.
2026-05-04 07:18:07 -04:00
Juan Fernandez 376f602088 Fixed bug with about to expire CLI banner (#34924)
Resolves #34924

Updated the message shown on about to expire license to point to
https://fleetdm.com/learn-more-about/downgrading.
2026-05-04 07:17:08 -04:00
Juan Fernandez 706520c8ea Add include_all label scope UI to policies and reports (#41565)
Resolves #41565 

Surfaces the new include_all label scope on the policy and report (query) edit forms via a "Custom" target dropdown.
2026-05-04 07:16:09 -04:00
Martin AngersandMagnus Jensen c2dda6a16c Wipe host cancels all upcoming activities (#44323)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #40459 

# 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

Recording:
https://drive.google.com/file/d/1_XqLyy-oY-WnIa97R4t9HihiBq3Fui6n/view?usp=drive_link

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

* **New Features**
* Wiping a host now cancels all upcoming and queued activities for that
host in a single, atomic operation to avoid intermediate activations.

* **Bug Fixes**
* Wipe response handling now distinguishes success vs failure and
reliably cancels queued activities; datastore errors during host lookup
or cancellation are surfaced.
* Device lock/erase flows consistently update and propagate datastore
errors.

* **Tests**
* Added integration and datastore tests validating wipe clears upcoming
activities across macOS, Windows, Linux, and mixed-host scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Magnus Jensen <magnus@fleetdm.com>
2026-05-01 14:01:46 -06:00
Magnus Jensen 275b266ca1 produce failed enrollment renewal activity (#44511)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #41418 

# 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

To manually QA, I put an early return with `msg.Fail` in the
`mdm_scep.go` file under PKIOperation method, and then triggered a SCEP
renewal.

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

* **New Features**
* Activity logging for Apple MDM enrollment profile renewal failures to
improve auditing and diagnostics.
* Host display enhancements: include computer name and hardware model to
improve host identification in activities and UI.

* **Tests**
* Integration tests verifying enrollment renewal failure activity
creation, association to the correct host, and activity payload
contents.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-01 11:38:08 -06:00
Victor Lyuboslavsky de86536f42 Redis-backed cache for host-by-key lookups (#43936)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #43928 

This PR adds a Redis-backed cache in front of the two host-by-key
lookups on the agent auth paths.

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

## What changes

**Read path (osquery/orbit auth):**

- `LoadHostByNodeKey` and `LoadHostByOrbitNodeKey` now check Redis
before falling through to MySQL.
- Successful lookups are cached for 60s ± 10% jitter (configurable via
`FLEET_REDIS_HOST_CACHE_TTL`).
- `NotFound` results are cached for 5s as a negative entry, dampening
repeated probes for keys that
do not exist (deleted hosts whose agents are still polling, attacker
scans, retry storms).
- Concurrent lookups for the same key collapse into one DB query via
`singleflight`. The shared
query runs under a context detached from any one caller's deadline so
the leader giving up does
not abort the work for joiners. The shared query is itself bounded by a
30s timeout so a wedged
  DB call cannot pin the singleflight slot indefinitely.

**Write path (invalidations):**

- These methods now invalidate the cache after a successful inner call:
`UpdateHost`, `SerialUpdateHost`, `UpdateHostOsqueryIntervals`,
`UpdateHostRefetchRequested`,
`UpdateHostRefetchCriticalQueriesUntil`,
`UpdateHostIdentityCertHostIDBySerial`, `EnrollOsquery`,
`EnrollOrbit`, `NewHost`, `DeleteHost`, `DeleteHosts`,
`CleanupExpiredHosts`,
  `CleanupIncomingHosts`, `AddHostsToTeam`.
- `AddHostsToTeam`, `DeleteHosts`, `CleanupExpiredHosts`, and
`CleanupIncomingHosts` use a pipelined
batch invalidator so 10k-host operations stay in the millisecond range
instead of taking minutes
  of sequential round-trips.
- Inner-call errors are not invalidations: a failing write leaves cached
state intact.

**Configuration:**

- New flags `FLEET_REDIS_HOST_CACHE_ENABLED` (default `true`) and
`FLEET_REDIS_HOST_CACHE_TTL`
  (default `60s`).
- Server refuses to start if the cache is enabled with `TTL <= 0`.

**Observability:**

- Three new OTEL counters under the `fleet` meter:
  - `fleet.host_cache.lookups{result=hit|negative_hit|miss}`
  - `fleet.host_cache.errors{op=get|set|del}`
-
`fleet.host_cache.invalidations{reason=update|enroll|team|delete|cert}`
- A pre-built SigNoz dashboard ships in
`tools/signoz/host_cache_dashboard.json`.

# 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


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

* **New Features**
* Optional Redis-backed host lookup cache for osquery and orbit auth,
with automatic invalidation and metrics/monitoring dashboard.

* **Bug Fixes**
* Fixed host-removal batching so cache-related removals use correct
chunks.

* **Tests**
* Added comprehensive host-cache unit tests covering hits, negative
cache, invalidation, concurrency, and JSON round-trips.

* **Chores**
* New config flags to enable the cache and set TTL (default 60s ±10%
jitter).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-01 12:06:16 -05:00
Victor LyuboslavskyandCopilot 62b716cc4e Enable disk encryption when only Windows MDM is configured. (#44462)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44194 

# 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

* **New Features**
* Team-level disk encryption can be toggled when at least one MDM
platform (Windows or Apple) is configured, enabling BitLocker control
for Windows-only deployments.

* **Bug Fixes**
* Updates validation to reject disk-encryption changes only when no MDM
platforms are configured.

* **Tests**
* Added coverage for platform combinations and expected behavior,
including Apple-specific profile creation when applicable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-01 09:19:34 -05:00
Lucas Manuel Rodriguez 1e4a9f292f Add activities for user actions on labels (#44522)
Resolves #36976

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

## Testing

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

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

* **New Features**
* Label operations (create, edit, delete) now generate activities shown
in the activity feed with label and optional fleet context.
* Host label add/remove operations emit corresponding label edited
activities; duplicate label names are deduplicated.
* Label activity types are selectable/filterable in the activity
dashboard.

* **Tests**
* Added unit, integration, and UI tests covering label activity
emission, rendering, filtering, and GitOps label lifecycle scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-01 10:19:45 -03:00
Victor Lyuboslavsky 2723c132c2 Fixed GET /api/v1/fleet/commands timeout in large Fleet deployments (#44297)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44170 and Resolves #44422

Pagination is now pushed into each branch of the merged query, so
per-tick work scales with page size instead of total commands. The
Windows side was rewritten to avoid a disjunctive join that forced a
nested-loop plan. `per_page` is capped (default 10), `page` is capped,
and `order_key` is enforced against a closed allowlist on both code
paths. Cursor pagination is fixed and is the recommended way to traverse
beyond the page cap.

This PR improves but does not fix the use case of fetching commands from
all hosts. Deprecate usage without host_identifier:
https://github.com/fleetdm/fleet/pull/44392/changes

API doc updates: https://github.com/fleetdm/fleet/pull/44292

# Checklist for submitter

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

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] 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 pagination on MDM commands list: per_page defaults to 10 (max
1,000) and page is capped at 100; traversal beyond page 100 requires
cursor pagination via after.

* **Bug Fixes / Performance**
* Improved MDM command listing performance and de-duplication for large
queries; fixed SQL error when combining host identifier with cursor
pagination.

* **Validation**
* Requests exceeding pagination caps return 400; invalid sort keys
return 422.

* **Tests**
* Added tests for pagination boundaries, cursor behavior, sort-key
validation, and error responses.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-30 15:44:19 -05:00
Tim Lee 2d586cb2ff fleetctl vulnerability-data-stream to download OSV data (#44260) 2026-04-30 10:46:51 -06:00