bf26771ff1301d611beadf18ce9e6a566bba301c
5391
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2fd2a02e2d |
Split MDM platform helpers by Android semantics (#50185)
**Related issue:** Resolves #46118 |
||
|
|
cb44e287f2 | Fix high-severity CodeQL and Scorecard code scanning alerts (#50333) | ||
|
|
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 --> |
||
|
|
60e6827071 |
Fix Apple built-in label memberships during ADE (#50287)
**Related issue:** Resolves #50285 ## Summary - Restore the `All Hosts` and Apple platform built-in label memberships in the same transaction that clears stale host state during Automated Device Enrollment (ADE). - Backfill missing built-in memberships for existing macOS, iOS, and iPadOS hosts. - Add regression coverage confirming that an iPadOS update declaration remains targeted and reaches verified status after the enrollment reset. # 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] 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 host's records do not affect another) - [ ] QA'd all new/changed functionality manually Automated verification: ```sh MYSQL_TEST=1 go test -run 'TestMDMApple/MDMAppleResetOnReenrollment' ./server/datastore/mysql MYSQL_TEST=1 go test -run TestUp_20260731100711 ./server/datastore/mysql/migrations/tables MYSQL_TEST=1 go test -run 'TestIntegrationsMDM/TestIPadOSUpdateDeclarationAfterMDMReset' ./server/service go test -run TestMDMTokenUpdateResetOnReenrollment ./server/service go vet ./server/datastore/mysql ./server/service go build ./server/datastore/mysql/migrations/... make test-schema ``` ## Database migrations - [x] Checked schema for all modified tables for columns that auto-update timestamps during migration. - [x] Confirmed that timestamp behavior is acceptable and will not cause unwanted side effects. The migration inserts only missing memberships and leaves existing membership timestamps unchanged. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Apple devices now retain their built-in label memberships after Automated Device Enrollment or MDM reset. * Label-scoped profiles, software, and operating system updates can now continue to be delivered after a reset. * Platform-specific memberships are restored for macOS, iOS, and iPadOS devices, including applicable hosts with unspecified platforms. * iPadOS update declarations now reconcile successfully after an MDM reset. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7f1b330c90 |
Restrict deleting a fleet to global admins (#50271)
# 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 * **Bug Fixes** * Restricted fleet deletion to users with global write permissions, including global administrators and GitOps. * Corrected team deletion authorization to require global write access. * Prevented global technicians, team technicians, and observer-level users from deleting teams. * Updated authorization behavior to consistently enforce the required access level. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9d0f510a8d |
Add DDM custom activations schema (#50133)
**Related issue:** Resolves #49966 Adds the schema for custom DDM activations (parent story #48222). - **Creates `mdm_apple_ddm_activations`** — stores the activation JSON as-is (`mediumtext`, so the generated `token` column hashes the exact stored bytes) with a `declaration_uuid` FK to `mdm_apple_declarations` that cascades on delete. - **Extends `mdm_configuration_profile_variables`** with `apple_ddm_activation_uuid` so activations can carry Fleet variables (needed by #49970). - **Adds `activation_updated_at`** to `host_mdm_apple_declarations` so a changed activation regenerates the declaration's effective token, mirroring `variables_updated_at` / `assets_updated_at`. - **Drops `mdm_apple_declaration_activation_references`** — created with the original DDM tables in `20240327115530_AddDDMTables.go`, never written to by any code path, so it is empty in every deployment. ### Deviations from the SQL in #49966 The `declaration_uuid` FK is the one addition, [confirmed with @MagnusHJensen](https://github.com/fleetdm/fleet/issues/49966): it keeps the 1:1 lifecycle enforced by the database rather than requiring cleanup in every delete path. `configuration_identifier` is kept alongside it for validation and DDM serving. Its unique key doubles as the FK's backing index. The rest are corrections needed for the specced SQL to work, all following the precedent in `20260409153715_AddDDMVariablesSupport.go`: - **`ck_mdm_configuration_profile_variables_exactly_one` is dropped and re-added** to count the new column. That constraint requires exactly one owner column to be non-null; adding a seventh without updating it means any row setting `apple_ddm_activation_uuid` sums to 0, fails the check, and is rejected. - **`UNIQUE (apple_ddm_activation_uuid, fleet_variable_id)` added** to match the six existing owner columns. That table's write path is `INSERT ... ON DUPLICATE KEY UPDATE`, which needs a unique key to collide on. - **`activation_updated_at` is `DATETIME(6)`, not `TIMESTAMP(6)`** — its siblings are `datetime(6)` and `EffectiveDDMToken` formats them into the token string, so `TIMESTAMP`'s session-timezone conversion on read would change tokens and re-push declarations to every host. - **`team_id` gets `DEFAULT '0'`** to match `mdm_apple_declarations`, where 0 is Unassigned. ### Note for #49970 `declaration_uuid` is `NOT NULL`, so the upload path must populate it in addition to `configuration_identifier`. The declaration UUID prefix has no separator (`MDMAppleDeclarationUUIDPrefix = "d"`, 1 char + 36-char UUID = the full `varchar(37)`). # 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. No changes file: this sub-task adds schema only and ships no user-visible behavior. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually `TestUp_20260729115013` covers: the stale table is present before and gone after; pre-existing `mdm_configuration_profile_variables` rows survive the check constraint replacement (that `ADD CONSTRAINT` revalidates every existing row); an activation attaches to a declaration and gets its generated token; the 1:1 unique key and the FK both reject bad inserts; a variable row binds to an activation (the case the old constraint would have rejected); the constraint still rejects two-owner and zero-owner rows; and deleting the declaration cascades to the activation and through it to the activation's variable rows. Also ran the full migrations suite (`MYSQL_TEST=1 go test ./server/datastore/mysql/migrations/...`) to confirm no other migration is disturbed, and verified the regenerated `schema.sql` diff contains only changes from this migration. ## 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`). Neither modified table has an `ON UPDATE CURRENT_TIMESTAMP` column, so no rows have their timestamps touched. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for Apple DDM custom activations. * Added activation-specific tokens and timestamps to support reliable declaration updates. * Enabled configuration variables to be associated with a specific activation. * Added validation to prevent duplicate or invalid activation associations. * Activations and related settings are now automatically removed when their declaration is deleted. * **Tests** * Added coverage for activation creation, uniqueness, validation, associations, token generation, and cascading cleanup. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
294a172d11 |
Clarify maintained app download timeout errors (#50104)
**Related issue:** Resolves #48416 When adding a Fleet-maintained app, a large-installer download that's canceled or times out now returns a clear message pointing at the likely proxy/load-balancer timeout, instead of a raw `context canceled`. # 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 * **Bug Fixes** * Improved error messages when adding Fleet-maintained apps times out or is canceled during large installer downloads. * Added clearer guidance for configuring server, proxy, and load balancer timeouts. * Properly handles additional timeout and upstream cancellation responses, including HTTP 408, 499, and 504. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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. |
||
|
|
e5b0f313f9 |
Fix password reset accepting case-mutated tokens
Reset tokens are base64url (case-sensitive) but the password_reset_requests.token column used case-insensitive utf8mb4_unicode_ci, so a case-mutated token copy still matched. Switch the column to utf8mb4_bin for byte-exact comparison. |
||
|
|
8a65ecf20b | Bound Android device reconciliation pagination loop (#49615) | ||
|
|
dcefd13130 |
Stop leaking live query campaign existence via the websocket results stream (#50210)
# 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 * **Bug Fixes** * Standardized websocket error responses when requested campaigns are unavailable. * Prevented campaign existence from being inferred through differing error messages. * Improved consistency for both nonexistent campaigns and campaigns inaccessible to the current user. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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> |
||
|
|
1397531199 |
Authorize packs before returning them in query responses (#50148)
- [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** * Query responses now include pack details only when the requester has permission to view them. * Prevented pack metadata from being disclosed across fleets when query names overlap. * Corrected target selection labels and empty-state messaging for fleet-based targets. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1a0f0101cc |
Fix gitops not updating FMA installer (#50000)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49811 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] Timeouts are implemented and retries are limited to avoid infinite loops - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed Fleet-maintained app updates when a rebuilt installer keeps the same version. * Rebuilt installers now update their files, hashes, filenames, and install scripts correctly. * Prevented installers from being incorrectly skipped when their contents differ despite matching versions. * **Tests** * Added coverage for same-version installer rebuilds and team-specific caching behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e6118b4cc5 |
extra error message checks and correct escaping in error message (#50136)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #40074 unreleased bug <img width="539" height="141" alt="image" src="https://github.com/user-attachments/assets/1ac8e2c2-236d-4567-a200-0eb35cce46e7" /> # 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 - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved configuration profile validation for unescaped special characters in Apple payloads. * Error messages now consistently indicate when characters like `&` and `<` must be XML-escaped. * Updated error examples to show properly escaped guidance. * Expanded test coverage to verify the standardized XML-escaping error for additional failing scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9c2ef14947 |
Scrub device policy responses in Fleet Desktop (#50094)
- [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] 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 * **Security Improvements** * Updated device-authenticated policy and host-detail responses to omit policy author identity fields and any raw SQL/query data. * Device policy endpoints now return a device-safe policy representation consistently. * **Bug Fixes** * Prevented administrative policy information from appearing in device-authenticated host details and policy listings. * **Tests** * Strengthened integration coverage to verify device-safe responses (required user-facing fields present; sensitive fields absent). <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
f5ca4b5b0d |
Add Android support for custom host vitals (#49696)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49421 Custom host vitals (`$FLEET_HOST_VITAL_<id>`) already worked in scripts and Apple/Windows configuration profiles, but Android configuration profiles and managed app configuration explicitly rejected them at upload to keep parity with `$FLEET_SECRET_*`. This left admins unable to inject per-host vitals (e.g. an asset tag) into Android MDM configuration the same way they can for every other platform. For more context, prior PRs: - https://github.com/fleetdm/fleet/pull/49334 - https://github.com/fleetdm/fleet/pull/49586 # 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 - Created an "Asset tag" host vital. - Enrolled an Android device. - Initially the test profile showed as "Failed" because no value was set for the vital. - Set a value for the vital, saw that it went from Enforcing to Verified. <img width="1446" height="510" alt="Screenshot 2026-07-24 at 8 57 46 AM" src="https://github.com/user-attachments/assets/c0e2348c-e521-48f3-85cd-6f884689b2cd" /> <img width="1520" height="936" alt="Screenshot 2026-07-24 at 8 56 56 AM" src="https://github.com/user-attachments/assets/169b9545-ec7a-429b-8f45-0e2740f61c77" /> <img width="1607" height="1136" alt="Screenshot 2026-07-24 at 8 57 30 AM" src="https://github.com/user-attachments/assets/a8213745-b224-4a36-a54d-32152a15c377" /> Also tested the rejection cases: - trying to upload a profile with an invalid custom host vital id (either a non-numeric value, a numeric but non-existent ID, and referencing a vital as a JSON key instead of a value) - deleting a vital referenced in a profile https://github.com/user-attachments/assets/e8b4acde-ddf4-41c0-b00a-5ab4945d0bc2 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Android app configurations and profiles now support custom host vital placeholders (`$FLEET_HOST_VITAL_<id>`). * Custom host vital values are expanded per device during Android delivery. * Managed Android profiles/configurations are automatically resent when a referenced vital value changes. * **Bug Fixes** * Added validation for malformed, missing, or undefined vital references during Android app association and profile/config uploads. * Prevented deletion of vitals referenced by Android profiles. * Improved error handling and delivery failure details when a device lacks a required vital value. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5983f9de40 |
Require Fleet MDM enrollment before escrowing macOS disk encryption key (#50042)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48965 ## Description Fleet was escrowing a macOS disk encryption key — and logging an "escrowed a disk encryption key" activity — for hosts that aren't enrolled in Fleet's MDM (e.g. still managed by Jamf, or with a leftover `/var/db/FileVaultPRK.dat`). Because Fleet never installed its FileVault escrow profile on such a host, the stored key is unusable: the cron marks it `decryptable = 0` and `GET /hosts/:id/encryption_key` returns 422, so "Show disk encryption key" never appears. The result is a misleading activity and a dead key row. Root cause: the macOS key ingestion (`directIngestDiskEncryptionKeyFileDarwin` and its `file_lines` fallback) gated only on the disk being encrypted and disk encryption being enabled for the host's team — it never checked Fleet MDM enrollment. The Windows/orbit key path (`SetOrUpdateDiskEncryptionKey`) already performs this check. - **`server/service/osquery_utils/queries.go`** — added an `IsHostConnectedToFleetMDM` guard to both macOS ingestion functions, skipping archival (no key stored, no activity) when the host isn't connected to Fleet MDM. Mirrors the existing Windows path. Prevention only — this stops new bad escrows; it does not delete keys previously escrowed for non-enrolled hosts. ## Testing - **Unit** (`queries_test.go`): added a "host not connected to Fleet MDM" case asserting neither ingestion function escrows when the host isn't Fleet-MDM-connected, and initialized the `IsHostConnectedToFleetMDM` mock so existing cases still pass. - **Integration** (`integration_mdm_test.go`): `TestMDMAppleHostDiskEncryptionWithDisabledEncryptionSetting` was creating an orbit-only host (no Fleet MDM) and expecting escrow to succeed — i.e. relied on the bug. Switched it to a Fleet-MDM-enrolled host (`createHostThenEnrollMDM`), which is now required for escrow. Passes. # 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 - [ ] QA'd all new/changed functionality manually <!-- covered by automated integration test; live no-device repro is impractical, flagged for reviewer --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - FileVault recovery keys are now archived/escrowed only for macOS hosts that are connected to Fleet MDM. - Hosts without an active Fleet MDM connection no longer attempt to archive encryption keys. - Disk-encryption key archival now cleanly reports MDM connectivity errors when checks fail. - **Tests** - Added/updated coverage to verify both connected and disconnected host scenarios, including ensuring no archival occurs when MDM is not connected. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
f1228c873d |
47713 auld software update assets migration (#50036)
**Related issue:** Resolves #47713 - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for tracking available Apple OS update assets and supported devices. * Added per-host Apple OS update targets, deadlines, and resolution status. * Added configuration options for host target OS versions and deadlines. * **Database** * Updated the MySQL schema and migration seed data to include the new tables and fleet variables, and to reflect updated migration/status metadata. * **Tests** * Added migration tests to validate table creation, constraints, defaults, and upsert behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
0504e5949e |
Add host_id and host_serial to Apple mdm_enrolled activity (#49969)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49777 ## Description Adds `host_id` and `host_serial` to the Apple `mdm_enrolled` activity so IT admins can build automations on top of it, and surfaces the activity on the individual host's activity timeline. - **`server/fleet/activities.go`** — added `HostID` to `ActivityTypeMDMEnrolled` and a `HostIDs()` method (mirrors the existing `ActivityTypeMDMUnenrolled` pattern), so the activity is linked to the host and appears on its timeline. - **`server/mdm/lifecycle/lifecycle.go`** — populate `host_id` for macOS/iOS/iPadOS enrollments. Account-driven user (BYOD) enrollments have no hardware serial, so they report the enrollment ID as `host_serial` too, keeping `host_serial` populated for automations regardless of enrollment type. - **Frontend** — new `MdmEnrolledActivityItem` component, registered in the host past-activity component map (and the `IHostPastActivityType` union), renders the now-host-linked `mdm_enrolled` activity on the host details **Activity** card. There's no Figma, so the copy mirrors the sibling `mdm_unenrolled` item (e.g. "Mobile device management (MDM) was turned on for this host"). `host_id` uses `omitempty`, so Windows (`microsoft_mdm.go`) enrollments keep their existing activity payload unchanged — Windows is intentionally out of scope, handled in #47874, which also owns the audit-log documentation update for the shared field. > **For reviewer:** the ADUE `host_serial = enrollment_id` behavior comes from the issue's test plan. It means `host_serial` and `enrollment_id` carry the same value for BYOD. Flagging in case Product would rather leave `host_serial` empty for ADUE and have automations read `enrollment_id`. ## Testing - **Automated:** `TestMDMEnrolledActivityHostIDAndSerial` (`server/mdm/lifecycle`) covers device enrollment (`host_serial` = hardware serial) and ADUE (`host_serial` = enrollment ID), both asserting `host_id`/`HostIDs()`. Also verified `server/datastore/mysql` `TestMDMEnrollment`, `server/activity/internal/mysql` `TestListActivities`, and `server/service` `TestMDMTokenUpdate*` pass. - **Live (simulated) manual macOS enrollment** via `osquery-perf`: the `mdm_enrolled` activity recorded `host_id` + `host_serial`, and an `activity_host_past` row linked it to the host (confirmed it shows on the host timeline). - **Frontend:** `MdmEnrolledActivityItem.tests.tsx` covers the rendered copy for macOS/iOS/Android and the actor/no-actor variants; also visually confirmed the activity renders on a host's Activity card in the running app. `yarn jest`, `eslint`, and `tsc` pass. - Updated the MDM integration tests (`integration_mdm_test.go`, `integration_mdm_dep_test.go`, `integration_vpp_install_test.go`) whose activity-detail and host-feed assertions changed now that `mdm_enrolled` carries `host_id` and appears on the host timeline (feed assertions now filter by activity type). - **Pending on-device QA (next week):** DEP/ADE macOS and account-driven user enrollment (iOS/iPadOS) on real hardware, per the issue's test plan. - Regression: Windows `mdm_enrolled` payload is unchanged (`host_id` is omitted when zero); both platforms' `mdm_unenrolled` are unaffected. # Screenshot for the frontend change <img width="706" height="382" alt="Screenshot 2026-07-28 at 11 16 57 AM" src="https://github.com/user-attachments/assets/8f57d129-f819-4399-8754-18b397a49db8" /> # 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. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually <!-- manual macOS verified via simulator; DEP + real-device ADUE pending next week --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Added support for rendering “MDM enrolled” in the host activity feed with platform- and actor-aware messaging. * **Bug Fixes** * Updated Apple “MDM enrolled” activity details to include the correct host identifier and serial/enrollment identifiers. * Ensured host-scoped activity behavior applies only when the host is known (host id present). * **Tests** * Expanded regression and integration coverage for “MDM enrolled” activity details and feed contents, including VPP-related assertion stability. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Magnus Jensen <magnus@fleetdm.com> |
||
|
|
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> |
||
|
|
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 --> |
||
|
|
19efda2d1b |
Windows SCEP profiles now fail with non-printable chars (#49887)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47492 Windows cert profile fails if challenge uses non-printable characters. <img width="987" height="329" alt="image" src="https://github.com/user-attachments/assets/04dc7c78-8e3e-41c8-823e-cb4a961a91eb" /> # 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 ## Summary by CodeRabbit * **Bug Fixes** * Windows SCEP profiles now fail with a clear error when the certificate authority challenge includes characters not supported by Windows ASN.1 PrintableString. * Prevents misleading “Verified” status when no certificate is installed. * Preserves valid challenge values, including leading/trailing spaces. * Improves Windows error tooltips by showing raw certificate-install error details. * **Tests** * Added coverage for invalid/valid Windows SCEP challenge scenarios and the updated error tooltip behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
89f67544b4 |
Add support for fleet vars in scripts(controls scripts, software scripts/script-only packages and setup experience scripts) (#49781)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49511 and #46837 as a whole # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for Fleet built-in variables in host scripts, software installer scripts, setup-experience scripts, and maintained-app installer scripts. * Variables are resolved per host at execution time; saved content remains unexpanded. * **Bug Fixes** * Requests now validate Fleet variables up-front, with clear script-specific error messages for unsupported variables. * Added improved messaging when variable resolution fails during execution. * Enforced Fleet Premium licensing for script/installer flows that use Fleet variables. * **Documentation** * Documented supported variables and Premium requirements, including usage examples. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5c127e5fe4 |
Fix software ingestion lock convoys and unbatched deletes (#49894)
**Related issue:** Resolves #49805, Resolves #48719 # 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 ## 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 --- ## Context A customer (~2,500 hosts, v4.89.1) had their DB writer slammed with `DELETE FROM host_software_installed_paths` statements carrying 30,000+ IDs each. These never completed, required repeated manual intervention, and the table grew from 14.5M to 14.8M rows in 2 days. This is #49805. While investigating, Victor linked #48719, a related `software_titles` INSERT lock convoy issue seen in load tests. Both are in the same software ingestion code path (`server/datastore/mysql/software.go`), so this PR fixes both. ## Root cause ### #49805: Unbatched DELETEs on `host_software_installed_paths` When a host's software changes, Fleet computes a delta and deletes stale rows from `host_software_installed_paths`. The function `deleteHostSoftwareInstalledPaths()` issued a **single** `DELETE FROM host_software_installed_paths WHERE id IN (?)` with all IDs expanded by `sqlx.In()`. With 30,000+ IDs and 14.8M rows in the table, these massive statements held row locks for minutes, timed out, and never completed. On the next agent check-in, the same (or larger) DELETE was retried, creating a feedback loop where the table grew unboundedly. Notably, the INSERT function for the same table (`insertHostSoftwareInstalledPaths`) already batched at 500 rows. The DELETE simply lacked the same treatment. ### #48719: INSERT IGNORE lock convoys on `software_titles` (related) When a host reports software that Fleet hasn't seen before, `preInsertSoftwareInventory()` runs `INSERT IGNORE INTO software_titles (...)` inside a `withRetryTxx` transaction. For homogeneous fleets (many hosts sharing the same software catalog, typical for imaged corporate Windows machines), hundreds of concurrent goroutines try to INSERT IGNORE the same title rows simultaneously. Even though `INSERT IGNORE` is a no-op when the row already exists, InnoDB still acquires row/gap locks on the unique index for the duration of the enclosing transaction. With many goroutines holding or waiting on the same index locks, the DB enters a "lock convoy" where sessions serialize on locks they don't actually need. In load tests (40 Fleet instances, 100K hosts, 141 identical Windows software items), this produced 690 average active sessions on the writer and 85s fleet-wide p99. The existing read-first check (`getIncomingSoftwareChecksumsToExistingTitles`) prevents the convoy at steady state. But on cold start (empty `software_titles`, e.g. after cleanup purges orphaned titles), the check finds nothing and all goroutines race to INSERT the same titles. ## How I reproduced it Started MySQL via `docker compose up -d mysql_test`, created a git worktree. ### #49805 `TestHostSoftwareInstalledPathsDeleteExplosion`: Created a host with 500 software items and installed paths, then replaced all software with an entirely new set. This triggers `deleteHostSoftwareInstalledPaths()` with all 500 old IDs in a single unbatched DELETE statement. At 500 IDs the local test completes quickly, but the structure confirms the problem: at 30K+ IDs on production Aurora with 14M rows, these never finish. ### #48719 `TestSoftwareTitlesInsertIgnoreLockConvoy`: Created 50 hosts, each reporting 100 identical software items (simulating a homogeneous fleet). Used a barrier to release all 50 goroutines simultaneously, then measured two phases: 1. **Cold start** (empty `software_titles`): All 50 hosts concurrently call `ds.UpdateHostSoftware()`. 2. **Steady state** (titles exist): Same 50 hosts re-ingest. **Before fix:** | Metric | Cold start | Steady state | |--------|-----------|-------------| | Wall time | 3.0s | 38ms | | Avg per-host | 1,981ms | 29ms | | **Convoy factor** | **79x** | | The 79x slowdown confirms the lock convoy. ## How I fixed it ### #49805: Batch the DELETE at 500 Changed `deleteHostSoftwareInstalledPaths()` from a single `DELETE ... WHERE id IN (all IDs)` to a loop that processes 500 IDs per batch, matching the existing INSERT batching pattern in the same file. ### #48719: Three-layer defense against lock convoys **Layer 1 - Move title INSERT IGNORE outside the transaction.** Previously, `INSERT IGNORE INTO software_titles` ran inside `withRetryTxx`, so locks were held for the full transaction duration. Now each title INSERT is executed via `ds.writer(ctx).ExecContext()` outside any transaction, auto-committing independently and holding locks for microseconds. **Layer 2 - singleflight per title key.** Added a `singleflight.Group` on the `Datastore` struct. For each title, only one goroutine actually executes the INSERT; concurrent goroutines wait and share the result. **Layer 3 - In-process cache (`sync.Map`).** After a title is inserted, its key is stored in `knownSoftwareTitleKeys`. Subsequent ingestions check the cache first and skip the INSERT entirely. `CleanupSoftwareTitles` clears the cache when it deletes orphaned titles. The three layers work together: the cache handles the common case (title already known), singleflight handles the cold-start race (only one INSERT per title), and auto-commit ensures even the winning INSERT holds locks for microseconds. ## How I tested that it works ### New reproduction tests - `TestSoftwareTitlesInsertIgnoreLockConvoy`: 50 concurrent hosts, 100 identical software items. Measures cold-start convoy factor and verifies all 100 titles are created. - `TestHostSoftwareInstalledPathsDeleteExplosion`: Full software replacement path with 500 items per host, including concurrent hosts. ### Existing test suite Ran all existing software tests including: - `UpdateHostSoftware`, `UpdateHostSoftwareDeadlock`, `PreInsertSoftwareInventory` - `SoftwareTitleUpgradeCodeDriftMatch`, `UpdateHostSoftwareSameBundleIDDifferentNames` - `CleanupSoftwareTitles` (validates cache invalidation works correctly) - `SaveHost`, `SyncHostsSoftware`, and ~80 other subtests All pass. ### After-fix measurements | Metric | Before fix | After fix | |--------|-----------|-----------| | Cold-start wall (50 hosts) | ~3.0s | ~1.4s | | Cold-start avg per-host | ~1,981ms | ~594ms | | Steady-state wall | ~38ms | ~7ms | | Titles created correctly | 100/100 | 100/100 | The remaining cold-start time is from other pipeline operations (`INSERT IGNORE INTO software`, host_software linking), not from `software_titles`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Performance Improvements** - Improved software inventory ingestion under large, concurrent workloads, including more efficient handling of repeated software-title inserts. - Reduced lock contention when many devices report the same titles at the same time. - Batched deletions of installed software-path records to speed up large updates. - **Bug Fixes** - Ensured deterministic, collation-safe software-title deduplication to prevent incorrect or stale title mapping. - Strengthened orphan cleanup behavior so caches are cleared when orphan titles are removed. - **Tests** - Added stress/regression tests for software-title insert contention and large installed-path delete workloads. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
09fea47ce4 |
Fleet UI: Handle long fleet names across the Fleets UI (#49216)
## Issue Closes #47290 Also implements the "Cap free-text `maxLength` to the backend column length" pattern established in [#49041 (patterns.md thread)](https://github.com/fleetdm/fleet/pull/49041/files#r3572648691). ## Description Fleet name inputs had no `maxLength` cap and no service-layer length check, so a name >255 chars failed with a raw MySQL `Data too long` error, and several UI surfaces didn't handle long names gracefully. This PR fixes all four manifestations called out in the bug, plus a related label-overflow case on the host details page, and hardens adjacent name inputs across the app. **Frontend fixes for #47290:** - Create/Rename fleet name inputs now cap at 255 characters (matches `teams.name varchar(255)`). - Fleets table Name column uses `LinkCell` with `tooltipTruncate` + `className="w400"` so long names truncate with an ellipsis and full-name tooltip instead of overflowing across the Hosts/Users columns. - Fleet-detail page header (`.team-details__team-header`): h1 gets `overflow: hidden; text-overflow: ellipsis; white-space: nowrap;`, `__team-details` gets `min-width: 0; flex: 1`, and `.action-buttons` gets `flex-shrink: 0` + `white-space: nowrap` on buttons so *Manage enroll secrets / Rename / Delete* no longer wrap to a second line when the fleet name is long. - Manage enroll secrets modal body — `__description` gets `overflow-wrap: anywhere; min-width: 0` so a long `<b>{fleet name}</b>` wraps within the modal instead of spilling out the right edge. **Backend fixes for #47290:** - New `fleet.MaxTeamNameLength = 255` constant. - `NewTeam`, `ModifyTeam`, and `ApplyTeamSpecs` now return `fleet.NewInvalidArgumentError("name", "may not exceed 255 characters")` instead of surfacing a raw `Data too long` MySQL error. Covers UI, API, and GitOps entry points. **Broader consistency pass (per [#49041 thread](https://github.com/fleetdm/fleet/pull/49041/files#r3572648691)):** - New shared `MAX_ENTITY_CHAR_LENGTH = 255` constant in `frontend/utilities/constants.tsx`. - Refactored 8 existing files that had ad-hoc `NAME_MAX_LENGTH = 255` / `MAX_LABEL_NAME_LENGTH = 255` locals to use it. - Slotted it into 16 additional `InputField` name/description inputs that were missing a cap (API user, custom variable, certificate, label name + description, pack name + description, and all 5 CA forms — CustomEST, CustomSCEP, Smallstep, Digicert, Hydrant). - Pruned dead FE length validators that can no longer fire now that the DOM cap enforces the limit (certificate modal, custom variable modal, both label helpers, both category modals). Unusual/shorter caps (e.g. `varchar(64)`, custom business rules) still keep their inline validators — silent truncation is only appropriate for the common 255-char norm. **Bonus:** fixed the long-label overflow on the host details Labels card by capping the pill button `max-width` at 300px. ## Screenrecording https://github.com/user-attachments/assets/b917b72e-7437-4d0c-a1a1-c49b4b1c28ba https://github.com/user-attachments/assets/3a3efbb2-09d8-4f47-9fd4-f158b3453b9e https://github.com/user-attachments/assets/73e5e022-dc93-4381-82b3-be9549d050e6 Latest - max width 300px long label: <img width="1106" height="262" alt="Screenshot 2026-07-23 at 11 29 24 AM" src="https://github.com/user-attachments/assets/741fddbd-f78d-4578-a025-bddf64a81c25" /> ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually Test coverage: - `CreateFleetModal.tests.tsx`, `RenameFleetModal.tests.tsx` — new case per file asserting the name input's `maxLength === 255`. - `AddCertificateModal.tests.tsx`, `Variables.tests.tsx` — the existing "shows too-long error when pasting 256 chars" tests are now unreachable via the DOM cap; converted to `maxLength === 255` assertions. - `ee/server/service/teams_test.go` — `TestNewTeamNameValidation`, `TestModifyTeamNameValidation`, and `TestApplyTeamSpecsNameValidation` each get two new cases (accepts at the limit, rejects one over with the expected error message). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Limited fleet, team, and other user-entered names and descriptions to 255 characters. * Replaced database errors for oversized names with clear validation messages. * Prevented long fleet and label names from overflowing tables, headers, modals, and host details. * Improved modal and dropdown layouts for long text. * **Tests** * Added coverage for character limits, boundary values, and multibyte names. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
aeb56916ee |
Block host enrollment with empty enroll secrets
VerifyEnrollSecret matched by exact string, so an empty enroll_secret matched any stored empty secret and issued a valid node key. Guard the shared chokepoint: reject empty/whitespace secrets before matching, closing all enrollment paths (osquery, Orbit, Apple MDM, Android). Add a migration to delete pre-existing empty secrets. |
||
|
|
6bb0b1ea52 |
Stop leaking cross-team software title names via the hosts endpoint (#49638)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves: N/A # 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 * **Bug Fixes** * Corrected `software_title_id` filtering for hosts so software title details are strictly scoped to the current team and never backfill mismatched or out-of-scope data. * Removed unintended debug output and ensured software title details remain unset when the title isn’t accessible. * **Tests** * Added an enterprise integration test verifying cross-team `software_title_id` behavior. * Updated existing integration expectations for team-scoped visibility. * Added datastore coverage for team-scoped software title name lookup behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
b22a046a96 |
Fix undeletable Apple DDM declarations when allowed types change (#49810)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #47535 ## Description `DeleteMDMAppleDeclaration` re-ran the upload-time validator (`ValidateUserProvided`) on the delete path. That validator enforces *upload-admission* rules — forbidden declaration types (`ForbiddenDeclTypes`) and the `AllowAllDeclarations` config flag — so any declaration that was accepted at upload time became **undeletable** through the API once the accepted set later shrank. Two ways this happens in practice: - A server config flag that had been enabled at upload time is later disabled (the original customer report, prod 4.86.1). - A declaration type is added to `ForbiddenDeclTypes` in a later release, after declarations of that type were already uploaded. In both cases the UI showed "Couldn't delete. Please try again." and the API returned `400` with an upload-validation message on a *delete* request. Whether a declaration is Fleet-managed (and therefore protected from deletion through this endpoint) is already determined by the Fleet reserved-name check that runs immediately above the offending block. This PR removes the upload-time validation from the delete path and relies solely on that reserved-name check, so: - A user can delete any declaration they previously uploaded, regardless of whether the current validator config would still accept it on upload. - Fleet-managed declarations (reserved names) remain protected from deletion. The `AllowAllDeclarations` flag and `ValidateUserProvided` are unchanged on the **add/upload** path — admission control still happens where it belongs. ## Testing Extended `TestMDMConfigProfileCRUD` (replacing the pre-existing `// TODO: Add tests for create/delete forbidden declaration types?`) with two cases: - A declaration whose type is in `ForbiddenDeclTypes` can be deleted (regression guard — fails before this change, passes after). - A declaration with a Fleet-reserved name remains protected from deletion (guards the reserved-name check that is now the sole Fleet-managed gate — a boundary that was previously untested). Manually verified end-to-end in the UI: reproduced the stuck declaration (upload a forbidden type with `FLEET_MDM_ALLOW_ALL_DECLARATIONS=true`, restart without the flag), confirmed the pre-fix `400`, then confirmed deletion succeeds after the fix with the flag off. # 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), 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 * **Bug Fixes** * Improved Apple MDM declaration deletion to avoid re-running upload-time validation during the delete flow. * Declaration deletion checks now rely on Fleet management status and reserved naming, preserving protection for Fleet-managed declarations. * Added/adjusted deletion behavior for restricted and Fleet-reserved declaration types. * **Tests** * Added regression coverage for Apple declaration profile deletion via the configuration profile delete endpoint, including strict-mode scenarios and cleanup behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f75cd2e151 | Bump migration timestamps after 4.89.2 cherry-picks (#49849) | ||
|
|
f72de68f43 |
Fixed unreleased Windows cert ingestion perf issue (#49787)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49705 Verified fix with 100k host Windows load test. # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [x] Alerted the release DRI if additional load testing is needed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Bug Fixes** * Improved host certificate deduplication and automated self-healing when duplicate certificate records are ingested. * Updated source reconciliation to only change what’s stale, preventing unnecessary rewrites of unchanged source entries. * Ensured certificate sources consistently associate to the newest canonical certificate record for each certificate hash. * Improved certificate listing accuracy by returning a deduplicated set of certificate/source pairs with correct usernames. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
f7f0cfa98e |
test case and doc to ensure bootstrap package comes before profiles (#49808)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49750 # 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. (Already a part of something else, this is just further solidifying the current behaviour) - [ ] 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 - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added coverage to verify the command sequence during Apple device enrollment. * Ensures the fleet management agent installation happens first, followed by the bootstrap package, and then configuration profile and management commands. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 --> |
||
|
|
83f3f4b560 |
Add clear error for Firefox / Firefox ESR conflict (#49714)
**Related issue:** Resolves #49682 Mozilla Firefox and Firefox ESR are distinct Fleet-maintained apps that share the macOS bundle identifier `org.mozilla.firefox`, so they resolve to one software title. Adding both to a fleet previously gave a generic conflict error (or no error at all). This adds a clear message — "Only one of Mozilla Firefox or Mozilla Firefox ESR can be added to the same fleet." — on both the single-add and GitOps/batch paths. The check is general (any two FMAs sharing a bundle identifier), with the app names filled in dynamically. # 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). ## 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 - **Bug Fixes** - Prevented adding both Mozilla Firefox and Firefox ESR to the same fleet when they share a bundle identifier. - Updated the UI to show a specific conflict message explaining that only one of the two can be added. - Ensured existing workflows still work for adding new versions of the already-selected app. - **Tests** - Added backend and frontend test coverage for the new conflict detection and error-message formatting. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
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 |
||
|
|
9d6f25acd7 |
Make MFA token redemption atomic to prevent multiple sessions
Resolves #16770 The MFA login token redemption path (`POST /api/latest/fleet/sessions`) read the one-time verification token with a non-locking `SELECT` on the read replica, then created a session and deleted the token in a *separate* transaction without verifying the token was still present. Concurrent requests carrying the same token each passed the `SELECT` and each minted a distinct session, breaking the single-use guarantee. `SessionByMFAToken` now consumes the token and creates the session inside a single transaction: - The token row is locked with `SELECT ... FOR UPDATE`, then deleted, and the delete's rows-affected count is confirmed non-zero before the session is created. - Concurrent redemptions serialize on the row lock; the loser re-reads after the winner commits the delete, finds no row, and aborts before creating a session. - The user is still loaded *before* the transaction, so a concurrently-deleted user or a transient read error leaves the token intact for retry (preserving the pre-fix atomicity behavior). --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Juan Fernandez <juan@fleetdm.com> |
||
|
|
4972732c75 |
Fix test failures by avoiding mutating shared state
Fix test failures by avoiding mutating shared state |
||
|
|
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. |
||
|
|
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. |
||
|
|
d903ec58e1 |
Fix label update consistency issue
Persist label metadata and membership changes together in a single transaction so a failed update can't leave a partial change behind. |
||
|
|
42c0e4f408 |
Move "Install self-service software" endpoint to public REST API docs (#49618)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** N/A # 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. ## Summary Moves the `POST /api/v1/fleet/device/{token}/software/install/{software_title_id}` ("Install self-service software") endpoint out of the contributor-only API reference (`docs/Contributing/reference/api-for-contributors.md`) and into the public REST API docs (`docs/REST API/rest-api.md`), nested under the existing `## Software` section. - Added `### Install self-service software` to `docs/REST API/rest-api.md`, right after `### Uninstall software`, with a TOC entry and a note that it uses the device's authentication token instead of the usual Fleet API token. - Removed the TOC entry and body section for this endpoint from `docs/Contributing/reference/api-for-contributors.md`. Sibling device-authenticated self-service endpoints were left in place there since only this one endpoint was moved. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an API route allowing Fleet Desktop users to initiate self-service software installations using a device token and software title. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Rachael Shaw <r@rachael.wtf> |
||
|
|
b9136f4da5 |
Release from AB backend support (#49680)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #49367 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added “Release from Apple Business” for eligible Apple hosts, including per-device success/failure reporting and activity logging. * Added a new API endpoint to trigger the action and return results for each selected host with clear error details. * Introduced authorization rules for global admins and team admins to release only within allowed scope. * **Bug Fixes** * Improved validation and error handling: rejects oversized selections, reports unknown/ineligible hosts and DEP-related failures per device, and treats assignment-cleanup failures as non-blocking. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
940706c9e8 |
log command UUIDs for fleetd and bootstrap in DEP release flow (#49754)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # Super small change to make it easier to correlate bootstrap and fleetd `InstallEnterpriseApplication` command UUID with log statements # Checklist for submitter If some of the following don't apply, delete the relevant line. ## Testing - [ ] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved logging for Apple MDM command delivery by including the associated command identifier when application and bootstrap package installation commands are sent. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ccaea1373b |
trim MDM SSO whitespace in GitOps and API (#49378)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #48003 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Fixed MDM SSO configuration handling to automatically remove leading and trailing whitespace from provider fields. - GitOps-applied MDM SSO settings are now normalized before validation, preventing otherwise invalid configurations caused by extra spaces. - Required-field and URL validation now operate on the cleaned values. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
10ac3c73a3 |
Harden password reset token handling
Ensure a password reset token can only be used once. |
||
|
|
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 --> |