a77e2bb642ace0adea9dd1935cb2d9176deb547e
2685
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2c8b21a782 |
Defer Windows MDM profile removals via pending-delete retention (#47156)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46993 Requires #47071 to merge first Loadtest shows reduction of batch delete of 40 profiles for 30K hosts down to ~3.9 seconds. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually ## Database migrations - [x] 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 ## Release Notes * **Bug Fixes** * Resolved timeout issues when removing large numbers of Windows configuration profiles from teams with many hosts. * **New Features** * Windows profile deletions now process asynchronously in the background, enabling faster API responses and consistent behavior with profile delivery operations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6c342a1625 | Refetch certs on macOS RemoveProfile ack for ACME profiles (#46867) | ||
|
|
557def9c83 |
add default fleet for BYOD Apple migration (#47161)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45595 # 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. (Will add in a follow up story) - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Enabled BYOD fleet enrollments with default team assignment capability * Added enrollment challenge tracking and management for ADUE device registrations * Implemented secure enrollment URL token generation for enrollment flows <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b4dcea8a82 |
Improved Windows MDM reconciler (#47071)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45635 Moved profile reconciler work from SQL to code, similar to what Apple MDM team did last sprint. The Windows MDM loadtest for 40 profiles with 30K hosts looks much better. ``` ┌──────────────────────────┬─────────────────────────────────────────┬───────────────────────────────────────────┐ │ │ Pre-fix baseline │ This branch │ ├──────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤ │ Transfer wall time │ ~40–42 min │ ~15.5 min │ ├──────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤ │ Per work tick │ 215–257s (host-finding query dominated) │ ~48s (host-finding gone; now bulk writes) │ ├──────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤ │ Ticks > 30s (work ticks) │ ~all │ ~all (16/17, ~48s) │ ├──────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤ │ Pacing governor │ the host-finding query │ the 2000-host delivery cap + 30s interval │ └──────────────────────────┴─────────────────────────────────────────┴───────────────────────────────────────────┘ ``` The writer spikes briefly to 16 AAS, but has CPU headroom, so I'd say we can claim to support 40 profies on 30K hosts. ``` ┌───────────────┬───────────────┬───────────────────────────┬───────────────────────────────────────┐ │ Instance │ CPU avg / max │ DBLoad avg / max (4 vCPU) │ Read / Write / Commit latency │ ├───────────────┼───────────────┼───────────────────────────┼───────────────────────────────────────┤ │ writer -two │ 67.9% / 74.9% │ 4.84 / 16.0 │ 0.28ms / 2.07ms / 10.6ms (max 12.2ms) │ ├───────────────┼───────────────┼───────────────────────────┼───────────────────────────────────────┤ │ reader -one │ 46.1% / 52.7% │ 1.19 / 5.0 │ 1.59ms / — / — │ ├───────────────┼───────────────┼───────────────────────────┼───────────────────────────────────────┤ │ reader -three │ 65.4% / 70.1% │ 1.77 / 5.0 │ 1.72ms / — / — │ └───────────────┴───────────────┴───────────────────────────┴───────────────────────────────────────┘ ``` # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Reworked Windows MDM reconciliation to a snapshot-based, batched drain-loop, improving responsiveness and reducing database load during large profile operations. * **Performance / Reliability** * Windows MDM profile changes now reach hosts faster; large team-wide profile additions/removals (including host transfers) complete more quickly with lower DB impact. * **Chore / Configuration** * Added tunables to control per-tick delivery caps and scan budgets. * **Tests** * Expanded end-to-end and property tests for install/remove, team/label gating, and multi-window drain behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
251093f6b3 |
Setup experience software policy checks (#47075)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45309 If software is linked to policies, we run the policy during setup experience to determine if software should be installed. We install on failing policies. # 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] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Windows/Linux setup experience installers can be gated by team policies: setup will run a policy check and skip installing if the policy already passes; if the policy fails, the installer runs as part of setup. * After gated setup completes, the host’s policy set is re-evaluated promptly so subsequent policy actions run immediately. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0c820a67fc |
Fix GCS checksum flag derived from wrong endpoint key (#47145)
Fixes https://github.com/fleetdm/fleet/issues/47142 |
||
|
|
1e9f341eb5 |
Narrow host lookup for iDevice URL auth (#47141)
# Summary Adds a `HostByUUID` datastore method that matches on the `uuid` column only, and uses it in the iOS/iPadOS device URL authentication path (`AuthenticateIDeviceByURL`) instead of the broader `HostByIdentifier` helper. |
||
|
|
097c82a337 |
Reorder org_logo migration to follow AddHostCertificatesOriginDeletedAtIndex (#47168)
Follow-up to #47099. Re-timestamps the `CreateOrgLogoTable` migration so it can also ship in the **4.86.2** patch. `CreateOrgLogoTable` must sort **immediately after** `20260527215817_AddHostCertificatesOriginDeletedAtIndex` (the last migration in 4.86.1). ## Testing - Started server with latest `main` migrations applied. It failed. - Ran `UPDATE migration_status_tables SET version_id = 20260527215818 WHERE version_id = 20260608173427;`. - Started server, no crashes. <img width="1458" height="628" alt="Screenshot 2026-06-09 at 10 19 40 AM" src="https://github.com/user-attachments/assets/68d24712-78ae-42ca-8989-60c39647dd33" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated database migration infrastructure and corresponding tests to maintain consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7ad95ac2c3 |
Fixed the host's Software UI showing a date decades in the past (#46779)
**Related issue:** Resolves #43622 |
||
|
|
ad30812054 |
Speed up /vulnerabilities and filtered /software/versions queries (#45564)
Address 100% DB CPU spikes observed when paginating these endpoints with filters. Two root causes: cve_meta and vulnerability_host_counts lack indexes for the actual filter shapes, and ListVulnerabilities ran correlated scalar subqueries on every row of vulnerability_host_counts that matched the scope (1.1M rows examined per call). Add three online indexes: - cve_meta(cisa_known_exploit, cve) for the exploit filter - cve_meta(cvss_score, cve) for the CVSS range filter - vulnerability_host_counts(global_stats, team_id, host_count, cve) for the scope filter on the vulnerabilities endpoint Refactor ListVulnerabilities into a two-stage query: an inner query filters, sorts, and paginates vulnerability_host_counts (with an optional LEFT JOIN to cve_meta for sort/filter columns), and an outer query enriches only the paginated page with the created_at and source scalar subqueries. Net effect: the heavy subqueries run perPage times (~20-100) instead of millions. Sort-by-created_at falls back to the single-statement form since the sort key is itself the subquery result. CountVulnerabilities drops the redundant DISTINCT (vhc.cve is already unique within a (global_stats, team_id) scope via the existing UNIQUE KEY) and only joins cve_meta when KnownExploit filtering is requested. **Related issue:** Resolves #45415 |
||
|
|
3f5944626c |
Fix Fleet startup crash on read-only filesystem without S3 bucket (#47099)
**Related issue:** Resolves #47090 Fleet crashes into `CrashLoopBackOff` on startup when deployed on Kubernetes with `readOnlyRootFilesystem: true` and **no** S3 software installers bucket configured: ``` Failed to start: initializing filesystem org logo store: mkdir /tmp/org-logos: read-only file system ``` I realised I was calling `initFatal` when failing to create a directory on the filesystem which doesn't match the pattern of `logging` + `creating a "failing" store` (one that is initialized but fails all operations) as we do for e.g. software title icons (see NewFailingSoftwareTitleIconStore). Per this slack conversation: https://fleetdm.slack.com/archives/C084F4MKYSJ/p1780931127976389, we decided to fall back to a database-backed storage: <img width="737" height="114" alt="Screenshot 2026-06-08 at 3 16 28 PM" src="https://github.com/user-attachments/assets/2a6ff75f-b382-40ba-81d9-3be3cfbd648a" /> # 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 Commented out this line to force filesystem usage: <img width="615" height="71" alt="Screenshot 2026-06-08 at 1 18 53 PM" src="https://github.com/user-attachments/assets/85043c88-5c8c-48a0-8145-098fba9513bd" /> #### Before Server crashes <img width="1278" height="124" alt="Screenshot 2026-06-08 at 1 18 17 PM" src="https://github.com/user-attachments/assets/7b788a24-131a-47a3-8580-fcd9fda8b449" /> #### After Server starts and logo upload works - Without --dev_license https://github.com/user-attachments/assets/58c5ebf9-cf52-4ba0-ac98-9675e7eef92c - With --dev_license https://github.com/user-attachments/assets/117bb812-31bd-4849-927c-93cafd1a71d7 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** - Organization logos now support database storage as the fallback option when S3 software installers bucket is not configured, replacing local filesystem storage for improved reliability. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2570e25f0e |
Defer writing team_id on android check-ins (#46929)
**Related issue:** Resolves #44113 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Bug Fixes** * Fixed an issue where Android device check-ins could revert admin team transfers, ensuring team assignments persist correctly after re-enrollment. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e34126ab3a |
Merge branch 'main' of github.com:fleetdm/fleet into feat/39018-self-service-categories
Bump migration, fix failing test and nilaway check |
||
|
|
6a84d3a489 |
update apple query for profile verification with include all/any + exclude (#47079)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Follow up PR for the Include Any/All + Exclude label story, since this was missed. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved Apple MDM profile verification to more accurately determine expected configuration profiles, including correct handling of mixed include/exclude label combinations and exclusion edge cases. * **Tests** * Updated unit and integration tests to reflect the expanded Apple include+exclude scenarios and to run Apple-only profile reconciliation flows. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
cd5c44db72 |
MDM Windows push perf fixes (#46917)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46567 Loadtest feedback: reducing the number of `UPDATE mdm_windows_enrollments e SET e.has_pending_commands` writes. # 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 ## 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. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed Windows MDM enrolled devices to correctly track pending commands. Acknowledged commands are now properly removed from the pending list, and the system accurately reflects command status after device acknowledgment. Command cleanup for processed requests is now more efficient. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
863363561b |
Fix fleet-scoped host vitals labels (#46953)
**Related issue:** Resolves #46869 - [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** * Host vitals labels based on identity-provider group membership now correctly apply to both global and team-scoped hosts, preventing cross-team leakage. * **Tests** * Added and updated tests to validate IdP-group-backed vitals label membership across global and per-team hosts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
89965f4f9a |
Extract platform-neutral MDM reconcile label primitives (#47032)
Pure refactor, no behavior change. First step for #45635 (Windows batched in-memory reconciler). - New server/mdm/reconcile package holds the include/exclude label handlers and the team+label applicability dispatcher. The Apple platform gate stays in the Apple wrapper since platform eligibility is platform-specific. - New platform-neutral fleet types (MDMProfileLabelRef, MDMProfileIncludeMode, MDMLabeledEntity); the Apple names are now type aliases so existing code and tests are unchanged. - BulkGetHostLabelMemberships moves from apple_mdm_batched.go to a neutral file; it was already platform-agnostic. - The existing Apple label-scenario tests keep covering the shared logic through the delegating wrappers; the shared package also gets its own handler/dispatcher tests. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45635 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Moved MDM profile include/exclude label logic into a shared, platform-neutral reconciliation flow for consistent behavior across platforms. * Consolidated Apple MDM label handling to reuse the shared reconciliation primitives and improved host label membership lookup behavior. * **Tests** * Added and reorganized unit tests covering MDM label-based profile reconciliation, include/exclude rules, and Apple-specific wrapper behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fb9e4c4701 |
Auth in-house iOS app downloads with install tokens (#46819)
# 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. - [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 ## 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 ## Release Notes * **New Features** * In-house iOS app manifest and package downloads now use secure per-install tokens embedded in the URL path instead of query parameters * Installation tokens are bound to specific devices and teams, enhancing security * Installation tokens automatically expire after 6 hours <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Jonathan Katz <yehonatankatz@gmail.com> |
||
|
|
49db931ffb |
Auto-clean duplicate Okta CA SCEP cert after profile install (#46172)
**Related issue:** Resolves #42757 ## Summary Resending or renewing the Okta conditional access profile leaves an orphaned SCEP certificate in the per-user macOS keychain, accumulating duplicates with every renewal. This PR auto-runs an existing keychain-cleanup script after a successful `InstallProfile` ack for the Okta CA profile, so admins no longer have to find and run the script manually. ## Root cause Investigation in the issue thread isolated the trigger: - The Okta CA `.mobileconfig` bundles `com.apple.security.scep` with `com.apple.security.identitypreference` in a single profile (macOS rejects the alternative — `Identity payload not found in same profile as identity preference payload`). - The Identity Preference payload creates a keychain-resident preference item that keeps the *old* cert pinned across profile replacement, even though the rewritten Identity Preference now points to the fresh SCEP enrollment. - EAP-TLS Wi-Fi profiles renew cleanly because they reference the cert via SystemConfiguration (`PayloadCertificateUUID`), not the keychain — so this isn't a generic SCEP-bundling issue. The team decision in the issue (`@sharon-fdm`) was to delete the duplicate certificate rather than restructure the profile. A standalone cleanup script already shipped at `docs/solutions/macos/scripts/delete-duplicate-scep-certificates.sh` and was linked from the Okta CA guide; admins had to find and run it. ## Approach Hook the existing Apple MDM `InstallProfile` ack path in `MDMAppleCheckinAndCommandService.CommandAndReportResults`, parallel to the existing ACME `CertificateList` follow-up. When the ack is for the Okta CA profile and status is `verifying`, enqueue an internal host script run that executes the cleanup script targeting the host's per-user MDM enrollment short name. Key properties: - **Single hook, three paths covered.** Admin "Resend" nulls the profile status and the reconciliation cron re-enqueues an `InstallProfile`; the SCEP renewal cron also re-issues `InstallProfile`. Both flow through the same ack handler this hook attaches to. - **Idempotent.** The cleanup script no-ops when only one matching cert is present, so triggering on initial installs (not just renewals) is safe and removes the need to distinguish "is this a renewal". - **Tightly gated.** Single indexed lookup keyed on `(host_uuid, command_uuid, profile_identifier, platform='darwin')`. Other SCEP-bearing profiles do not trigger the script. No work happens for hosts with no per-user enrollment. - **Internal-script semantics** (matches lock/unlock/wipe prior art). Runs even when scripts are globally disabled. Does not appear in the user-facing host activity feed. - **Failure-isolated.** Enqueue errors are logged but do not break the ack path; the renewal itself is what matters. - **Defense in depth on the shell call.** The macOS short name is validated against a strict regex (`^[A-Za-z0-9_][A-Za-z0-9_.-]*$`, ≤31 chars) before being interpolated, and POSIX single-quote-escaped on the way through. ## Files **New** - `server/service/conditional_access_cleanup.go` — `//go:embed` of the cleanup script, the hook helper `maybeRunOktaCACleanupScript`, the validated shell-wrapper builder, and the POSIX single-quote escape helper. - `server/service/conditional_access_cleanup_test.go` — unit coverage for username validation, shell escaping, the routing decisions of the hook helper (mock-based), and an embed-sync assertion against the docs copy. - `server/service/embedded_scripts/delete-duplicate-scep-certificates.sh` — embed source-of-truth copy, byte-for-byte equal to the public `docs/solutions/macos/scripts/` script. - `changes/42757-okta-conditional-access-duplicate-scep-cert-cleanup` — user-visible changes note. **Datastore** - `server/datastore/mysql/mdm.go` — `OktaCACleanupTargetForInstallCommand`: single SQL lookup that returns `(host_id, user_short_name, ok)` for the new hook. Returns `ok=false` for non-Okta profiles, non-darwin hosts, or hosts without a user-channel enrollment. - `server/datastore/mysql/scripts.go` — `NewInternalHostScriptExecutionRequest`: thin wrapper that routes through the existing internal-script codepath (`isInternal=true`) used by lock/unlock/wipe. Refactored the existing public method to share an internal helper. **Interface / mocks** - `server/fleet/conditional_access_idp.go` — exported `ConditionalAccessOktaProfileIdentifier`, `ConditionalAccessOktaCertificateCN`, and the new `OktaCACleanupTarget` struct, so both the template-render path and the SQL lookup can reference the same source of truth. - `server/fleet/datastore.go` — `OktaCACleanupTargetForInstallCommand` and `NewInternalHostScriptExecutionRequest` added to the `Datastore` interface. - `server/mock/datastore_mock.go` — regenerated (additions only). **Wiring** - `server/service/apple_mdm.go` — call into `maybeRunOktaCACleanupScript` from the InstallProfile `MDMDeliveryVerifying` branch, alongside the existing ACME `maybeQueueCertificateListForACMEProfile` follow-up. Warns on error rather than failing the ack. - `server/service/conditional_access_idp.go` — use the new `fleet.ConditionalAccessOktaCertificateCN` constant when rendering the profile template, eliminating the magic string duplication. **Tests touched** - `server/datastore/mysql/mdm_test.go` — integration test `testOktaCACleanupTargetForInstallCommand` covering the happy path, non-Okta profile, device-only enrollment, and unknown command. - `server/datastore/mysql/scripts_test.go` — `testNewInternalHostScriptExecutionRequest` confirming the internal flag is set correctly and the new entry only appears under the internal-only listing filter. - `server/service/apple_mdm_test.go` — added the new mock stub for `OktaCACleanupTargetForInstallCommandFunc` to `TestMDMCommandAndReportResultsProfileHandling` so the existing test continues to pass with the new hook in the codepath. - `server/service/conditional_access_idp_test.go` — the rendered-profile assertion now also pins on the shared `ConditionalAccessOktaProfileIdentifier` and `ConditionalAccessOktaCertificateCN` constants so the template can't drift from the SQL lookup. |
||
|
|
b02fa180b2 |
Preserve android device team assignment (#46868)
**Related issue:** Resolves #45263 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Android devices no longer lose team assignments or certificate configuration when a host is deleted and the device re-enrolls. * Re-enrollment restores a device’s previously known team when available, preserving certificate templates and team-specific settings. * Team transfers for Android devices now reliably update device records so certificates and access remain consistent. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d6b56d81bd |
Self service categories - install all (#46865)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46393 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] Timeouts are implemented and retries are limited to avoid infinite loops - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually |
||
|
|
244cdd5558 |
45178 cpie reconciler query updates (#46889)
**Related issue:** Resolves #45178 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## 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. _Note: Only windows and Mac OS. Android required by someone with a device._ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved MDM profile applicability on Android, Windows, and Apple to handle combined include-all, include-any, and exclude-any label rules, yielding more accurate install/remove decisions. * **Tests** * Added cross-platform tests covering combined include/exclude label scenarios to verify correct profile selection, installation, and removal 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> |
||
|
|
f19c9a6696 |
Optimize ListLabels host-count query
Fixes #4890 * Optimized listing labels query by refactoring correlated subquery. * Optimized aggregate that counts host's labels to executed once, and skip the join to hosts entirely when the team filter allows all hosts. |
||
|
|
8cb7f8af67 |
Add macos_applications filter for host software list (#46223)
Adds a `macos_applications` boolean query parameter to the list host
software endpoint (`GET /api/_version_/fleet/hosts/{id}/software`). When
true, results are restricted to apps installed at the top level of the
macOS /Applications folder, hiding helper apps, system apps,
command-line tools, and user-local apps. The filter applies only to
macOS hosts and is ignored on other platforms.
The filter is applied by pruning the in-memory software maps in
ListHostSoftware down to the title IDs that have a top-level
`/Applications` bundle, so the count and paginated queries stay
consistent and the filter applies uniformly across regular, VPP, and
in-house apps. Top-level is determined from
`host_software_installed_paths` via
`installed_path LIKE '/Applications/%' AND NOT LIKE '/Applications/%/%'
on source 'apps'`.
**Related issue:** Resolves #39017
|
||
|
|
49b86438bb |
feat: replace osquery column with agent column on hosts page (#44811)
for #44846 for #43458 - UPDATE: @noahtalerman: For the following story: - https://github.com/fleetdm/fleet/issues/44846 --- # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## 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 ## Release Notes * **New Features** * Added a new Agent column on the Hosts page displaying Orbit version with tooltips showing Osquery, Orbit, and Fleet Desktop versions for comprehensive version visibility. * **Improvements** * Updated default column visibility on the Hosts page—Issues and Private IP columns are now hidden by default for a cleaner view. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Scott Gress <scott@fleetdm.com> |
||
|
|
bb1d09fc90 |
Add GCS IAM authentication for S3-compatible storage (#40303) (#40374)
Closes #40303 ### Summary Adds support for Google Application Default Credentials (ADC) bearer token authentication when using GCS's S3-compatible endpoint. This allows Fleet deployments on GCP to use workload identity instead of static HMAC keys. Changes - Add `s3_software_installers_gcs_iam_auth` config option for software installer storage - Add `s3_carves_gcs_iam_auth` config option for file carving storage - Implement OAuth2 bearer token auth in S3 client via middleware (removes AWS SigV4 signing) - Add validation to ensure GCS IAM auth requires endpoint URL containing `storage.googleapis.com` - Add Helm chart values and deployment env vars for both options - Add documentation for new configuration options - Add tests for GCS IAM auth validation and integration ### Usage Enable GCS IAM auth by setting the endpoint URL to Google's S3-compatible endpoint and enabling the IAM auth flag: ```yaml s3: software_installers_endpoint_url: https://storage.googleapis.com software_installers_gcs_iam_auth: true software_installers_bucket: my-bucket software_installers_force_s3_path_style: true ``` Or via environment variables: ``` FLEET_S3_SOFTWARE_INSTALLERS_ENDPOINT_URL=https://storage.googleapis.com FLEET_S3_SOFTWARE_INSTALLERS_GCS_IAM_AUTH=true FLEET_S3_SOFTWARE_INSTALLERS_BUCKET=my-bucket FLEET_S3_SOFTWARE_INSTALLERS_FORCE_S3_PATH_STYLE=true ``` ### Testing - Unit tests validate configuration requirements (GCS endpoint, no HMAC keys, no STS role) - Integration test verifies bearer token is correctly injected into requests **Related issue:** Resolves # ## Checklist for submitter If some of the following don't apply, delete the relevant line. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [X] Added/updated automated tests - [TODO] QA'd all new/changed functionality manually ## New Fleet configuration settings - [X] Setting(s) is/are explicitly excluded from GitOps > [!NOTE] These are infrastructure-level server settings (env vars/config file), not app-level settings managed via GitOps YAML. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Google Cloud Storage (GCS) IAM authentication support for file carving and software installer storage using Google Application Default Credentials * **Configuration** * New authentication configuration option available for both carving and software installer S3 storage in Helm deployments and configuration files <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/40374) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Carlo <1778532+cdcme@users.noreply.github.com> |
||
|
|
7bcc79da0c |
Decrease lock state cleanup time to 1 minute (#46730)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #44440 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] QA'd all new/changed functionality manually ^ I verified if within 1 minute it's still locked, after 1 minute it removes the Locked state <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Reduced the delay for Apple MDM unlock status updates so recently unlocked hosts are reflected as unlocked much faster (cleanup window shortened from ~5 minutes to ~1 minute), improving Fleet responsiveness and accuracy. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6d8ec7a1d0 |
Fix restoration of DEP hosts when a duplicate exists (#46815)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45192 # 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 * **Bug Fixes** * Deleting one of multiple duplicate Apple DEP hosts now properly resolves the duplicate and prevents recreation of a pending host when another host with the same serial and platform still exists. * **Tests** * Added unit tests covering deletion behavior for duplicate DEP hosts to ensure correct resolution and no unintended pending-host restoration. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
cfcca6a6ac |
Handle not found bootstrap package in GitOps flows (#46802)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45441 The issue is when hitting the `svc.DeleteMDMAppleBootstrapPackage` via the API/UI, it only clears the row in `mdm_apple_bootstrap_packages`. However when GitOps runs the next time, it compares the old team config, which has a stale `macos_setup.bootstrap_package` config value. Which forces it to call the same Delete method again. This PR adds the defensive approach to gracefully handle a not found bootstrap package when GitOps wants to delete it. The reason the second run works, is that we only attempt to delete the bootstrap package after we called SaveTeam with the new empty `bootstrap_package` value. So next run sees it as empty and avoid calling the Delete method. _One question is if we want to add a more active approach on the delete service method, which also handles updating the team config clearing out this value? That would have prevented the cause, I think either keeping only this layer, or doing both solutions is a good approach._ # 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** * GitOps automation no longer fails on its first run after a bootstrap package is deleted via the UI. * Clearing a macOS bootstrap package (team or app config) now succeeds even if the underlying package record is already missing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
07129edc66 |
Clean up Apple reconciler queries, no longer used (#46712)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Final part of Optimize apple reconciler queries. It does include a slight logic change, when cleaning up for the setup experience status and release DEP worker, checking for pending profiles. 🤑🤑🤑 <img width="106" height="35" alt="image" src="https://github.com/user-attachments/assets/68498b1c-31cb-494c-9643-ed5da2602615" /> # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. Added in another PR. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] 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 * **Refactor** * Move Apple MDM profile and declaration reconciliation to batched/scheduled processing. * Stop immediate bulk-updating of pending host profiles after creating/editing profiles or declarations; Android remains synchronous while Apple/Windows are deferred. * **New Features** * Added targeted per-host pending-profile detection for Apple devices to improve reconcile accuracy. * **Tests** * Reworked and expanded Apple MDM reconciliation tests; removed legacy/obsolete batch tests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
02d1738d0e |
Fixes from Konstantin's code review (#46701)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #41683 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactoring** * Replaced ad-hoc string checks with standardized enrollment-status constants across platforms. * Centralized Android wipe validation into a single reusable check. * **Bug Fixes** * Updated Apple lock and wipe validations to use standardized enrollment-status values. * Fixed pending-device handling during Apple device sync to rely on the centralized status representation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1b42e2276c |
Fix ListVulnerabilities cursor pagination with ambiguous column names (#45983)
Closes #45843 ## Summary - Table-qualify column names in `vulnerabilitiesAllowedOrderKeys` so they resolve correctly in both `ORDER BY` and cursor `WHERE` clauses - `cve` was ambiguous between `vhc.cve` and `cm.cve` - `hosts_count` and `cve_published` were SELECT aliases not valid in WHERE scope - Also fixed `host_count_updated_at` / `hosts_count_updated_at` which had the same alias issue ## Reproduction ### Bug (before fix) The `ListVulnerabilities` query joins `vulnerability_host_counts vhc LEFT JOIN cve_meta cm`. When cursor pagination appends `WHERE <column> > ?`, three order keys fail: | `order_key` | Old column value | MySQL error | |-------------|-----------------|-------------| | `cve` | `cve` | `Error 1052: Column 'cve' in where clause is ambiguous` (exists on both `vhc` and `cm`) | | `hosts_count` | `hosts_count` | `Error 1054: Unknown column 'hosts_count' in 'where clause'` (SELECT alias, not a real column) | | `cve_published` | `cve_published` | `Error 1054: Unknown column 'cve_published' in 'where clause'` (SELECT alias for `cm.published`) | Reproduced locally by running the raw SQL the old code would generate: ```sql -- BUG 1: ambiguous ... WHERE vhc.host_count > 0 AND cve > 'CVE-2023-0002' ORDER BY cve ASC; -- ERROR 1052 (23000): Column 'cve' in where clause is ambiguous -- BUG 2: alias not valid in WHERE ... WHERE vhc.host_count > 0 AND hosts_count > 10 ORDER BY hosts_count ASC; -- ERROR 1054 (42S22): Unknown column 'hosts_count' in 'where clause' -- BUG 3: alias not valid in WHERE ... WHERE vhc.host_count > 0 AND cve_published > '2020-01-01' ORDER BY cve_published ASC; -- ERROR 1054 (42S22): Unknown column 'cve_published' in 'where clause' ``` ### Fix Changed the allowlist values from bare names/aliases to table-qualified actual column names: | `order_key` | Before | After | Why | |-------------|--------|-------|-----| | `cve` | `cve` | `vhc.cve` | Ambiguous: both `vhc` and `cm` have a `cve` column | | `cve_published` | `cve_published` | `cm.published` | SELECT alias, not a real column; invalid in WHERE | | `hosts_count` / `host_count` | `hosts_count` | `vhc.host_count` | SELECT alias for `vhc.host_count`; invalid in WHERE | | `hosts_count_updated_at` / `host_count_updated_at` | `hosts_count_updated_at` | `vhc.updated_at` | SELECT alias for `vhc.updated_at`; invalid in WHERE | Table-qualified names work in both `ORDER BY` and `WHERE` clauses. ### Manual verification (after fix) Started a local Fleet server (`--dev --dev_license`), seeded 6 vulnerability entries, and hit all three previously-broken API calls: ``` GET /api/v1/fleet/vulnerabilities?order_key=cve&order_direction=asc&per_page=3&after=CVE-2023-0002 --> 200 OK, returned CVE-2023-0003, CVE-2023-0004, CVE-2023-0005 (correct ascending order) GET /api/v1/fleet/vulnerabilities?order_key=hosts_count&order_direction=asc&per_page=3&after=10 --> 200 OK, returned hosts_count=20, 30, 50 (correct ascending order) GET /api/v1/fleet/vulnerabilities?order_key=cve_published&order_direction=asc&per_page=3&after=2020-01-01 --> 200 OK, returned 3 CVEs with publish dates after 2020-01-01 ``` Regression checks (no breakage): - `order_key=cvss_score` cursor pagination still works - Page-based pagination (`page=0&per_page=3`) still returns correct results with `has_next_results: true` ## Test plan - [x] Added `testListVulnerabilitiesCursorPagination` integration test covering all three broken order keys (`cve`, `hosts_count`, `cve_published`) - [x] Existing tests pass: sort, page-based pagination, team filter, known exploit filter, count - [x] Manual verification on local Fleet server (see above) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Bug Fixes * Fixed cursor pagination for the vulnerabilities endpoint when sorting by CVE, host count, or CVE publication date to prevent SQL errors and ensure reliable result navigation. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45983?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
339af293be |
Fix tight install loop on continous automations feature (#46823)
**Related issue:** Resolves #45149 (adds to) ## 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** * Throttle continuous policy automations to avoid repeated install attempts within the policy update interval. * **New Features** * Install records now include an updated timestamp for accurate cooldown decisions. * Added tracking of recently verified VPP app installs to avoid redundant re-installs. * **Tests** * New and updated unit and integration tests covering cooldown behavior and VPP verification lookups. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
07df7c5cfd |
Track software deletions in GitOps (#46764)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #43729 # Details Adds output to GitOps runs indicating which custom/FMA software packages would be deleted. This involves adding a `deleted_packages` key to the `/software/batch/:request_uuid` ("Get status of software batch-apply request") API, which will be documented separately. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [X] Added/updated automated tests - [X] QA'd all new/changed functionality manually - [X] verified that a GitOps dry run produces one "would've deleted" line per custom package / fma that would be deleted - [X] verified that a GitOps real run produces one "deleted" line per custom package / fma that was deleted - [X] verified that adding software is unaffected <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * GitOps batch software operations now report packages pending deletion: dry-runs show "would've deleted" warnings and real runs show deletions; apply flows surface per-package deletion messages. * Empty payload dry-run now still reports pending deletions when applicable. * **Tests** * Added integration and datastore tests validating deletion-warning output, pending-deletion detection, and related result handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e20cedc8a0 |
fleetd Windows MDM wake (push vs poll) (#46594)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46567 and Resolves #46737 Solution for the agressive polling: - no WNS (although we could add it later as another avenue for notifications) - fleetd advertises a sync capability, persisted as `mdm_windows_enrollments.fleetd_sync_capable` - The management session relaxes the DMClient poll (`poll_schedule_relaxed`) - When an MDM command is queued, `has_pending_commands` flips, the next orbit check-in returns `WindowsMDMSyncRequest`, and fleetd runs `deviceenroller` to deliver it immediately - older fleetd versions keep the 1-minute poll Docs: https://github.com/fleetdm/fleet/pull/46780 Changes to osquery_perf and any additional changes after loadtesting will be done in a separate PR. # 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`). ## 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** * On-demand Windows MDM sync: servers can request immediate delivery of queued MDM commands to Windows clients; Orbit triggers client-side sync on Windows. * **Enhancements** * Orbit throttles per-device on-demand sync to avoid excessive runs. * Server reconciles and persists device poll schedule (fast vs relaxed) and exposes consolidated host MDM state (awaiting-configuration + has-pending-commands). * **Tests** * Added tests covering host config state, pending-command flows, poll-schedule toggling, and on-demand sync behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a3338d032e |
Self service categories - GitOps support (#46671)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46392 A few things in this PR: - updated the conversion from old default category to the new ones with the emoji included that was introduced in the feature branch. It takes into account what exists in the database now so if an admin wants to add for example "Productivity" without the emoji as a category it won't get overwritten. - updated a few places to ignore missing categories rather than error (what we do for adding a single FMA currently) - updated permissions for "gitops" users - added everything needed for gitops, generate-gitops support using the existing endpoints from the last PR. Didn't add logs like "[+] applied X self service categories" since it wasn't mentioned in the docs, but wouldn't be too hard to add. # Checklist for submitter ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually ## New Fleet configuration settings - [x] Verified that the setting is exported via `fleetctl generate-gitops` - [x] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [x] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [ ] Verified that any relevant UI is disabled when GitOps mode is enabled - Currently missing, at least on this branch |
||
|
|
d7d9a96aa3 |
Add combined include/exclude label targeting for MDM profiles (API and GitOps) (#46437)
**Related issue:** Resolves #45180 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [x] Confirmed that the fix is not expected to adversely impact load test results <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * MDM profiles can combine label inclusion (include-all/include-any) with exclusion (exclude-any) so you can target hosts by labels while excluding specific labeled hosts. * Profile validation now enforces a single include-mode and explicitly rejects any label used in both include and exclude lists. * **Bug Fixes** * Deleting a label that’s referenced by an MDM configuration profile or declaration is blocked and returns an error to prevent broken targeting. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
995d366332 |
Add migration to prevent deletion of labels referenced by MDM profiles (#46436)
**Related issue:** Resolves #45182 ## What this does Changes the foreign key constraints on `mdm_configuration_profile_labels` and `mdm_declaration_labels` from `ON DELETE CASCADE` (or no restriction) to `ON DELETE RESTRICT`. This prevents a label from being deleted while it is still referenced by an MDM configuration profile or declaration. Previously, deleting a label that was targeted by a profile would silently remove the label reference, leaving the profile in a \"broken\" state in the UI (showing a \"Label deleted\" warning with no way to recover without re-uploading the profile). With this change, Fleet returns an error when attempting to delete a label that is in use by a profile, prompting the user to remove the profile's label targeting first. ## Why This is part of a broader set of changes (CPIE include/exclude label targeting) that introduces combined include+exclude label targeting on profiles. Allowing silent label deletion would cause ambiguous broken states when both include and exclude labels are in use on a single profile. ## Testing - Migration tested via the accompanying `_test.go` file, which covers: - Label deletion is blocked when referenced by a configuration profile label row - Label deletion is blocked when referenced by a declaration label row - Label deletion succeeds when not referenced by any profile or declaration - Verified that the `ALTER TABLE` DDL change does not trigger `ON UPDATE CURRENT_TIMESTAMP` on `mdm_configuration_profile_labels.updated_at` (DDL does not fire row-level triggers) # Checklist for submitter ## Testing - [x] Added/updated automated tests ## 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`). |
||
|
|
d5e0c5d352 |
resend config profiles on no device mapping user (#46623)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34668 # 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 profile resend behavior so configuration profiles are retried using available identity attributes when a host has no linked IdP user or the referenced IdP user is missing. * Ensured profile resend markers are cleaned so pending resends behave correctly after identity changes. * **Tests** * Improved test coverage to validate profile resend and status reset when device mappings or identity links change. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
59a673bc15 |
Added trace sampler to use OTEL in prod. (#46595)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #44652 Docs: https://github.com/fleetdm/fleet/pull/46631 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [x] Setting(s) is/are explicitly excluded from GitOps <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Route-aware OpenTelemetry trace sampling with tiered default ratios (very low for select high-volume routes, reduced rate for admin reads, full sampling otherwise). * Admin-only GET/PATCH /debug/trace_sampler to view and update sampling ratios and a runtime "force full" toggle. * Liveness probe endpoints (/healthz, /version, /metrics) are excluded from tracing; settings propagate to replicas at runtime without restart. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
cbf2be25ed |
Fix host software label scope after FMA replacement (#46649)
Resolves #43863 |
||
|
|
a4d1cfab1f |
CSUD: Add validation for OS Update profiles and OS updates being configured (#46545)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45282 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Deploy custom OS update configuration profiles for Apple (macOS/iOS/iPadOS) and Windows; tracks and enforces one custom OS‑update profile per scope. * **Improvements** * Prevent changing OS update settings when a custom profile exists; returns guidance to remove the custom profile first. * Batch upload now detects OS‑update payloads and enforces license requirements. * UI error handling surfaces API-specific messages. * FileVault control separated from OS updates and gated behind a configurable flag/license. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ea5b15699e |
windows_mdm: link enrollment row via DevDetail at first management session (#46268)
Closes the race after Windows BYOD MDM enrollment (Settings > Access work or school > Connect) where mdm_windows_enrollments.host_uuid stayed empty for ~10s while osquery's distributed-read cycle ran directIngestMDMDeviceID Windows. During that gap any server-side lookup keyed on host UUID via MDMWindowsGetEnrolledDeviceWithHostUUID returned NotFound. processIncomingMDMCmds now inspects unlinked enrollments on every management session: it parses any incoming Results for ./DevDetail/Ext/Microsoft/SMBIOSSerialNumber, looks up the Windows host by hardware_serial, and updates host_uuid. If still unlinked after processing the incoming message, it appends a Get for that LocURI to the response so the device replies on the next round-trip. The Get is idempotent and reinjected each session until linkage succeeds. The post-link UPN/SCIM/DEP bookkeeping previously inlined in directIngestMDMDeviceIDWindows is extracted into a shared helper (osquery_utils.LinkWindowsHostMDMEnrollment) so both the new SyncML path and the osquery direct-ingest backstop run it exactly once per linkage. New datastore method WindowsHostLiteByHardwareSerial does a Windows-only serial lookup and returns NotFound when two Windows hosts share a serial, so we never mis-link on virtualization-shared SMBIOS values. For Autopilot and Entra-during-OOBE the host record does not exist until fleetd installs later in ESP, so the osquery backstop and the name-based fallback in setup_experience.go remain in place for those flows. <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #45380 # 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] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Immediately link Windows BYOD MDM enrollments to host records during the first management session when a device serial is present, and prompt the device to resend serial info if missing. * Detect and ignore placeholder/ambiguous hardware serials to avoid incorrect host linking. * Reduce noisy warnings for internal-sync command IDs. * **Bug Fixes** * Resolve a race causing Windows MDM enrollments to remain unlinked for several seconds. * **Tests** * Added coverage for serial-based linkage, retry behavior, placeholder detection, and internal-command ID handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Konstantin Sykulev <konst@sykulev.com> |
||
|
|
0858580ff5 |
Refactored ListHostSoftware and ModifyAppConfig for nilaway (#46555)
Refactored `ListHostSoftware` and `ModifyAppConfig` into smaller helpers so nilaway can analyze them for nil-pointer dereferences <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46554 Refactoring. No functional changes. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved host software listing by consolidating assembly, merging, deduplication, and out-of-scope filtering into dedicated helpers for more reliable and maintainable results. * Streamlined app configuration updates by extracting conditional-access (Okta) validation into a focused helper, improving validation consistency and error reporting. * **Chores** * Updated static analysis configuration: bumped a pinned plugin version and removed a suppression rule that hid certain internal lint messages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
00d340291c |
Mark ptr methods as deprecated (#46626)
Mostly to prevent AIs from picking them instead of using new (because then the linters in CI complain). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Deprecated internal pointer helper functions in favor of Go's standard pointer allocation syntax. Updated test files throughout the codebase to use the standard approach for consistency and maintainability. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
38d13b135c |
Skip policy_membership writes for unchanged values (#44191)
Implements the optimization described in [#44191](https://github.com/fleetdm/fleet/issues/44191): inside `RecordPolicyQueryExecutions`, fetch the existing `policy_membership` rows for the incoming policies and narrow the UPSERT batch to only the rows whose stored value differs from incoming. Steady-state rows are skipped entirely. The added SELECT is a small indexed lookup on `(host_id, policy_id)`; the savings are on the writer side, which is the loadtest bottleneck. |
||
|
|
923d1a2e3d |
Fix FK constraint failure in RecordPolicyQueryExecutions when policy deleted mid-flight (#46587)
Fixes #40362 Use INSERT IGNORE in the sync path so that a policy deleted between distributed query dispatch and result ingestion is silently skipped, matching AsyncBatchInsertPolicyMembership which already handles this race with the same approach. |
||
|
|
1072c852e8 |
Added support for validating Microsoft Entra v2 access tokens (#46416)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46388 Video demo: https://www.youtube.com/watch?v=t3yuGh0kwP8 Docs PR: https://github.com/fleetdm/fleet/pull/46483 # 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`. - [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. ## New Fleet configuration settings If you didn't check the box above, follow this checklist for GitOps-enabled settings: - [x] Verified that the setting is exported via `fleetctl generate-gitops` - [x] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [x] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [x] Verified that any relevant UI is disabled when GitOps mode is enabled <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * UI to add/remove Entra application (client) IDs for Windows automatic enrollment; add/delete modals and list management. * **Enhancements** * Activity feed entries for added/removed Entra client IDs. * Entra client ID allowlist surfaced in GitOps and persisted config; client IDs normalized (trim/lowercase) and de-duplicated. * **Documentation** * Note: from July 1, 2026 new on‑prem Windows MDM apps receive Entra v2 tokens with aud = client ID; v1 tokens remain supported. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7fb464abc4 |
Clean up policy query to use parameter binding for platform filter (#46604)
## Summary
- Refactored the conditional access policy query to use `CONCAT('%', ?,
'%')` with a bound parameter instead of string concatenation for the
platform `LIKE` clause, consistent with how other queries in this file
handle string filters.
## Test plan
- [ ] Verify conditional access policy lookup still returns correct
results for macOS/Windows hosts.
- [ ] Confirm no regression in policy filtering behavior.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Improved platform filtering in conditional access policy queries to
enhance query reliability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
abd38218fa |
Self service categories endpoints + activities (#46593)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46391 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] 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 |