Commit Graph
1764 Commits
Author SHA1 Message Date
Jonathan Katz 45abf8c9ad Add software installer upload/download progress to GitOps runs (#50250)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45728
Changes:
- Adds a new redis key to keep track of downloaded packages. It starts
out with an empty list and gets filled with each download. Each update
writes the entire struct at once to the key.
- Adds logging in the fleetctl gitops client to show which packages were
downloaded
- Fixes the categories key potentially expiring 

# 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
- Right now the batch will write the whole slice of all packages to a
single redis key for every package in the loop. Looks like performance
is acceptable for now (500 packages), but maybe this will need to be
limited.
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

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

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



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

## New Features
- Added per-package software download progress in fleetctl GitOps.
- Progress now reports downloading, completed, skipped, and failed
packages during real and dry runs.
- Installation output now distinguishes applying and applied stages.

## Bug Fixes
- Improved download error messages and cached-package handling.
- Prevented duplicate progress messages and ensured tracking issues do
not interrupt successful software batches.

## Tests
- Expanded coverage for progress reporting, failures, dry runs, package
types, and authorization scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-31 21:36:44 -04:00
Dante Catalfamo 2fd2a02e2d Split MDM platform helpers by Android semantics (#50185)
**Related issue:** Resolves #46118
2026-07-31 15:52:19 -04:00
Lucas Manuel Rodriguez 0dc8c382c5 Add 'linux' as platform for labels (#50270)
Resolves #44088.

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

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

## Testing

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

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

* **New Features**
  * Added Linux as a label platform option.
* Linux labels now apply across supported distributions, including
Ubuntu, Debian, RHEL, CentOS, and generic Linux hosts.
  * Updated platform names for improved clarity and consistency.

* **Bug Fixes**
* Improved platform matching so Linux labels apply consistently to
compatible hosts.
  * Removed the obsolete Zorin platform option.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-31 15:02:57 -03:00
Nico 07457475b6 fleet-mcp: align Render blueprint with the deployed service (#50317)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #43544

This blueprint has drifted from the deployed `fleet-mcp` service in two
ways. `FLEET_LIVE_QUERY_REST_PERIOD=25s` is too short for a hosted
service aimed at a whole fleet: enough targeted hosts are asleep or
offline that `run_live_query` returns a near-empty result before they
check in, reading as "no data" rather than "still waiting." And `plan:
starter` disagrees with the Standard instance the service actually runs
on, so a blueprint sync risked silently downgrading it. Both fields
carry literal values, making them blueprint-managed, so a dashboard
override would be reverted on the next sync.

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

## Summary by CodeRabbit

* **Configuration**
  * Updated the hosted Fleet deployment to use the standard plan.
  * Increased the live-query interval to 15 minutes.
* Clarified configuration guidance for Fleet server alignment and hosted
Fleet behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-31 14:43:40 -03:00
Carlo a442d7af3a Python script-only packages: follow-on QA fixes (#50143)
**Related issues:** Resolves #50068, Resolves #50106, Resolves #50107,
Resolves #50108, Resolves #50110, Resolves #50114

Follow-on fixes from QA of #41470 (Python script-only packages):

- Software-installer validation errors are action-neutral, so the Add
and Edit flows each show the correct single verb, and the
unsupported-file error names a content/format mismatch instead of
blaming the extension (#50068, #50107).
- `.py` packages accept `setup_experience_platform` (`darwin`/`linux`),
matching `.sh` (#50106).
- A failed-to-run install script (exit code `-1`) now renders a
diagnostic instead of empty output, and orbit surfaces the underlying
execve error (#50108).
- The install-rejection message for `.sh`/`.py` packages says "macOS and
Linux hosts" instead of "linux" (#50110).
- Orbit writes each script's temp file with an extension matching its
shebang (`.py`/`.sh`/`.ps1`), so tracebacks reference the right file
type (#50114).

# Checklist for submitter

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

## Testing

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

## fleetd/orbit/Fleet Desktop

- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes.
- [x] Verified compatibility with the latest released version of Fleet
(orbit-only change; the server↔agent `SoftwareInstallDetails` contract
is unchanged).


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

* **Bug Fixes**
* Improved installer validation and rejection messaging for
unsupported/invalid package contents (including correcting “add” vs
“edit” wording and avoiding duplicated phrasing).
* Added clearer diagnostics when install scripts fail to start
(including empty output cases).
* Corrected handling of script-only packages so Python scripts use the
proper script type/extension, reducing misleading tracebacks.
* Updated platform availability messaging so `.sh`/`.py` packages
display macOS+Linux support.
* **New Features**
* Python script-only packages can now specify macOS and Linux setup
experience platforms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-30 14:40:24 -04:00
Juan Fernandez b06cbde1de Exclude non-existent host IDs from host transfer activity
The host transfer endpoint recorded raw requested host IDs in the
transferred_hosts activity verbatim, letting an authorized user inject
fabricated IDs into the audit trail. Derive the activity's host IDs and
names only from hosts that actually exist, and skip the activity when
none exist.
2026-07-30 13:59:43 -04:00
c83ecc2231 Match Windows software with version in name to FMA software title
Resolves #44406

Windows programs report a version in their name (e.g. `Granola
7.373.2`), so each version created its own `software_title` and never
linked to the Fleet-maintained app installer's title (`Granola`), hiding
the uninstall action. macOS handles this via `bundle_identifier`;
Windows had no join key.

- Give matching Windows programs the canonical FMA name at ingestion
(name-prefix match), so all versions collapse onto the title the
installer owns. `software.name` is unchanged.
- Merge already-mismatched versioned titles onto the canonical title in
`ReconcileMaintainedAppSoftwareNames` (runs on FMA sync; no migration
needed).

---------

Co-authored-by: Tim Lee <timlee@fleetdm.com>
Co-authored-by: Juan Fernandez <juan@fleetdm.com>
2026-07-30 09:49:52 -04:00
Victor Lyuboslavsky ffc85a42ae Add Windows admin account config (#49863)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48720 

Subtask of https://github.com/fleetdm/fleet/issues/43488
This PR only adds the Windows config, and doesn't mess with macOS
configs.

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

## 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)
- [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 managed local account settings for Windows to app and team
configuration, including GitOps support.
* Exposed an explicit enabled/disabled toggle in configuration output
and Fleet controls.
* Added licensing and Windows MDM prerequisites for enabling the
setting.

* **Bug Fixes**
* Managed local account enable/disable actions are now correctly
persisted and declaratively applied.
* Activity feed messages now display platform-specific (macOS vs
Windows) wording.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 12:10:33 -05:00
Rajendra Kadam f2662ccaf5 Default setup experience account type to admin when serving team config (#50034)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #49346

## Description

A fleet created before the managed local account keys existed (e.g. in
4.84.0) and never edited since has no `end_user_local_account_type` or
`enable_managed_local_account` in its stored config. `GET /teams/:id`
served these as `null`, so the *Setup experience → Users* card showed no
account-type selection and a wrongly checked, greyed-out "Create hidden
admin" box.

- **`server/fleet/teams.go`** — `Team.MarshalJSON` now falls back to
`"admin"` / `false` for these keys when they're unset, mirroring the
existing `AppConfig.MarshalJSON` fallback that already covers the global
("No team") config. This is the one serve path that was missing the
default; the save path (`TeamConfig.Value()`) already applied it, which
is why only untouched pre-4.84.0 fleets were affected.

Serve-time fallback only — no stored data is modified and the
account-provisioning logic is untouched.

> **Note for reviewers:** `Team.MarshalJSON` is also the serialization
used by `fleetctl get teams` / GitOps, which had the same `null` bug.
With this change those now emit `end_user_local_account_type: admin` and
`enable_create_local_admin_account: false` for teams that previously
showed `null` — matching what the global config already emits. The
get→apply roundtrip stays idempotent because the save path already
writes these defaults. Team goldens updated accordingly.

## Testing

- **Automated:** `TestTeamMarshalJSONMacOSSetupDefaults`
(`server/fleet`) — a team with the keys unset marshals to `"admin"` /
`false`, and explicitly set values still round-trip. Updated the
`fleetctl` team goldens (`TestGetTeams`, `TestApplyMacosSetup`,
`TestApplyMacosSetupDeprecatedKeys`) to reflect the defaulted output.
- **Manual:** simulated a 4.84.0 fleet by removing both keys from a
team's stored `config` JSON. On `main` the Users card showed no selected
radio and a checked, greyed hidden-admin box; on this branch the same
fleet shows **Admin** selected and the box unchecked, matching what
global "No team" already renders.

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).

## Testing

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


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

## Summary by CodeRabbit

* **Bug Fixes**
* macOS device setup now applies correct defaults when managed local
account settings are missing from existing team configurations.
* The end-user local account type now defaults to **admin** and managed
local account creation defaults to **disabled** (false) unless
explicitly configured.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-28 20:04:41 +05:30
bf3e1bab99 Add Apple marketing names to backend, frontend, and an osquery table (#46482)
**Related issue:** Resolves
https://github.com/fleetdm/fleet/issues/46818 and
https://github.com/fleetdm/fleet/issues/48524.

# Checklist for submitter

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

## Testing

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

## fleetd/orbit/Fleet Desktop

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


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

* **New Features**
* Host lists and Host details now show human‑readable Apple hardware
marketing names (macOS, iOS, iPadOS) where available (e.g., "MacBook Pro
(16‑inch, 2021)"), replacing raw model identifiers.
* Hardware model displays fall back to the original model identifier for
non‑Apple or unmapped devices.

* **Bug Fixes / CSV**
* Exported host CSVs now align with the UI by using the marketing name
for Apple devices when available.
<!-- 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: Lucas Manuel Rodriguez <lucas@fleetdm.com>
2026-07-27 22:26:30 -03:00
Magnus Jensen 4c36caa453 pass validation for fleets gitops files for DDM assets (#49991)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #49979 

# 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. (Unreleased bug)

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

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

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

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

## Summary by CodeRabbit

* **Bug Fixes**
* Prevented Fleet Free from attempting to apply premium-only Apple DDM
assets.
* Improved macOS DDM asset reconciliation so explicitly empty settings
can clear previously configured assets.
* Ensured GitOps and team configurations consistently recognize and
validate macOS asset settings.
* Restricted DDM asset processing to Premium deployments with configured
and enabled MDM.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 20:23:54 +02:00
Andrew Mellor d06a4c222c 47700 abm token invalid errors (#49770)
**Related issue:** Resolves #47700

# 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.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] Added/updated automated tests

- [ ] QA'd all new/changed functionality manually. **_Not able to do for
all code paths yet_**



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

* **New Features**
* Added `token_invalid` for Apple Business Manager tokens, automatically
tracked based on Apple responses.
* Enhanced host DEP assignment API responses with a structured
`dep_device_error` field to classify why device details couldn’t be
retrieved.
* **Bug Fixes**
* Improved error handling for DEP device lookup, distinguishing
invalid/rejected tokens, expired terms, not-found devices, server/API
errors, and unavailable/unspecified failures.
* Added regression and unit test coverage for ABM token invalidation and
DEP device error classification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 10:35:27 +01:00
Victor Lyuboslavsky e42dc7accf Improved the performance of the configuration profiles status summary (#48873)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48340 

Windows only. The fix is to use a rollup status table instead of
recalculating the host profile summary on demand.

Verified the fix in load test with 100k Windows MDM hosts. Note that
this does not improve the host details page filtered by OS settings,
which will be handled by the follow up
https://github.com/fleetdm/fleet/issues/48996

# Checklist for submitter

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

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

- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

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

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

## Database migrations

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

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

* **Bug Fixes**
* Improved Windows fleet configuration profile status summaries to avoid
timeouts on large fleets.
* Kept per-host Windows profile statuses accurate after profile updates,
resends, certificate changes, cleanup, unenrollment, and host deletion.
* Added automatic reconciliation to correct stale or orphaned status
data.
* **Data Integrity**
* Improved Windows profile status reporting, including profile and
BitLocker summaries, for more reliable results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 11:59:37 -05:00
Sharon Katz f492a6a41d Enforce API-only endpoint restrictions on chart routes (#49477)
# 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

## Summary

Enforced API-only endpoint restrictions on chart endpoints, matching the
pattern already used by the activity bounded context. Also added
`RouteTemplateRequestFunc` to chart route server options so the
middleware can read the matched mux route template from context.

## Testing

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

### Reproduction

Created an API-only user with a restrictive endpoint allow-list (only
`GET /api/v1/fleet/hosts`). Confirmed that:
- Allowed endpoint (`/api/latest/fleet/hosts`) returns 200
- Non-allowed cataloged endpoint (`/api/latest/fleet/users`) returns 403
- Chart endpoint (`/api/latest/fleet/charts/uptime`) returned 200 before
the fix (the bug)
- After the fix, chart endpoint correctly returns 403

### Unit test

Added a test case in `server/service/middleware/auth/api_only_test.go`
that verifies an API-only user with endpoint restrictions is denied
access to chart endpoints not in their allow-list. The chart endpoint is
included in the test catalog (matching production), so the test
exercises the allow-list rejection path.

All 17 tests in the auth middleware package pass.

### Local verification

1. Confirmed the chart middleware in `cmd/fleet/serve.go` previously
called `auth.AuthenticatedUser(svc, next)` without
`APIOnlyEndpointCheck` wrapping
2. Verified the activity bounded context (same file) already uses
`auth.APIOnlyEndpointCheck(next)` as the correct pattern
3. Applied the same wrapping to the chart middleware
4. Added `RouteTemplateRequestFunc` to
`server/chart/internal/service/endpoint_utils.go` so the route template
is available in context (required by `APIOnlyEndpointCheck`)
5. Ran `go test ./server/service/middleware/auth/ -v` with all 17 tests
passing
6. Ran `make lint-go-incremental` with 0 issues
2026-07-23 10:44:13 -04:00
Juan Fernandez fbccb8cc59 Emit created/deleted activities for setup experience scripts
Setup experience script add/replace/delete now record activities (API
and GitOps), skipping no-op re-submissions.
2026-07-23 06:41:51 -04:00
Juan Fernandez e91a0b2987 Normalize login responses for MFA-enabled accounts
Make failed logins for MFA-enabled accounts return a consistent response
and timing regardless of the cause, in line with authentication best
practices. Guidance for CLI users whose client can't complete email
verification is now surfaced by fleetctl on any login failure.

Added a `user_mfa_requested` activity, recorded when valid credentials
are submitted for an MFA-enabled account and a verification email is
sent.
2026-07-23 06:41:27 -04:00
Victor Lyuboslavsky a7eb747faf Flag to bypass end user auth (#49683)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46644 

Demo video: https://www.youtube.com/watch?v=svCaA-820yc
Docs: https://github.com/fleetdm/fleet/pull/49713/changes

# Checklist for submitter

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

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

## Testing

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

## fleetd/orbit/Fleet Desktop

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


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

* **New Features**
  * Added `--bypass-end-user-auth` to `fleetctl package` and Orbit.
* Generated Linux and Windows installers can skip the end-user
authentication prompt during enrollment.
* Added `ORBIT_BYPASS_END_USER_AUTH` for environment-based
configuration.
* End-user authentication remains enabled when a supported EUA token is
provided.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 15:32:58 -05:00
Nico e017eb6176 Allow bypassing network blocking in production via config (#49747)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #49751

A customer's egress proxy (an Envoy sidecar bound to loopback) was
getting blocked by Fleet's SSRF network-blocking check, since the check
applies to whatever address the HTTP transport dials, including the
proxy hop itself, not just the ultimate destination. There was no
supported way to disable this in production (the existing full-bypass
mode was dev-only), leaving no path forward for environments where
egress is already constrained by external infrastructure.

# Checklist for submitter

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


## Testing

- [x] Added/updated automated tests

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

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

## Summary by CodeRabbit

* **New Features**
* Added a production server setting to bypass outbound network blocking
for integration requests when external egress controls are already in
place.
* The setting is disabled by default and can be configured through the
server configuration.

* **Documentation**
* Clarified that bypassing network blocking disables SSRF protections
for all outbound integration requests.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 13:23:21 -03:00
Allen Houchins 0e587dc80c Add Firefox Nightly and Firefox Developer Edition Fleet-maintained apps (#49501)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #49149

Adds **Firefox Nightly** and **Firefox Developer Edition** as
Fleet-maintained apps for macOS and Windows (4 new FMAs). Mozilla VPN
(also requested in #49149) is not included, so this doesn't close the
issue.

## What's included

| App | macOS | Windows |
|-----|-------|---------|
| Firefox Nightly | Homebrew cask `firefox@nightly`, bundle ID
`org.mozilla.nightly` | MSIX `Mozilla.Firefox.Nightly.MSIX` (no exe
package exists in winget) |
| Firefox Developer Edition | Homebrew cask `firefox@developer-edition`,
bundle ID `org.mozilla.firefoxdeveloperedition` | NSIS exe
`Mozilla.Firefox.DeveloperEdition`, machine scope, `/S` |

All identity fields were verified against the real installers, not
catalog metadata: bundle IDs read from the DMGs' `Info.plist`, MSIX
identity ("Firefox Nightly" / publisher "Mozilla Corporation") read from
the package's `AppxManifest.xml`, and DevEd's registry identity
(`Firefox Developer Edition (x64 en-US)`, publisher `Mozilla`,
versionless DisplayName) confirmed in Mozilla's NSIS installer source at
the shipped release tags.

The MSIX install/uninstall scripts follow the established Slack/Claude
pattern (provision machine-wide + register for the logged-on user via
scheduled task).

## Pre-release version handling (macOS)

Mozilla's pre-release bundles report only the base version in
`CFBundleShortVersionString` (`153.0` for cask version `153.0b13`),
which would make the generated patch policy flag every up-to-date
install as outdated. Instead, the patch policies for these two channels
compare **`bundle_version`** (`CFBundleVersion` encodes the build date,
e.g. `15326.7.15`), so individual pre-release builds are
distinguishable:

- **Nightly**: derived directly from the build timestamp embedded in the
cask version (`154.0a1,2026-07-17-09-27-13` → `15426.7.17`). No external
calls.
- **Developer Edition**: build date resolved from Mozilla's
[buildhub](https://buildhub.moz.tools) (indexed as product `firefox`,
channel `aurora`). On buildhub failure the ingester logs a warning and
falls back to a base-version comparison (cycle granularity) rather than
failing the run; it self-corrects on the next scheduled ingestion.

The macOS validator gets a matching exception accepting `base + "b"`
versions for the DevEd bundle ID. Both computed values were verified
against the actual DMGs' `Info.plist`.

**Known limitation (Windows):** patch detection for Developer Edition on
Windows is only accurate to the release cycle (153 vs 154), not between
betas (b13 vs b14) — the registry `DisplayVersion` and winget's
`PackageVersion` are both the base version (`151.0`) with no beta
number, and osquery's `programs` table has nothing finer to compare.
Nightly on Windows is day-granular since its MSIX package version
encodes the build date. Documented in #49149.

## Other changes

- Tightened `firefox_uninstall.ps1` (release channel FMA): its
`*Firefox*` match would have uninstalled Developer Edition (or ESR)
first depending on registry enumeration order. Now matches `Mozilla
Firefox*` and excludes ESR; `firefox/windows` output regenerated.
- Channel-specific icons generated from the real app bundles (frontend
components + website PNGs), with map keys covering both catalog and
inventory names.

## Why Firefox Beta is not included

Beta (requested in #49149) was deliberately dropped:
- On Windows, the Beta exe registers the same identity as release
Firefox (`Mozilla Firefox (x64 en-US)`), making it indistinguishable in
inventory. The only distinct package is `Mozilla.Firefox.Beta.MSIX`,
which has no `en-US` winget locale manifest (only `en`), which the
ingester requires.
- On macOS, Beta shares both the bundle ID (`org.mozilla.firefox`) and
the install path (`/Applications/Firefox.app`) with release Firefox, so
installing it silently replaces a release install.

## Notes for reviewers

- Nightly URLs are date-stamped and refresh with the daily FMA
ingestion; within-cycle Nightly darwin builds share a `CFBundleVersion`
date so same-day rebuilds are indistinguishable.
- DevEd's winget package lags Mozilla's releases (winget latest is 151.0
vs current 153.0b13); the FMA tracks winget as usual.
- The `CFBundleVersion` format (`<major><yy>.<M>.<D>`, unpadded) is an
inferred contract of Mozilla's build system, verified against both
shipped DMGs; if it ever changes, patch status fails visibly (reports
unpatched), not silently.

# Checklist for submitter

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

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

## Testing

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


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

* **New Features**
* Added deployment support for Mozilla Firefox Developer Edition and
Firefox Nightly on macOS and Windows (including Homebrew/Winget inputs
and platform-specific install/uninstall workflows).
* Added new catalog entries and dedicated UI icons for both Firefox
variants.
* **Bug Fixes**
* Improved macOS “patched” detection and version matching for Developer
Edition and Nightly builds.
* Enhanced Homebrew ingestion by resolving build information (with
fallback when unavailable).
* Refined Windows uninstallation matching to target the correct Firefox
release channels and avoid ESR.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-17 16:05:27 -05:00
Konstantin Sykulev fd4f92a7e7 Android Load testing with osquery perf (#48535) 2026-07-17 13:54:09 -07:00
Lucas Manuel Rodriguez da3f30df79 Allow Microsoft conditional access on premium self-hosted (#49414)
Resolves #47699.

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

## Testing

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

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

* **New Features**
* Microsoft Entra Conditional Access is now supported for self-hosted
Fleet Premium instances.
* Conditional Access is available only on the Fleet Premium license
tier.
* **Changes**
* Removed the Microsoft Compliance Partner API key configuration and
updated the proxy behavior accordingly.
* Removed the managed-cloud indicator from license/config responses and
adjusted related UI rendering and gating.
* **Tests / Maintenance**
* Updated fixtures and automated tests to reflect the new licensing
gates and API/proxy behavior (including updated failure codes).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-17 10:59:32 -03:00
Juan Fernandez 0d3a3bdc95 Added audit activities when secret variables are upserted
Added audit activities when secret variables are created or updated
through the `PUT /api/latest/fleet/spec/secret_variables` endpoint.
2026-07-16 18:54:04 -04:00
Carlo 57bab9e5ec Allow Python script-only packages (#49070)
**Related issue:** Resolves #41470

Adds support for uploading Python (`.py`) script-only software packages
— accepted as script-only (the file contents become the install script;
advanced options and automatic install follow `.sh`/`.ps1`), assigned
the new `py_packages` source, and installable on macOS and Linux hosts
across the UI, REST API, and GitOps.

Feature branch combining the backend (#48942) and frontend (#48946)
sub-PRs.

# Checklist for submitter

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

## Testing

- [x] Added/updated automated tests
- [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 Python (`.py`) script-only software packages across
UI uploads, API/self-service installs, and GitOps parsing.
* Python installers now derive metadata correctly and render the proper
Python icon, with install eligibility for macOS & Linux.
* **Bug Fixes**
* Improved installer-script validation and “supported file types” error
messages to include `.py` (and consistent handling of related script
fields/options).
* **Tests**
* Expanded unit, integration, and GitOps tests to cover Python package
parsing, metadata derivation, platform/host eligibility, and UI
rendering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-16 14:20:03 -04:00
Juan Fernandez 83cef5483f Extend support for all built-in
Relates to #38806

Extend host name templates beyond the three host-identity variables to
also accept the IdP end-user variables, and re-enqueue the rename when a
referenced variable's value changes.

Re-enqueue on value change:
- An IdP data change (SCIM user/group create/update/delete) re-queues
only the affected hosts whose template uses the changed IdP variable —
IdP values are per host, so the scope is the specific hosts mapped to
that user/group.
- A custom (secret) value change re-queues every eligible host in each
team / "No team" whose template references the changed secret — secret
values are global, so the scope is the whole team/No-team.

Built-in variables intentionally NOT supported:
- Certificate/CA variables — $FLEET_VAR_NDES_SCEP_CHALLENGE,
_NDES_SCEP_PROXY_URL, _CUSTOM_SCEP_CHALLENGE_*,
_CUSTOM_SCEP_PROXY_URL_*, _SMALLSTEP_SCEP_CHALLENGE_*,
_SMALLSTEP_SCEP_PROXY_URL_*, _DIGICERT_DATA_*, _DIGICERT_PASSWORD_*,
_SCEP_WINDOWS_CERTIFICATE_ID, _CERTIFICATE_RENEWAL_ID (and legacy
_SCEP_RENEWAL_ID), _PSSO_DEVICE_REGISTRATION_TOKEN. These resolve to
one-time SCEP challenges, proxy URLs, base64 PKCS12 cert data, or
Fleet-minted tokens — meaningless as a device name, and resolving them
has side effects (issuing certificates, consuming one-time challenges)
and would leak secrets into a name that's broadcast on-device, in
osquery, and in the UI.
- Legacy $FLEET_VAR_HOST_END_USER_EMAIL_IDP — deprecated ("avoid in new
replacements") and not a documented built-in variable, so it's excluded
in favor of the supported IDP_USERNAME variables.
2026-07-16 10:43:37 -04:00
Juan FernandezandKonstantin Sykulev 621ede7584 Software > OS: Show Android versions and vulnerabilities (#49399)
Resolves #35075 

- Added vulnerability (CVE) reporting for Android OS versions.
- Folded the Android security patch level into the host's OS version.

---------

Co-authored-by: Konstantin Sykulev <konst@sykulev.com>
2026-07-16 10:37:57 -04:00
Carlo DiCelico 4ce133cb26 merge main 2026-07-15 19:17:29 -04:00
Nico b10642be3c 44954 custom host vitals (#49334)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44954 

# Checklist for submitter

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

## Testing

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


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

* **New Features**
* Added Custom Host Vitals management (create/edit/delete, search) with
copyable variable tokens and per-host values.
* Show Custom Host Vitals on host details, including role-based editing.
* Enabled Custom Host Vitals in host-vitals labels and the activity
feed.
* Extended GitOps to manage global Custom Host Vitals declaratively
(including dry-run behavior).
* Split Controls → Variables into Global Variables and Custom Host
Vitals, including routing updates.

* **Bug Fixes**
* Improved validation and expansion of Custom Host Vital references
across scripts, profiles, installers, and deployments, with clearer
failures when values are missing or invalid.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 19:35:27 -03:00
Carlo DiCelico a65af7461e Merge remote-tracking branch 'origin/main' into feat/28108-multiple-custom-packages 2026-07-15 17:47:12 -04:00
Allen Houchins 829064c7b2 Bump FMA validator download timeout to 5 minutes (#49338)
**Related issue:** NA

## What & why

The FMA validator (`cmd/maintained-apps/validate`) downloads each app's
installer with a hardcoded 2-minute context timeout. Large installers
can't finish in that window — e.g. Android Studio (Windows) is ~1.39 GB,
which needs ~12.4 MB/s sustained to complete in 2 minutes. When the
runner is slower, the download aborts with `context deadline exceeded`,
failing validation with a misleading error that looks URL-related.

This bumps the validator timeout from 2 to 5 minutes. (For reference,
the production download path already uses `InstallerTimeout = 15 *
time.Minute`.)

# Checklist for submitter

- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

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


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

## Summary by CodeRabbit

* **Bug Fixes**
* Increased the installer download timeout to five minutes, improving
reliability for slower downloads.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 10:15:25 -05:00
Juan Fernandez 82db4d5389 macOS & iOS/iPadOS: Rename hosts
Resolves #38806 

Add an IT-admin naming convention for macOS/iOS/iPadOS hosts. An admin
sets a name template (e.g. "iPad $FLEET_VAR_HOST_HARDWARE_SERIAL") under
Controls > OS settings > Host names for a fleet or for "No team"; Fleet
resolves it per host, delivers it via an Apple `Settings`/`DeviceName`
MDM command, renames its own record on ACK, then verifies the name via
osquery (macOS) or a DeviceInformation refetch (iOS/iPadOS). Clearing
the template stops enforcement without renaming any host. Fleet Premium
only, mirroring disk encryption.
2026-07-14 10:28:19 -04:00
Carlo 5e2b76a3ad Rename setup_experience_platforms to singular comma-separated setup_experience_platform (#49245)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** #43667

# Summary

Renames the unreleased GitOps field `setup_experience_platforms` to
singular `setup_experience_platform`, accepting a comma-separated string
of `darwin`/`linux` (rejecting the `macos` alias) to match the
query/policy/label `platform` convention.

# Checklist for submitter

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

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

## New Fleet configuration 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)


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

## Summary by CodeRabbit

* **Improvements**
* Updated software setup-experience platform configuration to use a
single comma-separated `setup_experience_platform` value.
* Platform values are normalized for casing and whitespace,
deduplicated, and validated against supported platforms.
* macOS setup selections now use the canonical `darwin` value; the
`macos` alias is rejected.
* GitOps-generated configurations now use the updated field name and
platform format.
* **Bug Fixes**
* Improved validation messages for invalid setup-experience platform
values.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 20:02:36 -04:00
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
Carlo DiCelico 06863c4b37 Merge remote-tracking branch 'origin/main' into feat/28108-multiple-custom-packages
# Conflicts:
#	frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/LibraryItemAccordion/LibraryItemAccordion.tsx
#	frontend/pages/SoftwarePage/SoftwareTitleDetailsPage/SoftwareTitleDetailsPage.tsx
#	pkg/spec/gitops.go
#	server/datastore/mysql/schema.sql
#	server/fleet/software_installer.go
2026-07-10 14:48:55 -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
Jonathan Katz 7124b27187 Allow multiple packages - GitOps (#48710)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #48399
Summary:
- Allows multiple installers for the same title to be defined in a yaml
file
- `generate-gitops` generates a file like this if multiple installers
are available per title
- Allows labels, self_service, categories keys to be defined per package
- Inherits fleet-level keys only if they are not set at the
package-level
- Repoints policies.software_installer_id for a deleted installer to
either the first added installer for that title, or NULL if none are
available

# 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



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

## Summary by CodeRabbit

* **New Features**
* GitOps output now supports software titles that contain multiple
packages, generating a dedicated package file plus related assets.
* Software imports and updates now preserve package order and handle
multi-package titles more consistently.

* **Bug Fixes**
* Improved inheritance and validation for software fields so
package-level settings are respected and conflicting settings are
flagged.
* Fixed installer batch updates to better handle added, removed, and
reordered packages without disrupting related policies or pending
installs.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 12:42:36 -04: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
Carlo 2dd989cf06 Multiple packages API changes (#48607)
**Related issue:** Resolves #48397

  ## Summary

Adds the REST API layer for multiple custom packages per software title
(backend only):

- `GET /software/titles` and `GET /software/titles/:id` return a new
`packages[]` array; `software_package` is retained as the first-added
package for backwards compatibility.
- `POST /software/package` adds a package to an existing title and
returns the added package.
- `PATCH /software/titles/:id/package` targets a specific `installer_id`
and rejects a replacement whose hash matches a sibling package (409).
- `DELETE /software/titles/:id/available_for_install?installer_id=`
deletes one package; omitting `installer_id` deletes them all.

Builds on the data-model foundation (#48396). Install-time precedence
and the host-software endpoint are out of scope (#48398).

  # Checklist for submitter

  - [ ] Changes file added for user-visible changes in `changes/`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements).
- [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
2026-07-03 15:34:15 -04: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