This pull request updates the logic for selecting which user receives
maintenance window calendar events on hosts with multiple users. The
changes clarify and enforce a priority system for choosing the recipient
email, ensuring that IdP-sourced emails are preferred, followed by
Google Chrome profile emails. This affects both user-facing
documentation and backend implementation.
**User-facing behavior and documentation:**
* The end-user documentation now explicitly describes the email
selection priority for calendar event recipients: IdP Username email is
chosen first, then Google Chrome profile email, and if multiple Chrome
emails exist, the first alphabetically is selected.
**Backend logic and data selection:**
* The comment in `calendar_cron.go` is updated to match the new email
selection logic, explaining the prioritization of email sources for
host-user assignment.
* The SQL query in `policies.go` is refactored to implement the new
priority system for selecting user emails per host:
- IdP sources (`mdm_idp_accounts`, `idp`) are considered first,
- then Google Chrome profiles,
- then other sources.
- If multiple emails exist at the same priority, the first
alphabetically is chosen.
---------
Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com>
Co-authored-by: Juan Fernandez <juan-fdz-hawa@users.noreply.github.com>
Co-authored-by: Juan Fernandez <juan@fleetdm.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#39673
# 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
**Related issue:** Resolves#39361
This fixes an issue of the overflow of the resend button off the edge of
the os settting modal table.
We've changed the syling to grow and shrink the error text and column
dynamically so that the table will always be pushed up against the right
edge and the text will grow and shrink as needed so that it wont push
the button any further right
<img width="838" height="436" alt="image"
src="https://github.com/user-attachments/assets/a5acfd44-0d77-4062-92e4-909077827fee"
/>
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] QA'd all new/changed functionality manually
**Related issue:** Resolves#40066
This allows ipados and ios devices to resend their profiles on the host
details and my device pages
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] QA'd all new/changed functionality manually
**Related issue:** Resolves#39324
# 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)
## 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
For unreleased bug fixes in a release candidate, one of:
- [x] Confirmed that the fix is not expected to adversely impact load
test results
---------
Co-authored-by: Magnus Jensen <magnus@fleetdm.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#40685
# 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
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#40564
# 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
* **Chores**
* Added OpenTelemetry instrumentation to the internal HTTP client to
provide enhanced observability through distributed tracing and metrics
collection for HTTP operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#37802
Attempt to fix Windows FMAs not showing up as available when the
software titles they match to have upgrade codes. Since we don't surface
upgrade codes in the `fleet_maintained_apps` table and matching exactly
by name could miss some cases, this fix uses `team_titles.name LIKE
CONCAT(LEAST(fma.name, fma.unique_identifier), '%')`. Note the LEAST
there is only for the "Box Drive" app which has a longer name than
unique_identifier, and just compares the strings and not their length.
This isn't optimal for performance or correctness, but it only checks
with titles already available to the team as installers so it shouldn't
be terrible. Until upgrade_code is surfaced in the
`fleet_maintained_apps` table this should be sufficient.
# 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
**Related issue:** Resolves#14401
# Checklist for submitter
this updates the mechanism of storing the auth token for a user that is
used for making requests and validating a user session. We change the
storage from local storage to a cookie. This allow a bit more security
and prepares for a future change where we will allow the browser to
handle setting and passing the auth token in the request.
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** For #40433
# Details
This PR updates `fleetctl gitops` and `fleetctl generate_gitops` to use
`unassigned.yml` in place of `no-team.yml`. The two files are utilized
identically, except that `unassigned.yml` expects the `name:` to be
`Unassigned` rather than `No team`.
Internally, we still map some things to the string "no team" before
sending to the back end so that we don't have to update back-end code
and make more spaghetti to clean up when we 🔪 No Team as a concept in
Fleet 5.
We do pass the filename into the main `DoGitOps` method, but both I and
Claude did our best to determine that it's not used in any way that
would break with this change.
# 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
From test plan:
- [X] With a pre-existing GitOps folder w/ `no-team.yml`, run `fleetctl
gitops -f /path/to/no-team.yml --dry-run
--enable-log-topics=deprecated-field-names` and verify that everything
works as expected and you get the deprecation warning.
- [X] Do the above without `--dry-run` and verify via the UI and/or
`fleetctl generate-gitops` that the Fleet config is as expected.
- [X] Change `no-team.yml` to `unassigned.yml`, try a gitops run with
`fleetctl gitops -f /path/to/unassigned.yml --dry-run
--enable-log-topics=deprecated-field-names` and verify that you get an
error because the `name:` is still `No team`
- [X] Change the `name:` to `Unassigned`, repeat the run above and
verify that the output is the same as with `no-team.yml`, and that no
deprecation warning is listed.
- [X] Do the same as the above without `--dry-run` and verify that the
Fleet config is as expected.
- [X] Run `fleetctl generate-gitops` and verify that `unassigned.yml` is
output rather than `no-team.yml`, and any related files are under the
`lib/unassigned` folder rather than `lib/no-team`, and any paths inside
`unassigned.yml` (e.g. for scripts) are pointed at `lib/unassigned`.
## New Fleet configuration 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)
@noahtalerman will work on this
---------
Co-authored-by: Ian Littman <iansltx@gmail.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#40021
# 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`.
## 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 false positive detections for Python packages on Ubuntu systems,
addressing misclassification scenarios that were affecting package
detection accuracy on Ubuntu 20.04 and other versions.
* Enhanced handling of duplicate Python package entries to correctly
identify and consolidate multiple occurrences, preventing incorrect
over-reporting of installed packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
# 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
- [ ] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#38536
This PR moves all logic to create new activities to activity bounded
context.
The old service and ActivityModule methods are not facades that route to
the new activity bounded context. The facades will be removed in a
subsequent PR.
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added webhook support for activity events with configurable endpoint
and enable/disable settings.
* Enhanced automation-initiated activity creation without requiring a
user context.
* Improved activity service architecture with centralized creation and
management.
* **Improvements**
* Refactored activity creation to use a dedicated service layer for
better separation of concerns.
* Added support for host-specific and automation-originated activities.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Extended the statistics payload to include arrays of Fleet-maintained
app slugs in use on macOS and Windows. Updated the datastore to query
and populate these fields, and documented the new fields in the usage
statistics article.
---------
Co-authored-by: Juan Fernandez <juan@fleetdm.com>
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#35805
Fixed to make sure software host counts tables never have host counts of
0.
Planning to loadtest this fix along with the follow up fix for
https://github.com/fleetdm/fleet/issues/35799
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed accumulation of dead rows in software host count tracking,
improving data accuracy and system performance.
* Enhanced validation to ensure consistent and reliable software
availability records.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#15744
# 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
- [ ] 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
Manually inserted 10k hosts and random emails associated to them.
Response times were always below 200ms locally.
We already have covering indexes so we don't need a migration.
https://github.com/user-attachments/assets/721db4f1-f3c9-4ede-ba62-499ac30c4a02
SQL used:
```sql
-- Seed 10k hosts for performance testing email search.
-- Requires: SET cte_max_recursion_depth = 10000;
--
-- Distribution (by osquery_host_id suffix):
-- 1-2500: Chrome profile email only
-- 2501-5000: IdP email only
-- 5001-7500: Both Chrome profile and IdP emails
-- 7501-10000: No email association
-- Generate 10k hosts using a recursive CTE
INSERT INTO hosts (osquery_host_id, node_key, hostname, uuid, platform, detail_updated_at, label_updated_at, policy_updated_at)
WITH RECURSIVE seq AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM seq WHERE n < 10000
)
SELECT
CONCAT('perf-osq-', n),
CONCAT('perf-nk-', n),
CONCAT('perf-host-', n),
CONCAT('perf-uuid-', n),
'darwin',
NOW(),
'2000-01-01 00:00:00',
'2000-01-01 00:00:00'
FROM seq;
-- Populate display names so that hosts are visible in the UI.
INSERT INTO host_display_names (host_id, display_name)
SELECT id, hostname
FROM hosts
WHERE osquery_host_id LIKE 'perf-osq-%';
-- 1-2500: Chrome profile email only
INSERT INTO host_emails (host_id, email, source)
SELECT id, CONCAT('chrome-', id, '@example.com'), 'google_chrome_profiles'
FROM hosts
WHERE osquery_host_id LIKE 'perf-osq-%'
AND CAST(SUBSTRING(osquery_host_id, 10) AS UNSIGNED) BETWEEN 1 AND 2500;
-- 2501-5000: IdP email only
INSERT INTO host_emails (host_id, email, source)
SELECT id, CONCAT('idp-', id, '@example.com'), 'mdm_idp_accounts'
FROM hosts
WHERE osquery_host_id LIKE 'perf-osq-%'
AND CAST(SUBSTRING(osquery_host_id, 10) AS UNSIGNED) BETWEEN 2501 AND 5000;
-- 5001-7500: Both Chrome profile and IdP emails
INSERT INTO host_emails (host_id, email, source)
SELECT id, CONCAT('chrome-', id, '@example.com'), 'google_chrome_profiles'
FROM hosts
WHERE osquery_host_id LIKE 'perf-osq-%'
AND CAST(SUBSTRING(osquery_host_id, 10) AS UNSIGNED) BETWEEN 5001 AND 7500;
INSERT INTO host_emails (host_id, email, source)
SELECT id, CONCAT('idp-', id, '@example.com'), 'mdm_idp_accounts'
FROM hosts
WHERE osquery_host_id LIKE 'perf-osq-%'
AND CAST(SUBSTRING(osquery_host_id, 10) AS UNSIGNED) BETWEEN 5001 AND 7500;
-- 7501-10000: no emails (nothing to insert)
-- Cleanup:
-- DELETE FROM host_emails WHERE host_id IN (SELECT id FROM hosts WHERE osquery_host_id LIKE 'perf-osq-%');
-- DELETE FROM host_display_names WHERE host_id IN (SELECT id FROM hosts WHERE osquery_host_id LIKE 'perf-osq-%');
-- DELETE FROM hosts WHERE osquery_host_id LIKE 'perf-osq-%';
```
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#40054
# 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
* **Refactor**
* Updated internal logging infrastructure across Mobile Device
Management (MDM) service modules to improve code consistency and
maintainability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes#34068 Adds automatic retries (up to 3 attempts) for failed software installs from host details, self-service, and setup experience across all installer types.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#40124
# Details
Implements the proposal in
https://docs.google.com/document/d/16qe6oVLKK25nA9GEIPR9Gw_IJ342_wlJRdnWEMmWdas/edit?tab=t.0#heading=h.nlw4agv1xs3g
Allows doing e.g.
```go
logger.WarnContext(logCtx, "The `team_id` param is deprecated, use `fleet_id` instead", "log_topic", "deprecated-field-names")
```
or
```go
if logging.TopicEnabled("deprecated-api-params") {
logging.WithLevel(ctx, slog.LevelWarn)
logging.WithExtras(
ctx,
"deprecated_param",
queryTagValue,
"deprecation_warning",
fmt.Sprintf("'%s' is deprecated, use '%s'", queryTagValue, renameTo),
)
}
```
Topics can be disabled at the app level, and enabled/disabled at the
command-line level.
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
## Testing
- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
No logs have this in prod yet, but I added some manually in a branch and
verified that I could enable/disable them via CLI options and env vars,
including enabling topics that were disabled on the server. Tested for
both server and `fleetctl gitops`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Added per-topic logging control to enable or disable logging for
specific topics via configuration and CLI flags.
* Added context-aware logging methods (ErrorContext, WarnContext,
InfoContext, DebugContext) to support contextual logging.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#39858
~~Also implements the idea from this comment:
https://github.com/fleetdm/fleet/issues/37802#issuecomment-3715729822~~
Decided to move the FMA name overriding idea to another PR.
## Changes
- `getOrGenerateSoftwareInstallerTitleID` now attempts to find existing
titles by name or by upgrade code if possible. It will update the
upgrade code if possible.
- also updated `addSoftwareTitleToMatchingSoftware` to match _only_ by
upgrade code if the installer has an upgrade code
These are the assumptions (and tests mostly) I made:
| installer | existing title | result |
|------------------|-----------------------------------|----------------------------------------------------------------------------|
| no upgrade code | same name, no upgrade code | uses existing |
| no upgrade code | same name, has upgrade code | uses existing,
existing upgrade code stays |
| has upgrade code | same name, no upgrade code | uses existing,
existing title is updated with the incoming upgrade code |
| has upgrade code | same name, different upgrade code | new title is
created with same name |
| has upgrade code | same name, same upgrade code | uses existing |
| has upgrade code | different name, same upgrade code | uses existing,
~~existing title's name is updated~~ |
# 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
- [ ] 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
- Tested having the title `7-Zip 23.01 (x64)` with an upgrade code in
the db, added 7-Zip FMA, title became the existing `7-Zip 23.01 (x64)`
title with the same upgrade code.
- Trying to add it again fails with the correct error message
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#34370
<img width="932" height="1152" alt="Screenshot 2026-02-20 at 8 23 49 AM"
src="https://github.com/user-attachments/assets/c7b6d0ae-a20e-4115-835d-5d5fb01c12bb"
/>
- [x] Changes file added for user-visible changes in `changes/`
- [x] QA'd all new/changed functionality manually
https://github.com/shogo82148/rdsmysql/pull/222
Adds AWS GovCloud RDS CA certificates (us-gov-east-1, us-gov-west-1) to
the rdsmysql TLS bundle, improving compatibility for Fleet deployments
in AWS GovCloud regions.
Transitive dependency updates pulled in by rdsmysql v2.5.0:
- github.com/aws/aws-sdk-go-v2 and related submodules (minor bumps)
- github.com/go-sql-driver/mysql v1.9.1 -> v1.9.3
- filippo.io/edwards25519 v1.1.0 -> v1.1.1
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves
https://github.com/fleetdm/fleet/issues/40148
## 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
— dependency bump only; ran full local test suite across all affected
packages (`server/platform/mysql`, `server/logging`, `server/config`,
`server/mail`) with no regressions. `go mod verify` passed.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#40028
# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
## Testing
- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Bug Fixes**
* Fixed telemetry misclassification where client-side errors were
incorrectly reported as server errors. Client-side errors and request
cancellations are now properly categorized for improved error tracking
and observability.
* **Tests**
* Added test coverage for client error detection and context
cancellation handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** For #39344
# Details
This PR builds on the previous PR
(https://github.com/fleetdm/fleet/pull/39847) which added `renameto`
tags to certain API parameters to mark them as deprecated. How this is
used:
### In requests
* When decoding requests, log a warning if a `json` or `query` param is
used that has a `renameto` tag, e.g. if a `team_id` param is sent but
the related struct has `renameto:"fleet_id"` in it.
* If the `renamedto` version (e.g. `fleet_id`) is sent in the request,
rewrite it to the deprecated name so that it can be unmarshalled into
the struct
* If both versions are sent (e.g. `team_id` AND `fleet_id`), throw an
error and quit
* URLs with deprecated terms have new aliases using `WithAltPaths` --
warning on using old URLSs a TODO that will be handled in a subsequent
PR.
### In responses
* Output _both_ the deprecated and new names for fields that have
`renameto` tags, so that we don't break existing workflows expecting the
old keys. Uses a shared `DuplicateJSONKeys` to do the duplication.
* Most API responses are handled in `EncodeCommonResponse`. Exceptions
are activities, failing policy webhooks and the streaming "list hosts"
endpoints which call the function directly.
### In fleetctl
* Similar to requests, log warnings when deprecated keys are used and
rewrite the new keys internally so that they can be unmarshalled.
* For `fleetctl get` and `fleetctl generate-gitops`, _only_ output the
new names
* The set of keys to replace is hardcoded in `fleetctl` rather than
being dynamically generated as it is for API endpoints. Given the
mixture of typed and untyped data and the level of nesting, dynamic map
generation was very fragile and error-prone.
### Performance considerations
* The biggest performance hit is the addition of the JSON key rewriter
to the request pipeline. The rewriter buffers the entire request into
memory before eventually passing it to the decoder than unmarshals the
data into structs. I tried implementing this as a true streaming
rewriter but encountered issues where the request would hang if the
downstream reader (the decoder) encountered any errors. It's possible we
could implement this in a streaming fashion if we replace our [current
request
decoder](https://github.com/fleetdm/fleet/blob/da43bf8371695382c4af0972d5da456c6b94bdaf/server/service/endpoint_utils.go#L108)
with the v2 version, which is a bigger change requiring more thoughtful
discussion in the engineering team. As it stands, memory usage for
requests with deprecated fields will double while the request is being
decoded.
* The "alias rules" used to determine the old and new key names are
cached per struct type and for most endpoints are generated on server
start, so no performance impact is expected.
* Some `fleetctl` commands may have an extra unmarshal/marshal step but
as these are user-initiated and not performed in tight loops, the impact
should be minimal.
### TODO
* Log deprecation warnings when old URLs like "/fleet/teams" are used
* Update API fields that the front-end uses to avoid deprecation
warnings
* Update `fleetctl apply` to accept/return `kind: fleet` rather than
`kind: team`
* Find/update any fleet server config vars with old language
* Update all error messages that use old language
# 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)
## 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
* Clicking around the front-end, no broken pages due to request
ingestion errors or bad responses
* Looking in network tab to verify that responses have both the old and
new keys
* Running `fleetctl generate-gitops` and verifying that the output looks
correct and can be ingested by `fleetctl gitops`
* Running `fleetctl get` and `fleetctl apply`
---------
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
#39921
Summary of fixes:
- Removed unnecessary calls to `BulkSetPendingMDMHostProfiles` when
settings are unchanged.
- Removed 3 unnecessary calls to `BulkSetPendingMDMHostProfiles` when
the Apple OS updates are unset.
- [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)
## Testing
- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#37306
I think we should actually solve this at the osquery level, but this is
just an alternative solution.
# 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
#### Setup
On a macOS VM:
1. Generated a certificate with Cyrillic characters in CN and O fields:
```bash
openssl req -x509 -newkey rsa:2048 -keyout newkey.pem -out newcert.pem -days 365 -nodes -utf8 -subj "/CN=АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯа/O=АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯа"
```
2. Installed the certificate:
```bash
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain newcert.pem
```
#### Before
Refetched vitals and observed certificate field too long error logs:
```
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=subject_org host_id=32 original_length=304 max_length=255 truncated_value=\xC3\x90\xC2\xA2\xC3\x90\xC2\xB5\xC3\x91\xC2\x81\xC3\x91\xC2\x82\xC3\x90\xC2\xBE\xC3\x90\xC2\xB2\xC3\x90\xC2\xB0\xC3\x91\xC2\x8F\xC3\x90\xC2\x9E\xC3\x91\xC2\x80\xC3\x90\xC2\xB3\xC3\x90\xC2\xB0\xC3\x90\xC2\xBD\xC3\x90\xC2\xB8\xC3\x90\xC2\xB7\xC3\x90\xC2\xB
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=subject_common_name host_id=32 original_length=304 max_length=255 truncated_value=\xC3\x90\xC2\xA2\xC3\x90\xC2\xB5\xC3\x91\xC2\x81\xC3\x91\xC2\x82\xC3\x90\xC2\xBE\xC3\x90\xC2\xB2\xC3\x90\xC2\xB0\xC3\x91\xC2\x8F\xC3\x90\xC2\x9E\xC3\x91\xC2\x80\xC3\x90\xC2\xB3\xC3\x90\xC2\xB0\xC3\x90\xC2\xBD\xC3\x90\xC2\xB8\xC3\x90\xC2\xB7\xC3\x90\xC2\xB
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=issuer_org host_id=32 original_length=304 max_length=255 truncated_value=\xC3\x90\xC2\xA2\xC3\x90\xC2\xB5\xC3\x91\xC2\x81\xC3\x91\xC2\x82\xC3\x90\xC2\xBE\xC3\x90\xC2\xB2\xC3\x90\xC2\xB0\xC3\x91\xC2\x8F\xC3\x90\xC2\x9E\xC3\x91\xC2\x80\xC3\x90\xC2\xB3\xC3\x90\xC2\xB0\xC3\x90\xC2\xBD\xC3\x90\xC2\xB8\xC3\x90\xC2\xB7\xC3\x90\xC2\xB
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=issuer_common_name host_id=32 original_length=304 max_length=255 truncated_value=\xC3\x90\xC2\xA2\xC3\x90\xC2\xB5\xC3\x91\xC2\x81\xC3\x91\xC2\x82\xC3\x90\xC2\xBE\xC3\x90\xC2\xB2\xC3\x90\xC2\xB0\xC3\x91\xC2\x8F\xC3\x90\xC2\x9E\xC3\x91\xC2\x80\xC3\x90\xC2\xB3\xC3\x90\xC2\xB0\xC3\x90\xC2\xBD\xC3\x90\xC2\xB8\xC3\x90\xC2\xB7\xC3\x90\xC2\xB
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=subject_org host_id=32 original_length=256 max_length=255 truncated_value=\xD0\x90\xD0\x91\xD0\x92\xD0\x93\xD0\x94\xD0\x95\xD0\x96\xD0\x97\xD0\x98\xD0\x9A\xD0\x9B\xD0\x9C\xD0\x9D\xD0\x9E\xD0\x9F\xD0\xA0\xD0\xA1\xD0\xA2\xD0\xA3\xD0\xA4\xD0\xA5\xD0\xA6\xD0\xA7\xD0\xA8\xD0\xA9\xD0\xAA\xD0\xAB\xD0\xAC\xD0\xAD\xD0\xAE\xD0\xAF\xD0\xB
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=subject_common_name host_id=32 original_length=256 max_length=255 truncated_value=\xD0\x90\xD0\x91\xD0\x92\xD0\x93\xD0\x94\xD0\x95\xD0\x96\xD0\x97\xD0\x98\xD0\x9A\xD0\x9B\xD0\x9C\xD0\x9D\xD0\x9E\xD0\x9F\xD0\xA0\xD0\xA1\xD0\xA2\xD0\xA3\xD0\xA4\xD0\xA5\xD0\xA6\xD0\xA7\xD0\xA8\xD0\xA9\xD0\xAA\xD0\xAB\xD0\xAC\xD0\xAD\xD0\xAE\xD0\xAF\xD0\xB
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=issuer_org host_id=32 original_length=256 max_length=255 truncated_value=\xD0\x90\xD0\x91\xD0\x92\xD0\x93\xD0\x94\xD0\x95\xD0\x96\xD0\x97\xD0\x98\xD0\x9A\xD0\x9B\xD0\x9C\xD0\x9D\xD0\x9E\xD0\x9F\xD0\xA0\xD0\xA1\xD0\xA2\xD0\xA3\xD0\xA4\xD0\xA5\xD0\xA6\xD0\xA7\xD0\xA8\xD0\xA9\xD0\xAA\xD0\xAB\xD0\xAC\xD0\xAD\xD0\xAE\xD0\xAF\xD0\xB
ts=2026-02-18T21:50:47Z level=error msg="truncating certificate field" err="certificate field too long" field=issuer_common_name host_id=32 original_length=256 max_length=255 truncated_value=\xD0\x90\xD0\x91\xD0\x92\xD0\x93\xD0\x94\xD0\x95\xD0\x96\xD0\x97\xD0\x98\xD0\x9A\xD0\x9B\xD0\x9C\xD0\x9D\xD0\x9E\xD0\x9F\xD0\xA0\xD0\xA1\xD0\xA2\xD0\xA3\xD0\xA4\xD0\xA5\xD0\xA6\xD0\xA7\xD0\xA8\xD0\xA9\xD0\xAA\xD0\xAB\xD0\xAC\xD0\xAD\xD0\xAE\xD0\xAF\xD0\xB
```
https://github.com/user-attachments/assets/31b80643-34fb-42ee-b3a1-19d54fe1d516
#### After
https://github.com/user-attachments/assets/d49c1643-0920-4607-a2f1-fa6bb658c16b
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#38699
The fix will only apply to new Fleet instances. To fix existing Fleet
instances, we need to support rotation:
https://github.com/fleetdm/fleet/issues/40080
# 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`.
## Testing
- [x] QA'd all new/changed functionality manually
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#38351
# 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
- Including Okta conditional access
## 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**
* Device authentication tokens now remain valid after automatic refresh,
keeping your Device page URL accessible
* Device tokens are automatically generated when needed during
conditional access authentication
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#35528
Potentially #38983
I avoided adding a migration to fix existing bad platform data. However
a small migration is needed to convert software titles with the source
"pkg_packages" that have a bundle id, to the source "apps".
### Changes
To get an installer with the wrong platform fixed:
- Remove then add back the .pkg installer that showed the wrong platform
to see it create a new title with the correct platform
To get hosts that report the wrong platform in inventory/library fixed:
- Devices would still show the app with the wrong platform in
inventory/library. This happens because there are still entries in
`software` that match the incorrect previous title. All of these entries
need to be deleted for this bug to be fixed. One way for this to happen
is for all hosts with that app to remove it then wait for refetch and
the `vulnerabilities` cron, or be deleted directly in the database where
they should get restored after new refetches.
# 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)
- [ ] 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
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#39871
# 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)
- [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
# 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
For unreleased bug fixes in a release candidate, one of:
- [x] Confirmed that the fix is not expected to adversely impact load
test results
Note: this solves https://github.com/fleetdm/fleet/issues/39832
---------
Co-authored-by: Scott Gress <scott@fleetdm.com>
Co-authored-by: Scott Gress <scottmgress@gmail.com>
**Related issue:** Resolves#38955
The query that was causing the lock contention was identified as `DELETE
FROM host_mdm_apple_profiles WHERE ( profile_identifier , host_uuid ) IN
( (...) /* , ... */ )` which corresponds to the query we use to delete
the Apple profiles in Bulk. The query was refactored to utilize the
primary key: (profile_uuid, host_uuid), which removes any kind of table
scanning.
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** Resolves#39260
# Details
Fixes the banner displayed when a team has no enroll secrets to match
similar, non-dismissible warning banners, and corrects the padding
between text and button in the "Add enroll secret" modal empty state.
<img width="773" height="221" alt="image"
src="https://github.com/user-attachments/assets/490f49f1-ccaa-47c7-8ba3-a7de2896d932"
/>
---
<img width="662" height="380" alt="image"
src="https://github.com/user-attachments/assets/0f73b9b8-d625-4f40-ac8d-edb71e9f2a22"
/>
# 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
- [ ] Added/updated automated tests
n/a, styling only
- [X] QA'd all new/changed functionality manually
See screenshots above