Commit Graph
1730 Commits
Author SHA1 Message Date
c5575e9d9a Add PSSO end to end integration tests (#48589)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #47171

Added integration tests for the fleet-psso feature and added PSSO
functionality to our MDM test client - idea being it is so tightly
integrated into the MDM side of things on the Apple side AND we ideall
want osquery-perf to be able to exercise it(coming in the next PR)

# Checklist for submitter

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

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

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

## Testing

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

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

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

* **New Features**
* Added Apple Platform SSO (PSSO) support for device registration,
password login, key requests, and key exchange.
* Added a simulator/test device for exercising the full PSSO workflow
end-to-end.
* Made PSSO AASA development app IDs configurable and enhanced macOS
PSSO activity in performance testing (with new counters).
  * Improved local macOS Desktop packaging/signing configurability.

* **Bug Fixes**
* Strengthened PSSO token/crypto handling, including algorithm pinning,
key ID canonicalization, encrypted assertion `typ` validation, and
replay protection.

* **Tests**
* Added extensive crypto interoperability tests (including Apple
known-answer vectors) plus new end-to-end integration coverage.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Magnus Jensen <magnus@fleetdm.com>
2026-07-10 18:51:33 -04:00
078fbc0f40 Add Targeted platforms column and platform filter to Policies page (#44125)
- @noahtalerman: For the following quick win:
  - https://github.com/fleetdm/fleet/issues/23737

## Summary

Adds a "Targeted platforms" column and a platform filter dropdown to the
Policies page (`/policies/manage`), matching the pattern already used on
the Reports page (`/queries/manage`, `ManageQueriesPage`).

### Frontend
- New non-sortable **Targeted platforms** column rendered via
`PlatformCell`, sourced from each policy's comma-separated `platform`
field.
- New platform filter dropdown (All / macOS / Windows / Linux /
ChromeOS) wired as a `customControl` on the Policies table, alongside
the existing automation filter. Selecting a value pushes a new URL (not
a replace), resets `page` to 0, and updates the `platform` query param.
- `ManagePoliciesPage` reads `location.query.platform` and threads it
through to both `globalPoliciesAPI.loadAll` / `teamPoliciesAPI.loadAll`
and the react-query keys, plus the count endpoints. The
automation-filter and count "hide" conditions now include the platform
filter so they remain visible when only a platform filter is active.
- `frontend/services/entities/global_policies.ts` and `team_policies.ts`
accept an optional `platform` param (with `"all"` normalized to
`undefined`).
- Added tests for the new column and dropdown in
`PoliciesTable.tests.tsx`.

### Backend
- Added `Platform string ` + `` `query:"platform,optional"` `` to
`ListGlobalPoliciesRequest`, `CountGlobalPoliciesRequest`,
`ListTeamPoliciesRequest`, `CountTeamPoliciesRequest`.
- Extended datastore and service signatures (`ListGlobalPolicies`,
`ListTeamPolicies`, `ListMergedTeamPolicies`, `CountPolicies`,
`CountMergedTeamPolicies`, `ListGlobalPolicies`/`ListTeamPolicies` on
the service) to accept a `platform string` arg. Mocks and all call sites
updated.
- Platform filtering in SQL uses a new helper `platformFilterClause`:
  ```sql
  AND (p.platforms = '' OR FIND_IN_SET(?, p.platforms))
  ```
so policies targeting "all platforms" (empty `platforms` field) always
match regardless of the selected filter. `FIND_IN_SET` uses a bound
parameter (no injection risk).
- Added a new MySQL integration test `testPoliciesPlatformFilter`
covering empty-platform (match-all), per-platform filter, and
team/merged paths.

### Docs
- REST API docs for `GET /api/v1/fleet/global/policies`, `GET
/api/v1/fleet/fleets/:id/policies`, and the corresponding `/count`
endpoints now document the `platform` query param.
- Added `changes/policies-targeted-platforms-filter`.

## Behavior

- `platform=all` (or missing) returns all policies.
- Selecting a specific platform returns policies whose `platforms`
column is empty OR contains the selected token.
- The dropdown only renders when the table is searchable (results exist
OR any filter is active).
- Changing the filter pushes a new URL and resets the page.

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`.

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

## Testing

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

Local verification:
- `go build ./...` — clean
- `go vet ./server/... ./cmd/... ./ee/...` — clean
- `make lint-go-incremental` — 0 issues
- Go service-level policy tests pass. MySQL integration tests compile
but could not be run locally (no Docker); CI will exercise the new
`testPoliciesPlatformFilter` test.

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

* **New Features**
* Added a "Targeted platforms" column with platform icons and an "All
platforms" option.
* Added a platform filter dropdown to scope policy lists; counts,
last-updated, and controls adapt when a platform filter is active.
Backend now honors an optional platform query parameter so filtering
returns matching policies.

* **Tests**
* Added and updated unit and integration tests covering the new column,
filter UI, and platform-filtered policy listings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: nulmete <nicoulmete1@gmail.com>
2026-07-10 13:32:16 -05:00
Carlo 6cfc4a3611 Add GitOps support for macOS script-only packages in setup experience (#49089)
**Related issue:** Resolves #43667

  # Summary

Adds a `setup_experience_platforms` field to the GitOps software package
spec so `.sh` script-only installers can be selected for macOS setup
experience declaratively. Reconciles the cross-platform selection table
on every batch apply.

  # Checklist for submitter

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

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

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

  ## Testing

  - [x] Added/updated automated tests

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

  ## New Fleet configuration settings

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

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

* **New Features**
* Added declarative `setup_experience_platforms` to software package
definitions to control “setup experience” targets, including selecting
script-only installers for macOS (mapped appropriately).
* Batch uploads now propagate these cross-platform selections and
reconcile installer cross-entries.

* **Bug Fixes**
* Improved platform normalization (trimming, casing, alias mapping),
deduplication, and extension-specific validation.
* Enhanced update behavior: omitting the field leaves existing
selections unchanged; providing an empty list clears them, with correct
setup/installation timing.

* **Tests**
* Added unit and integration coverage for normalization and batch
re-apply/reconcile behavior (nil vs empty, idempotency, mixed updates,
and validation failures).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 13:52:48 -04:00
Magnus Jensen 790f457bf0 SAAD: GitOps for DDM assets (#49046)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48570

# Checklist for submitter

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

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

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

## Testing

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

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

* **New Features**
* Added end-to-end Apple DDM asset support in GitOps, including export
and GitOps parsing for `macOS settings` assets.
* Introduced Apple DDM asset management APIs
(list/get/download/create/delete) plus a batch set operation with
dry-run.
* **Bug Fixes**
* Improved Apple MDM/DDM reconciliation so referenced asset updates
trigger re-delivery via asset-aware tokening.
* Added safer validation around asset type changes and deletion
conflicts when assets are still referenced.
* **Tests**
* Expanded unit and integration coverage for asset parsing, upload/apply
behavior, reconciliation, and access control.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 12:56:26 -04:00
Magnus Jensen a7010b2a4a SAAD: User channel + DDM assets for osquery-perf (#49108)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48573

# 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. In another PR

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

## Testing

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

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

* **New Features**
* Added support for macOS MDM user enrollment simulation, configurable
via enrollment probability.
* Implemented user-scoped Declarative Device Management handling for
tokens, declarations, configurations, assets, and status reporting.
* Added new performance metrics for MDM user activity and DDM user
activity (including tokens, items, and status outcomes).

* **Bug Fixes**
* Improved DDM synchronization by detecting declaration changes/removals
and consolidating status updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 15:22:12 +02:00
Magnus Jensen b4ce88645b SAAD: Support DDM assets in sync + reconciliation (#49016)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48568 second part

# Checklist for submitter

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

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

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

## Testing

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

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

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

## Summary by CodeRabbit

* **New Features**
* Apple declarative management now supports asset-backed declarations,
including device delivery of referenced DDM assets.
* Added a new device-facing endpoint to fetch managed DDM assets by
identifier (scoped to the device’s team).

* **Bug Fixes**
* Declaration/profile updates now refresh when referenced assets change
(not just variables).
* Device and host token/declaration matching now accounts for asset
update timing to trigger redeploys reliably.
* Improved validation to detect missing/invalid asset references before
saving.

* **Other**
* Updated which configuration declaration types are blocked during
user-provided validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 14:47:23 +02:00
a33481653d macos password sync feature branch (#47422)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45524

# Checklist for submitter

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

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

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

## Testing

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

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

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

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

## Database migrations

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

## New Fleet configuration settings

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

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

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


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

* **New Features**
* Added Apple Platform SSO (PSSO) for macOS with device registration,
sign-in, and public discovery (JWKS + Apple app-site association)
protected by single-use nonces.
* Added Apple account provisioning (Platform SSO password sync)
configuration with masked client-secret handling and GitOps support.
* Added a host-scoped PSSO device registration token variable for Apple
MDM profile generation.
* **Bug Fixes**
* Fixed macOS packaging to correctly build, embed, and sign the Platform
SSO extension.
* Resetting device Apple MDM data now also clears stored PSSO enrollment
records.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Magnus Jensen <magnus@fleetdm.com>
2026-07-09 14:57:48 -04:00
Lucas Manuel Rodriguez 56763d13c1 Move fleet-mcp from tools/ to cmd/ (#49044)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #43544. 

Moves `fleet-mcp` from `tools/fleet-mcp/` to `cmd/fleet-mcp/`. It is
becoming a production server used by customers, so it now lives under
`cmd/` alongside the other Fleet binaries.

Per the module strategy chosen for this move, it **remains a standalone
Go module** (keeps its own `go.mod`/`go.sum` and isolated deps such as
`mark3labs/mcp-go`, `logrus`, `gorilla/websocket`, `godotenv`) — the
root `github.com/fleetdm/fleet/v4` module is unchanged.

### What changed
- `git mv tools/fleet-mcp/ → cmd/fleet-mcp/` (history preserved as
renames).
- Updated all path references:
  - Root `Makefile` `update-go` module list.
- `.github/workflows/test-fleet-mcp.yml` — trigger paths,
`go-version-file`, `working-directory`.
  - `.github/dependabot.yml` — gomod directory.
  - `cmd/fleet-mcp/render.yaml` — `rootDir`.
- `cmd/fleet-mcp/README.md`, `Makefile`, `schema.go` — path
comments/links.
  - `articles/fleet-mcp.md` — README link.
  - Removed the `fleet-mcp/` row from `tools/README.md`.

### Follow-up (not in this PR)
- The Render service's Blueprint file path must be updated from
`tools/fleet-mcp/render.yaml` to `cmd/fleet-mcp/render.yaml` in the
Render dashboard.

## Testing
- `go build .` in `cmd/fleet-mcp` — OK
- `go test -race -count=1 ./...` — `ok fleet-mcp`

- [x] QA'd all new/changed functionality manually
2026-07-09 13:29:09 -03:00
Tim Lee 56a3c75155 Fix macOS software titles mis-named from embedded helper bundles (#44199) (#47831) 2026-07-09 10:01:27 -06:00
Victor Lyuboslavsky 0a3d73a732 Updated osquery perf for #45550 (#48935)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45550 

# Checklist for submitter

- [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 Windows MDM SCEP certificate simulation to track issued
certificate specs per host during check-ins.

* **Bug Fixes**
* Certificate data generation is now stably ordered and consistent
across refreshes.
* SCEP certificate processing now ignores failed installs (no
certificate) and records only valid issued cert details.

* **Testing**
* A small subset of simulated agents may withhold one SCEP certificate
to exercise verification edge cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-08 21:55:13 +01:00
Victor Lyuboslavsky 4608e82481 Added anonymous usage statistics reporting the number of macOS and Windows hosts enrolled in Fleet's MDM (#48840)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48685

# Checklist for submitter

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

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

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
- Tested `ShouldSendStatistics` method manually against our DB, which
covers all our changes.

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

## Summary by CodeRabbit

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

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

* **Tests**
* Updated and extended statistics tests to verify the new enrollment
counts are computed and reported correctly.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 19:22:31 +01:00
Victor Lyuboslavsky da59512037 Updated osquery-perf for certs (#48499)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #31294 

osquery-perf changes only

# Checklist for submitter

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

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

## Summary by CodeRabbit

* **New Features**
* Added a certificate inventory simulation to the performance tool,
including stable shared certificates and per-host generated
certificates.
* Enhanced macOS and Windows rendering to better match expected
certificate query output (including user vs machine scope formatting).

* **Bug Fixes**
* Improved per-host certificate cache behavior with realistic
refresh/churn.
* Added support for duplicated certificate identities across different
scopes.

* **Chores**
* Updated linting configuration to suppress gosec findings for the new
certificate simulation workload.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 16:30:11 +01:00
Victor Lyuboslavsky 8f3624cf0a Fixed Windows profile modify batch (#48474)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48349, as well as a few other minor issues
found during dev (such as canonical LocURI, ensuring we delete the CSP
version actually on the device, etc.).

Load tested the fix.

# Checklist for submitter

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

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

## Testing

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

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

## Database migrations

- [x] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [x] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).

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

* **New Features**
* Windows profile edits and deletions now handle large environments more
reliably, with faster processing and no size-based timeouts.
* Removed profile content is now cleaned up asynchronously, improving
the responsiveness of profile changes.
* **Bug Fixes**
* Fixed Windows profile edits so removed settings are deleted correctly
even when profiles are updated instead of fully removed.
* Improved matching for Windows configuration targets, making cleanup
more consistent across profile versions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 16:29:53 +01:00
Victor Lyuboslavsky d7692a43ef Add FLEET_MDM_ENABLE_DISK_ENCRYPTION alias for custom BitLocker profiles (#43518) (#48737)
**Related issue:** Resolves #43518

Adds a cross-platform alias `FLEET_MDM_ENABLE_DISK_ENCRYPTION`
(`mdm.enable_disk_encryption`) for the existing
`FLEET_MDM_ENABLE_CUSTOM_FILEVAULT` server configuration. When either
option is set, Fleet allows both custom Apple MDM profiles for FileVault
and custom Windows configuration profiles for BitLocker. Behavior
matches FileVault: no special conflict handling between Fleet's built-in
disk encryption controls and a custom profile. The setting remains Fleet
Premium only.

Both the single-add API/UI path and the batch/GitOps path are covered.
The existing `FLEET_MDM_ENABLE_CUSTOM_FILEVAULT` name continues to work
for backward compatibility.

Demo: https://www.youtube.com/watch?v=5naGaZKLZ8o
Docs: https://github.com/fleetdm/fleet/pull/48738/changes

# 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

## 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**
* Added a cross-platform disk encryption setting that can enable custom
management for both macOS FileVault and Windows BitLocker profiles.

* **Bug Fixes**
* Windows BitLocker profile uploads are now accepted when custom disk
encryption is enabled.
* Startup now disables custom disk encryption management when the
license does not support it, and logs a warning.

* **Tests**
* Added coverage for BitLocker profile handling with custom disk
encryption enabled and disabled.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-06 22:38:45 +01:00
Sharon KatzandClaude Opus 4.6 b36be84e85 Add native Splunk HEC log destination (#48455)
**Related issue:** Resolves #25574

# Checklist for submitter

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

---

## Summary

- Adds a new `splunk` log plugin that sends osquery logs directly to
Splunk's HTTP Event Collector (HEC) endpoint
- Eliminates the need for middleware like AWS Firehose when using Splunk
as a log destination
- Follows the same pattern as existing log destinations (Firehose, Kafka
REST, NATS, etc.)
- Includes `insecure_skip_verify` option for environments with
self-signed TLS certs

## UI changes

Follows the same pattern as the NATS log destination PR (#36527) --
adding "Splunk" to the display name, tooltip, and TypeScript type union.
No new components, pages, or styles.

### Manage automations modal -- "Log destination: Splunk"
<img width="822" height="527" alt="image"
src="https://github.com/user-attachments/assets/2533207f-fa95-4364-8ee0-3c39cd3e8e4d"
/>


### Query details page -- "Log destination: Splunk"
<img width="1905" height="662" alt="image"
src="https://github.com/user-attachments/assets/069a5005-f95c-4562-a819-fd8bdcc349f7"
/>



### Tooltip on hover
<img width="639" height="348" alt="image"
src="https://github.com/user-attachments/assets/809a47a6-b82a-4f45-b731-77b2d2c87947"
/>



### Edit query form -- "sent to your log destination: Splunk"
<img width="451" height="814" alt="image"
src="https://github.com/user-attachments/assets/b78b9a57-1f0c-4413-8b7c-654de1fd40a2"
/>



### Save new query modal -- "sent to your log destination: Splunk"
<img width="536" height="698" alt="image"
src="https://github.com/user-attachments/assets/d0a0ab01-66fe-4d63-9190-9c5e840e456d"
/>

---

### How it works

The Splunk writer (`server/logging/splunk.go`) implements the
`fleet.JSONLogger` interface. On startup it performs a health check
against the HEC `/services/collector/health` endpoint. On each `Write()`
call, it wraps each log entry in Splunk's HEC event format (adding
`time`, `index`, `source`, `sourcetype`), batches them up to 1 MB, and
POSTs to `/services/collector/event` with the `Authorization: Splunk
<token>` header. If a batch exceeds 1 MB it flushes and starts a new
one. Events over 1 MB are dropped with a log warning. Transient errors
(HTTP 503) are retried with exponential backoff (up to 8 retries).

### Configuration

```yaml
osquery:
  status_log_plugin: splunk
  result_log_plugin: splunk

splunk:
  url: https://splunk.example.com:8088
  token: <HEC token>
  index: main
  source: fleet
  source_type: fleet:json
  insecure_skip_verify: false  # set true for self-signed certs
```

Or via environment variables:
```
FLEET_OSQUERY_STATUS_LOG_PLUGIN=splunk
FLEET_OSQUERY_RESULT_LOG_PLUGIN=splunk
FLEET_SPLUNK_URL=https://splunk.example.com:8088
FLEET_SPLUNK_TOKEN=<HEC token>
FLEET_SPLUNK_INDEX=main
FLEET_SPLUNK_SOURCE=fleet
FLEET_SPLUNK_SOURCE_TYPE=fleet:json
```

### Files changed
- `server/logging/splunk.go` -- Splunk HEC log writer with batching,
retry, and health check
- `server/logging/splunk_test.go` -- 9 unit tests
- `server/logging/splunk_integration_test.go` -- 3 integration tests
against real Splunk (gated by env var)
- `server/logging/logging.go` -- Added `SplunkConfig` and `case
"splunk"` to factory
- `server/config/config.go` -- Added `SplunkConfig` struct and config
flags
- `cmd/fleet/logging.go` -- Wired Splunk config into logging builder
- `server/fleet/app.go` -- Added `SplunkConfig` type for API responses
(excludes token)
- `server/service/service_appconfig.go` -- Added `case "splunk"` to
logging plugin validation
- `frontend/interfaces/config.ts` -- Added `"splunk"` to LogDestination
type
-
`frontend/components/LogDestinationIndicator/LogDestinationIndicator.tsx`
-- Added Splunk display name and tooltip
- `docs/Configuration/fleet-server-configuration.md` -- Splunk config
documentation
- `docs/Get started/FAQ.md` -- Updated plugin list
- `articles/log-destinations.md` -- Updated Splunk section with native
HEC docs
- `changes/25574-splunk-log-destination` -- Change file

## Test plan

### Unit tests (9 tests)
- [x] `TestSplunkWrite` -- sends 3 events, verifies HEC format, auth
header, index/source/sourcetype
- [x] `TestSplunkWriteEmpty` -- empty logs don't trigger HTTP request
- [x] `TestSplunkServerError` -- HEC 403 propagates as error
- [x] `TestSplunkHealthCheckFailure` -- constructor fails on bad health
- [x] `TestSplunkRecordTooBig` -- oversized events (>1MB) are dropped,
normal events still sent
- [x] `TestSplunkSplitBatchBySize` -- logs exceeding 1MB batch limit are
split into multiple requests
- [x] `TestSplunkRetryOnServiceUnavailable` -- 503 retried with backoff,
succeeds on 3rd attempt
- [x] `TestSplunkRetryExhausted` -- after 9 attempts (1 + 8 retries)
returns error
- [x] `TestSplunkMissingConfig` -- empty URL/token returns descriptive
error

### Integration tests (3 tests, gated by `SPLUNK_INTEGRATION_TEST=1`)
- [x] `TestSplunkIntegration` -- 3 events sent via writer, queried back
from Splunk REST API
- [x] `TestSplunkIntegrationBatch` -- 100 events in one Write(), all
confirmed indexed
- [x] `TestSplunkIntegrationBadToken` -- bad token Write() returns 403

### End-to-end test (macOS ARM64, real osquery agent)

1. Started Splunk Enterprise, MySQL, Redis via Docker
2. Built Fleet server from this branch with
`--osquery_status_log_plugin=splunk`
3. Set up Fleet, enrolled a real osquery 5.23.0 agent on this MacBook
4. **83 real osquery status log events indexed in Splunk** with correct
source/sourcetype/index
5. Each event contained full osquery data (`hostIdentifier`,
`host_uuid`, `calendarTime`, `severity`, `message`, `decorations`)

### Splunk showing real osquery events from Fleet
<img width="1910" height="861" alt="image"
src="https://github.com/user-attachments/assets/192490bf-d594-4424-a3e3-a18306892873"
/>


Generated with [Claude Code](https://claude.ai/code)

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

* **New Features**
* Added native Splunk HEC logging destination for status, result, and
audit logs.
* Updated the log destination UI to display **Splunk** with a dedicated
tooltip.
* Added Splunk HEC configuration (URL/token/index/source/source type)
including TLS verification control.
* **Bug Fixes**
* Improved log delivery with batching, retries for temporary HTTP
failures, and safeguards for oversized events.
* **Tests**
* Added unit tests and optional integration tests covering routing,
batching, retries, and error scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-07-03 12:14:24 -04:00
Lucas Manuel Rodriguez 88492e98ff Fix TestGitOpsFullGlobal failing on main after Windows BatchSetMDMProfiles change (#48695)
Fixes `TestGitOpsFullGlobal`, which has been failing the `fleetctl` test
bundle on every `main` run since #48467 merged (bisected to a90eab6f62,
e.g. [this
run](https://github.com/fleetdm/fleet/actions/runs/28665588825)).

#48467 changed `BatchSetMDMProfiles` so that `assume_enabled` is only
honored on dry runs; real runs now validate Windows profiles against the
app config persisted in the datastore. That's correct in production,
because the GitOps run persists `windows_enabled_and_configured: true`
via `ModifyAppConfig` before the profiles batch call. But this test's
`AppConfigFunc` mock always returned a fixed app config with Windows MDM
disabled, never reflecting what `SaveAppConfigFunc` stored — so the
real-run profiles batch now fails with 422 "Windows MDM isn't turned
on".

The fix makes the mock behave like the real datastore: once
`SaveAppConfig` is called, `AppConfigFunc` returns the saved config.
Test-only change, no product code touched.

# Checklist for submitter

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

## Testing

- [x] Added/updated automated tests

`go test -run TestGitOps ./cmd/fleetctl/fleetctl/` passes locally (it
fails on `main` without this change).


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

## Summary by CodeRabbit

* **Tests**
* Improved GitOps test coverage to better match real persistence
behavior during an apply run.
* Updated test setup so saved app configuration is read back correctly
after changes are applied.
* Reset test state between subtests to keep each scenario isolated and
reliable.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-03 12:40:09 -03:00
Juan Fernandez e8f26ec4ef Fix S3 file carve cleanup hang and rework reconciliation
Relates to #48549

The S3 carve cleanup (server/datastore/s3, run by the
cleanups_then_aggregation cron) advanced ListObjectsV2 pagination using
the response's ContinuationToken — an echo of the request token —
instead of NextContinuationToken. On any bucket with more than one page
of objects this looped forever, hanging the entire serial cleanup cron
and stalling every cleanup/aggregation job ordered after it.

Replace the bucket-listing reconciliation with a direct HeadObject probe
per carve, which is exact and independent of listing order or object
counts:

- Only carves older than 24h with a completed upload are reconciled
(mirrors the MySQL carve store's floor; skips in-flight multipart
uploads). A carve is expired only on a definitive not-found; transient
or other probe errors leave it for a future run, so a carve whose object
still exists is never expired.
- Probes run with bounded concurrency; expirations are written in one
batched, retryable UPDATE (new ExpireCarves datastore method) rather
than one per carve.
- The number of carves reconciled per run is capped so a large backlog
drains across runs without any single run making unbounded S3 requests.

Add S3-carve-store-only server settings (the MySQL carve store is
unaffected):
- s3.carves_cleanup_disabled       — skip reconciliation entirely
- s3.carves_cleanup_max_per_run    — per-run cap (default 1000)
- s3.carves_cleanup_concurrency    — concurrent probes (default 32)

Also log the expired count per run and fix the test bucket cleanup
helper to paginate. Adds unit tests (transient-error safety, partial
failure, concurrency) and a MySQL integration test for ExpireCarves.
2026-07-01 14:00:59 -04:00
Lucas Manuel Rodriguez e719ece82c Fix IP blocking in tests (#48492)
Fixes issues caused by this merge:
https://github.com/fleetdm/fleet/pull/48261.

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

## Summary by CodeRabbit

* **Tests**
* Improved server startup test coverage for health checks to better
reflect how an external client reaches the service.
* Added cleanup to restore network settings after server startup tests,
reducing the chance of one test affecting others.

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

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

## Summary by CodeRabbit

* **Tests**
* Improved server startup checks to better reflect real external client
behavior during readiness probing.
* Added cleanup so network-blocking settings are restored after test
runs, reducing the chance of one test affecting another.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-30 12:45:35 -03:00
Eric 6abae9ccf4 Regenerate expired dev license (#48484)
Changes:
- Replaced the expired development license key

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

## Summary by CodeRabbit

* **Chores**
* Updated an internal development license value used in testing
environments. No end-user-facing behavior changed.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-30 12:03:22 -03:00
Rajendra kadam bf352c7208 Boot-test runServeCmd end to end (serve.go ~7% to ~64% coverage) (#48261)
Adds an end-to-end boot test for `runServeCmd`, the main server entry
point. This is the coverage milestone for #33370: `serve.go` goes from
~7% to ~64%, and `runServeCmd` itself from 0% to ~62%.

The earlier PRs on this issue (#44929, #45343, #45583, #46166, #46421,
#46517, #46742, #46830, #46893, #47151, #47562, #47891) extracted
testable pieces out of `runServeCmd`, but the function itself stayed at
0% — it blocks on an OS signal and wires the entire server together, so
the only way to cover it is to actually boot it. This PR does that.

`TestRunServeCmd` (gated behind `MYSQL_TEST` + `REDIS_TEST`) boots the
full server against a real migrated test MySQL and Redis, waits for
`/healthz`, then cancels the command context to trigger a graceful
shutdown. It covers two paths:

- **Full boot with Apple MDM enabled** — a 32-byte server private key
brings up the Apple MDM protocol services and the host-identity /
conditional-access SCEP setup, so the boot exercises the MDM startup
path as well as the core wiring, cron schedules, and HTTP server.
- **Fail-fast on bad config** — an invalid Redis host-cache
configuration (enabled with a non-positive TTL) aborts startup through
`initFatal` and returns rather than serving, covering the Redis-init
error path and the nil-pool guard.

Beyond coverage, this doubles as a regression net for the ongoing
`runServeCmd` slicing: a future change that breaks startup now fails
this test instead of reaching a release.

**One production change**, in `runServeCmd`'s shutdown `select`: it now
also watches `cmd.Context().Done()`. This is inert in production — the
root command runs via `Execute()` (not `ExecuteContext()`), so
`cmd.Context()` is `context.Background()` and never cancels. Only the
test runs the command with a cancelable context, which is how it shuts
the server down without sending a real signal (a `SIGTERM` would kill
the test binary).

A couple of notes for reviewers:
- The test uses `os.Setenv` (not `t.Setenv`) because the MySQL test
helper marks the test parallel; the boot scenarios run as serial
subtests so the process-global config env doesn't race.
- `runServeCmd` registers metrics with the process-global Prometheus
registry, which can only happen once per process, so there is a single
full boot here; the error-path scenario fails before that registration.
- The test DB is loaded from a schema dump that doesn't mark every data
migration as applied, so the boot runs with
`FLEET_UPGRADES_ALLOW_MISSING_MIGRATIONS=1`.

It adds ~2s to the `cmd/fleet` (`main`) test bundle, which is well off
the CI critical path.

**Related issue:** Refs #33370

# Checklist for submitter

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually (verified locally:
boots to /healthz, graceful shutdown, ~64% serve.go coverage)
- Changes file: not applicable — internal test coverage with no
user-visible behavior change

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

* **Bug Fixes**
* Improved server shutdown handling to stop cleanly when the running
command’s context is canceled, not only on OS signals.
* Added stronger startup validation to fail fast for invalid Redis
host-cache configuration (e.g., non-positive TTL).
* **Tests**
* Added an end-to-end test that boots the server against real
MySQL/Redis, verifies graceful startup/shutdown, and confirms fast-fail
behavior for misconfiguration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-30 09:28:20 -04:00
Juan Fernandez ed14c5385c Fix API endpoint validation for prefix-mounted SCIM routes
The SCIM endpoints are served by the elimity-com/scim library mounted as
a single prefix handler on the root ServeMux, so they are never
registered as individual gorilla/mux routes.

Since the routes can't be discovered, supply them to the validator
instead: add scim.RegisterValidationRoutes, a FeatureRouteFunc that
registers stub routes for the SCIM endpoints (handlers are never
invoked, only their path templates and methods are inspected). Wire it
into the three Validate call sites (production serve, test helper,
svctest).
2026-06-30 09:10:06 -04:00
Lucas Manuel Rodriguez ddc126ea8d Google Workspace IdP [4/6]: fleetctl generate-gitops support (#48167)
### 🥞 Stack (review/merge bottom-up)

1. #48164 — Activity types (FE+BE)
2. #48165 — Backend (cron + directory sync)
3. #48166 — Usage statistics
4. **#48167 — fleetctl generate-gitops ⬅ this PR**
5. #48168 — Settings UI

📄 Documentation is tracked separately in #48169 (targets
`docs-v4.89.0`).

---

## Summary

**PR 4 of 6.** **GitOps / fleetctl**: `fleetctl generate-gitops` support
for the Google Workspace integration, redacting `api_key_json` with a
TODO + secret warning, plus updated golden testdata.

> 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-3-statistics` (PR 3).

**Related issue:** Resolves #42915

# Checklist for submitter

- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops.

## Testing

- [ ] 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**
* GitOps now supports Google Workspace settings in organization
configuration output.

* **Bug Fixes**
* Free-tier accounts no longer include Google Workspace settings in
global GitOps output.
* Sensitive Google Workspace API key content is now replaced with a
placeholder in generated GitOps files, with a warning recorded.
* GitOps applies a clear state when Google Workspace settings are
omitted or left empty.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-29 13:20:11 -03:00
Lucas Manuel Rodriguez 70b41063a4 Google Workspace IdP [3/6]: usage statistics (#48166)
### 🥞 Stack (review/merge bottom-up)

1. #48164 — Activity types (FE+BE)
2. #48165 — Backend (cron + directory sync)
3. **#48166 — Usage statistics ⬅ this PR**
4. #48167 — fleetctl generate-gitops
5. #48168 — Settings UI

📄 Documentation is tracked separately in #48169 (targets
`docs-v4.89.0`).

---

## Summary

**PR 3 of 6.** **Usage statistics**: report whether a Google Workspace
IdP integration is configured via the new `googleWorkspaceConfigured`
field (`server/fleet/statistics.go`,
`server/datastore/mysql/statistics.go`).

> 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-2-backend` (PR 2).

**Related issue:** Resolves #42915

# Checklist for submitter

- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops.

## Testing

- [ ] 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**
* Usage statistics now include whether Google Workspace is configured,
improving reporting accuracy.

* **Bug Fixes**
* Fixed statistics submissions so the Google Workspace configuration
status is included consistently in outgoing requests.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-29 12:34:06 -03:00
Lucas Manuel Rodriguez ef0a051482 Google Workspace IdP [2/6]: backend (cron + directory sync) (#48165)
### 🥞 Stack (review/merge bottom-up)

1. #48164 — Activity types (FE+BE)
2. **#48165 — Backend (cron + directory sync) ⬅ this PR**
3. #48166 — Usage statistics
4. #48167 — fleetctl generate-gitops
5. #48168 — Settings UI

📄 Documentation is tracked separately in #48169 (targets
`docs-v4.89.0`).

---

## Summary

**PR 2 of 6.** Core **backend** for the Google Workspace IdP
integration:
- Directory sync client (`ee/server/googleworkspace/`) and cron job
(`server/cron/google_workspace_cron.go`) reusing the `scim_*` tables
(Google Workspace and SCIM are mutually exclusive).
- Config types + validation (`server/fleet/google_workspace.go`,
`app.go`, `integrations.go`), appconfig handling + activity emission
(`server/service/appconfig.go`), cron registration and schedule.
- SCIM is ignored while Google Workspace is configured
(`ee/server/scim/scim.go`).

> 🥞 **Stacked PR.** Base: `42915-gw-idp-vitals-1-activities` (PR 1) —
review/merge that first.

**Related issue:** Resolves #42915

# Checklist for submitter

- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops.

## Testing

- [ ] 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 Google Workspace integration support for syncing users, groups,
and host-related identity data.
* Added a scheduled sync that keeps directory data up to date
automatically.
* Added support for configuring Google Workspace in app settings, with
validation and masking of sensitive credentials.

* **Bug Fixes**
* Prevented SCIM provisioning from overwriting data when Google
Workspace sync is configured.
* Preserved existing Google Workspace credentials when an update omits
masked API key values.
* Added handling for deleted users and group membership changes during
sync.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-29 12:28:10 -03:00
7f8e800003 Add private network IP blocking for outbound HTTP requests (#46463)
**Related issue:** N/A (security hardening)

# Checklist for submitter

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

## Summary

Added network-level validation for outbound HTTP requests made by Fleet
integrations (webhooks, SSO, Jira, Zendesk, certificate authorities,
etc.) to prevent requests to unintended destinations. Includes a
configuration option for environments that require connectivity to
private network addresses.

Also fixes a pre-existing nil pointer panic in Jira retry logic and
ensures all HTTP clients use the validated transport.

## Testing

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

Unit and integration tests cover validation logic, boundary conditions,
and multiple configuration modes.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-29 10:41:16 -04:00
Jonathan Katz ba814f4965 Fix gitops leaving temporary url for script-only package in datastore (#48370)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #47947 

# 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

## New Fleet configuration settings

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

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

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


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

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed GitOps generation for script-only packages added by path so it
no longer creates invalid output files.
* Script package entries now use cleaner comments, while regular
packages still show version details.
* Placeholder `script://` installer URLs are now cleared properly and
won’t remain stored after processing.
* **Tests**
* Added coverage for script package comment formatting and for clearing
placeholder installer URLs during GitOps workflows.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-29 10:21:40 -04:00
Juan Fernandez bef74a6ff5 Add per-host reverse index for small-target live queries
Resolves #42441

Store queries that target at most
redis.live_query_small_target_threshold hosts (default 1000) in a
per-host reverse index instead instead of a per-query bitfield indexed
by host ID.

Setting the threshold to 0 disables the reverse index (no query has <= 0
targets), serving as the kill-switch.
2026-06-29 09:43:30 -04:00
George Karr 0f439f9593 Auto-update, pin, and rollback Fleet-maintained apps via UI and GitOps (#48293)
**Related issue:** Resolves #38504

  **Constituent PRs (merged into this feature branch):**

- #47682 — Fleet UI: APRF Software title details page Library/Inventory
layout
- #47808 — Extend update software installer API to support FMA version
pinning
  - #47944 — Fleet UI: APRF library item accordion component
  - #48081 — Versions modal, multi-row Library, pinned state
  - #48098 — Add `pinned_version` to `edited_software` activity
  - #48123 — Auto-update FMA cron
  - #48144 — Download a newly-published FMA version when pinned to it

  # 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
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

  ## Testing

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

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


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

* **New Features**
* Added Fleet-maintained app version pinning (Latest, exact, and major)
via a new Versions modal.
* Introduced premium auto-updates for maintained apps with pin-aware
promotion and rollback-safe caching.
  * Added expandable library version rows and a Policies modal.
* **Bug Fixes**
* Improved pin handling, cache/manifest hydration, and safer update
behavior on per-app failures and deduplication.
* **UI/UX**
* Refreshed the Software title details experience with new
accordion/list patterns, redesigned details widget/tooltips, and updated
installer presentation.
* **Documentation**
* Expanded Storybook component/page coverage and adjusted Storybook
canvas padding.
* **Tests**
* Added/updated unit and integration tests for pinning, auto-update
flows, and new modal/UI behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-26 14:42:23 -05:00
Konstantin Sykulev 19caa5ce8c Fixing android tests (#48336)
https://github.com/fleetdm/fleet/actions/runs/28218912241/job/83595668272

`cmd/fleetctl/fleetctl TestGitOpsAndroidCertificatesAdd`
`cmd/fleetctl/fleetctl TestGitOpsAndroidCertificatesChange`
`cmd/fleetctl/fleetctl TestGitOpsAndroidCertificatesDeleteOne`

Panic triggered due to missing mock
```
created by net/http.(*Server).Serve in goroutine 1296276
	/opt/hostedtoolcache/go/1.26.4/x64/src/net/http/server.go:3464 +0x88a
    gitops_test.go:6099: 
        	Error Trace:	/home/runner/work/fleet/fleet/cmd/fleetctl/fleetctl/gitops_test.go:6099
        	Error:      	Received unexpected error:
        	            	applying Android certificates: POST /api/latest/fleet/spec/certificates: do request: Post "http://127.0.0.1:39447/api/latest/fleet/spec/certificates": EOF (API time: 4ms)
        	Test:       	TestGitOpsAndroidCertificatesDeleteOne
```

  ## Testing

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

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

## Summary by CodeRabbit

* **Tests**
* Updated the test mocks used for GitOps and fleetctl scenarios to
support certificate template variable updates.
* Prevents failures when certificate template variable setting is
invoked during test runs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-26 12:48:46 -03:00
George Karr a2af2d97a0 Adding BYOD backend changes (#47716)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #23242

Backend changes for Apple BYOD (personal) MDM enrollment.

- Adds a `byod` enrollment path that distinguishes personal devices from
organization-owned devices.
- Persists per-host Apple MDM enrollment access rights in a new
`host_mdm_apple_enrollment_permissions` table so SCEP/ACME renewal
honours Apple's monotonic-narrowing invariant (permissions can never be
widened on profile replacement).
- Surfaces wipe/lock/clear-passcode allowed flags on host details for
manually-enrolled Apple hosts.
- Renames the personal enrollment status label to `On (manual -
personal)`.

# 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

### Test plan

- Manual (profile) enrollment, company-owned: device receives full
access rights; wipe/lock/clear-passcode allowed.
- Manual (profile) enrollment, personal (BYOD via `byod=1`): device
receives narrowed access rights (no device lock/erase); host details
show wipe/lock/clear-passcode disabled.
- SCEP/ACME renewal for each of the above: renewed profile preserves the
original ServerURL (incl. `byod=1`) and the stored (narrowed) access
rights; Apple does not reject the replacement.
- Renewal batching: multiple company-owned hosts collapse into a single
InstallProfile command; a BYOD host gets its own command.
- Account-Driven User Enrollment (ADUE): enroll a personal device via
ADUE and confirm it is inherently restricted (Apple `UserEnrollment`
mode — no device lock/erase regardless of AccessRights), and that its
SCEP renewal succeeds and preserves the account-driven enrollment
profile.
- Deleted-then-returned device: delete a still-enrolled BYOD host in
Fleet, let it check back in, and confirm a subsequent SCEP renewal still
uses the narrowed permissions.

## Database migrations

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

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

* **New Features**
* Added personal (BYOD) Apple MDM enrollment support across manual
profiles, OTA enrollments, and SCEP/ACME certificate renewals, with
access rights generated appropriately.
* Apple host details now surface per-device permission flags for wipe,
lock, and clear passcode when available.
* Enrollment status text now shows personal manual enrollments as “On
(manual - personal)”.
* **Bug Fixes**
* Enforced remote wipe/lock (and clear passcode) permissions correctly
for personal devices, including persistence across renewals.
* Host deletion cleanup now removes newly tracked enrollment permission
data.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 18:21:26 -05:00
Carlo DiCelico 2f9147e685 merge main 2026-06-25 13:57:22 -04:00
Carlo 6630aec5fb Auto-update FMA cron (#48123)
**Related issue:** Resolves #47681

Adds an hourly, Premium-only cron (maintained_apps_auto_update) that
keeps Fleet-maintained apps current. For each FMA-backed active
installer (per team), it fetches the latest manifest, downloads and
caches a newly-published version when the pin allows, and advances the
team's active installer based on the pin state:

- Unpinned (Latest): download/cache the newest published version and
advance the active installer to it.
- Caret pin (^N): advance to the newest version within major N
(downloading it if newly published). Never cross into another major.
  - Literal pin: never advance and never download.

New versions are cached as additional software_installers rows (no
schema change; reuses the existing (global_or_team_id, title_id,
version) index), capped at the two most recent per team for rollback.

  # Checklist for submitter

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [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
2026-06-25 13:02:01 -04:00
Rajendra kadam 4583b3cbaa Extract /api/ timeout-override middleware out of runServeCmd (#47891)
Extracts the `/api/` request timeout/body-size override middleware out
of `runServeCmd` and into `apiTimeoutOverrideHandler` in a new
`cmd/fleet/http_middleware.go`. Same pattern as the prior extractions on
this issue (#44929, #45343, #45583, #46166, #46421, #46517, #46742,
#46830, #46893, #47151, #47562). `runServeCmd` drops from ~1000 to ~900
lines, and `serve.go` from 1475 to 1373.

The middleware is the `~100`-line `rootMux.HandleFunc("/api/", ...)`
closure that applies per-route read/write deadline overrides for
endpoints that legitimately run long — synchronous script runs, large
software-installer and bootstrap-package uploads, the Android enterprise
signup SSE stream, and large MDM profile batch operations — and, for
package-upload routes, caps the request body and threads the configured
max installer size through the request context.

Behavior is preserved — the handler is moved verbatim and wired into
`rootMux` via a single `apiTimeoutOverrideHandler(apiHandler, config,
logger)` call, so the same routes get the same overrides and every
request still falls through to `apiHandler.ServeHTTP`. The now-unused
`scripts` and `installersize` imports drop out of `serve.go`.

On test scope: `TestAPITimeoutOverrideHandler` verifies the real
decision in this middleware — that package-upload paths thread the
configured max installer size into the request context (and non-upload
requests keep the default) — and that the wrapped API handler is always
invoked. The deadline overrides themselves go through
`http.ResponseController`, which a unit-test `ResponseRecorder` doesn't
support (the handler logs and proceeds, as in production), so those are
exercised by booting the server rather than asserted in a unit test.

**Related issue:** Refs #33370

# Checklist for submitter

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually (verified via local
server boot)
- Changes file: not applicable — internal refactor with no user-visible
behavior change

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

## Summary by CodeRabbit

* **Refactor**
* Improved timeout handling for long-running operations across the API.
Script execution, file uploads, Server-Sent Event streams, and batch
operations now have optimized request timeouts and body size limits.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-24 19:55:33 -04:00
Jonathan Katz 5864788472 Add pinned_version to edited_software activity (#48098)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #47679 
Adds a few things:
- exports pinned version in `generate-gitops` enclosed in double quotes
- adds `pinned_version` to the edited software activity. When set to a
full or major version it shows up in details, when set to latest or
unchanged it shows up as `pinned_version: null` (some other fields like
display_name also dont show up when unchanged)
- fixes a bug where some FMA's like google chrome couldn't be pinned to
major version because they couldn't be converted to semver (by just
splitting the version on periods instead of converting to semver)


# Checklist for submitter

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

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

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

## Testing

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

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

## New Fleet configuration settings

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

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

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


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

## Summary by CodeRabbit

* **New Features**
* Software titles now support version pinning in GitOps exports for
fleet-managed applications, with pinned version values properly
formatted as quoted strings in the exported YAML configuration
* Activity logs now record when pinned version information is modified
during software editing operations

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 16:15:54 -04:00
Allen Houchins a972ca21b0 Add "Support" default software category (#47923)
**Related issue:** Resolves #48064

Adds a new default self-service software category, rendered as **🛟
Support**, alongside the existing six defaults (Browsers, Communication,
Developer tools, Productivity, Security, Utilities).

## What changed

**Backend (Go)**
- `server/fleet/software.go` — added `🛟 Support` to
`DefaultSelfServiceCategoryNames` (seeds new fleets) and `"Support": "🛟
Support"` to `LegacySoftwareCategoryNames` (so GitOps/FMA manifests can
reference the non-emoji `Support`).
- New migration `20260619120000_AddSupportSoftwareCategory` — inserts
the global default (`team_id=0`) and backfills every existing fleet.
Timestamps pinned for deterministic schema dumps; `INSERT IGNORE` guards
the `(team_id, name)` unique key.
- `schema.sql` regenerated via `tools/dbutils`.
- `cmd/maintained-apps/main.go` — added `Support` to the FMA validator
allowlist.

**Frontend**
- `frontend/interfaces/software.ts` — added `"Support"` to the
`SoftwareCategory` union.
- `frontend/pages/hosts/details/cards/Software/SelfService/helpers.ts` —
added `{ label: "🛟 Support", value: "Support" }` to the fallback list.

**Docs**
- `docs/Configuration/yaml-files.md` — documented `Support` as a
supported GitOps category.

## Note on sort order
`ListSoftwareCategories` does `ORDER BY name` under
`utf8mb4_unicode_ci`, which sorts by the word after the (ignorable)
emoji. `🛟 Support` is therefore placed between `🔐 Security` and `🛠️
Utilities`.

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`.

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

## Testing

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

Verified against a dockerized MySQL:
- Migration test `TestUp_20260619120000`
- `TestSoftware/SoftwareCategoryCRUD` (order-sensitive assertion)
- `TestSelfServiceCategoriesCRUD` + `TestDeviceSelfServiceCategories`
integration tests
- `cmd/maintained-apps` tests, ee categories test, `go vet`, `make
lint-go-incremental` (0 issues)
- `tools/dbutils` schema regeneration matches

## Database migrations

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

## New Fleet configuration settings

- [x] Verified the setting is documented (GitOps `categories` supported
values in `docs/Configuration/yaml-files.md`).


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

## Summary by CodeRabbit

* **New Features**
* Introduced the "🛟 Support" category as a new self-service software
classification option. Users can now better organize support-related
applications within their software catalog. The category is available
globally across all teams, providing improved organization and discovery
capabilities for support applications alongside utilities and other
existing software categories.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-23 09:41:08 -05:00
Rachael Shaw f72325d81c v4.87.0 doc changes (#44709) 2026-06-19 17:47:50 -07:00
kilo-code-bot[bot] e1f972f3a2 Hide generate-gitops command from fleetctl help output (#44254) 2026-06-19 15:45:17 -07:00
Juan Fernandez 5368b99636 Policy status page: automation activity history, reset endpoint, and details UI
Resolves #38670 

Adds the backend and frontend for the Policy status page — a historical, per-host view of policy automation outcomes — plus a way to reset a policy's results.
2026-06-19 12:13:36 -04:00
Scott Gress 208715e2c8 Update some GitOps error messages for clarity (#47134)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45639 

# 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
- [ ] QA'd all new/changed functionality manually
A bit hard to replicate these ones, but they're text changes only.



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

* **Bug Fixes**
* Improved error message clarity for macOS setup assistant and bootstrap
package workflows, including more precise identification of the failed
operation (such as verifying or uploading) and better details for
script-reading failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-19 11:10:58 -05:00
Jonathan Katz ad52492c78 Undo rename from utilities to support (#47881)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #

## Testing

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

- [x] QA'd all new/changed functionality manually
Tested with fleet maintained apps and VPP in UI and gitops 

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

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

## Database migrations
N/A since this is just editing the existing migration
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).

## New Fleet configuration settings

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

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

- [x] Verified that the setting is exported via `fleetctl
generate-gitops`
- [ ] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [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)
- newly added custom category, or default category, was cleared if was
not in the yaml file
- [ ] 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

* **Bug Fixes**
* Corrected the “Productivity” category emoji/name and the “Utilities”
category emoji/name across the system for consistent display and
behavior.
* **Tests**
* Updated unit, integration, and handler tests to expect the corrected
category strings and delete-button labels.
* **Chores**
* Refreshed database seed data and migration/test expectations to align
default and per-team category names, preserving IDs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-19 10:12:10 -04:00
Magnus Jensen 8d26d298e2 fixed update teams not updating appconfig, and team delete not cleaning up appconfig (#47826)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Unreleased bugs while going through test plan

# Checklist for submitter

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

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

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

## Testing

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

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

* **Bug Fixes**
* Apple Business Manager (ABM) token team assignments now stay
synchronized when team defaults change across BYOD, macOS, iOS, and
iPadOS.
* “No team” selections are now saved as cleared (empty) assignments for
cleaner configuration output.
* Improved ABM token cleanup during team deletion to remove references
tied to the deleted team.
* **Tests**
* Added/extended coverage for ABM token team update behavior (including
invalid team handling and nil inputs) and deletion cleanup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-18 18:23:02 +02:00
Steven PalmesanoandJuan Fernandez 435c6e130b Display instructions needed for SSO-enabled accounts with fleetctl (#46768)
**Related issue:** Resolves #21818

# 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

* **New Features**
* The CLI now detects when SSO is enabled on the server and shows a
warning directing users to authenticate with an API token (with guidance
link) instead of email/password.

* **Bug Fixes**
* Authentication error messaging is now SSO-aware, improving guidance
when credential login fails.

* **Tests**
* Added coverage to verify the authentication guidance changes correctly
based on whether SSO is enabled.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Juan Fernandez <juan@fleetdm.com>
2026-06-17 18:19:00 -04:00
Magnus Jensen e14f6e67c1 fix gitops relative paths for unassigned and org_settings (#47512)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45661

I couldn't really find another good solution that would solve it all, as
the path resolution is spread out, plus unassigned merging into global
config definitely makes it more complex (root cause of the issue).

# 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 GitOps relative path resolution so controls and nested
organization settings correctly resolve referenced files from their
source directory, including cases with `unassigned.yml`.
* Corrected macOS setup assistant uploads to use the base filename
instead of the full configured path/URL.
* **Tests**
* Added regression coverage for GitOps relative path handling across
working-directory and nested-file scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-17 18:32:06 +02:00
Nico fcadb0e6b0 Gate all policy label inclusions/exclusions as premium-only (#47686)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #47677 

Updating code so that it matches the docs (all label inclusions and
exclusions for policies should be premium-only):
- https://github.com/fleetdm/fleet/pull/47643
- https://github.com/fleetdm/fleet/pull/46353

## 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
* Global and team policy label scoping now consistently enforces premium
licensing for `labels_include_any` and `labels_exclude_any` (in addition
to existing `any/all` restrictions).
* Non-premium requests that include these label filter fields are
rejected earlier with the appropriate license error.
* GitOps policy export/validation now omits or disallows
`labels_include_any`/`labels_exclude_any` on non-premium instances.

## Tests
* Expanded coverage to verify premium gating behavior across global
policy create/modify and spec-based policy application, including GitOps
validation paths.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-17 10:57:28 -03:00
Magnus Jensen dcf5029da5 BYOF: API & GitOps support (#47506)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45600

I could see the contributor endpoint was not updated, so I just included
it in this PR, and since it's a contributor one I think we are fine
updating ahead of release.

# 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. (Part of previous PR)

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

## Testing

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

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

## Release Notes

* **New Features**
* Added support for Apple Business Manager BYOD team assignments,
including saving/loading BYOD default team selections and exposing BYOD
team details via the API for personal mobile devices.

* **Refactor**
* Updated GitOps key handling for BYOD assignments to use `byod_fleet`,
with migration/aliasing from the older `byod_team` key.

* **Tests**
* Expanded GitOps and ABM token tests/fixtures to cover BYOD team
behavior, including defaults, clearing/reset behavior, and
error/validation scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-17 13:02:37 +02:00
Rajendra kadam dcf5203ff4 Extract cron schedule registration out of runServeCmd (#47562)
Extracts the cron schedule registration out of `runServeCmd` and into a
new `cmd/fleet/cron_registration.go`. Same pattern as the prior
extractions on this issue (#44929, #45343, #45583, #46166, #46421,
#46517, #46742, #46830, #46893, #47151). This is the largest slice so
far — `runServeCmd` drops from ~1300 to ~1000 lines, and `serve.go` from
1776 to 1472.

The 33 `StartCronSchedule` registrations move into one
`startCronSchedules` entry point backed by a `cronSchedulesDeps` struct
(the dependencies the closures previously captured from `runServeCmd`).
Registration is grouped by domain:

- `registerCleanupAndMaintenanceCrons` — chart data collection, the
`cron_stats` cleanup goroutine, software migrations, frequent cleanups,
cleanups-then-aggregation, query results cleanup, upcoming activities,
usage statistics, batch activities.
- `registerVulnerabilityCrons` — the vulnerabilities schedule, or the
remote-trigger proxy when processing is disabled on this instance.
- `registerWorkerCrons` — automations and worker integrations.
- `registerMDMCrons` — Apple MDM worker, DEP profile assigner, service
discovery, the Apple/Windows/Android profile managers, the Android
device reconciler, the Android policy migrations, and the APNs pusher.
- `registerPremiumCrons` — iPhone/iPad refetcher and reviver, maintained
apps, VPP app version refresh (and the one-shot VPP country backfill),
recovery lock passwords, managed local account rotation, activities
streaming, and the calendar schedule.
- `registerMiscCrons` — host vitals label membership and the batch
activity completion checker.

Behavior is preserved — the schedules register in the same order with
the same arguments, the same conditionals gate them (premium, audit log,
env vars, software store presence), and the `config` is threaded as a
pointer so the `&config` and `config.Calendar` mutations inside the
calendar closure keep their original semantics. `cmd/fleet/cron.go` (the
schedule definitions) is intentionally untouched; only the wiring moved.

One unit test added: `TestVulnerabilityProcessingDisabled` covers the
vuln enable/disable predicate extracted into
`vulnerabilityProcessingDisabled`, including the legacy
`current_instance_checks` `"0"` value. The rest of the file is
dependency-wiring relocation with no further decision logic to unit-test
— those paths construct real schedules, so they stay covered by the
existing suite and integration tests. The full `cmd/fleet` suite passes
against MySQL + Redis, and a local server boot confirms the same 30 cron
schedules start as before (verified against the "started cron schedules"
log line).

**Related issue:** Refs #33370

# Checklist for submitter

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually (verified via local
server boot — same 30 cron schedules start)
- Changes file: not applicable — internal refactor with no user-visible
behavior change


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

* **Refactor**
* Centralized background cron schedule startup and standardized job
initialization sequencing for maintenance, vulnerability handling,
integrations, MDM workflows, and premium tasks.
* **New Features / Behavior**
* Added config- and license-controlled enablement for vulnerability
processing (local vs remote triggering), MDM automation (including APNs
delivery and device reconciliation), and premium-only refresh/recovery
behaviors.
* Made chart data collection and optional activity streaming
configurable, with safe fallbacks for scheduling periodicity.
* **Tests**
* Added coverage for vulnerability-schedule enable/disable decision
logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-17 11:06:10 +02:00
Allen Houchins ec1d8fb30c Paginate Fleet-maintained apps and filters (#47615)
Fix the Fleet-maintained apps list being cut off by adding server-side
pagination and applying platform / "hide added apps" filters across the
full library. Introduces MaintainedAppListOptions (with Platform and
AvailableOnly) and changes the ListAvailableFleetMaintainedApps /
ListFleetMaintainedApps signatures. Datastore now paginates and counts
by distinct app name, fetches all platform rows for apps on a page, and
returns a count and pagination metadata; default client page size set to
500. Frontend no longer performs client-side filtering or local
status/platform state; it relies on the API and uses data.count for
totals. Docs, tests, mocks, and various call sites updated (including a
new test that verifies pagination, platform and availability filters).

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

# Checklist for submitter

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

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

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

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

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

## Database migrations

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

## New Fleet configuration settings

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

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

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

## fleetd/orbit/Fleet Desktop

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


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

* **Bug Fixes**
* Fleet-maintained apps listing now paginates server-side (100 per page)
so entries near the end of the alphabet are reachable.
* Platform and “Hide added apps” filters are applied across the entire
library, not just the currently loaded subset.
* The displayed count now matches results by counting macOS and Windows
versions separately.

* **New Features**
* Listing now supports URL-driven platform and “available” filtering,
and the UI consistently reflects the active filter state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-16 15:58:24 -05:00
Nico 12d2aba40c Fix macOS "Update new hosts to latest" staying enabled in GitOps after clearing version/deadline (#45984) (#47602)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45984 

Fix is applied on the GitOps side since that's what I figured the
customer was using on the [Slack
thread](https://fleetdm.slack.com/archives/C061ZA91Y1J/p1779372669701129).

# Checklist for submitter

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

## Testing

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

#### Before

Reproduced on `main`:
- Set `update_new_hosts: true` beforehand.
- Ran `gitops` with `update_new_hosts` commented out. It was still kept
as `true`.



https://github.com/user-attachments/assets/f6b41f0d-38e6-468f-a605-b3e66b7b2dbc

#### After

Running `gitops` with `update_new_hosts` commented out switched its
value to `false`.



https://github.com/user-attachments/assets/24756063-b3a9-400b-a2cc-208dd816a556



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

* **Bug Fixes**
* Corrected GitOps behavior for the macOS “Update new hosts to latest”
setting so it no longer stays enabled after clearing `minimum_version`
and `deadline`; it now defaults to disabled unless both are set.

* **Tests**
* Added GitOps test coverage to verify the defaulting outcomes across
YAML variations for the macOS update settings, including explicit and
empty field combinations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-16 10:21:20 -03:00
Magnus Jensen 76de4adfcb BYOF: Add support for unique token ADUE (#47407)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45598 

1. Apple disregards query params in the 403 WWW-Authenticate URL, so
setting it as the ?initiator= does not work, had to make a new route on
the frontend to match the same URL but with a dynamic token.

# 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

## Summary

* **New Features**
* Added support for a configured default fleet/team for BYO Apple
enrollment.
* Enabled account-driven Apple MDM enrollment using per-enrollment
tokens.
* Added tokenized Apple MDM service discovery and enrollment endpoints.

* **Bug Fixes & Improvements**
  * Added automated daily cleanup of expired enrollment challenges.
* Improved BYOD/account-driven enrollment challenge handling, including
default team assignment and Managed Apple ID updates.
  * Reduced unnecessary BYOD MDM profile refetches during reenrollment.

* **Tests**
* Expanded coverage for token lookup, enrollment challenges, and updated
BYOD/account-driven flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-16 14:56:11 +02:00
Konstantin Sykulev ab64d0e657 Throttling android software installs (#47461)
**Related issue:** Resolves #41910

# 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**
* Configurable Android app operation batch size
(FLEET_MDM_ANDROID_BATCH_SIZE, default 1000) to reduce Android
Management API load.
* Android software install and app-availability operations now run in
batched, staggered jobs across workers to improve reliability and avoid
API throttling on large fleets.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-15 19:54:23 -05:00