26791 Commits
Author SHA1 Message Date
Luke Heath e2ce259bae Cherry-pick #49582: Adding changes for Fleet v4.90.0 (#50652) 2026-08-05 21:10:10 -05:00
Noah Talerman 39d57caa09 Release article: Fleet 4.90.0 (#50240) 2026-08-05 20:42:47 -05:00
Rachael Shaw bfa766e9b7 v4.90.0 doc changes (#48141) 2026-08-05 20:38:39 -05:00
Luke Heath cca2f084a1 Restore "disagree and commit" to company values (#50591) 2026-08-05 20:26:39 -05:00
Andrey Kizimenko 8c6bedf661 Hangar: local dev environment — multi-server + SCEP, MDM assets & TUF tabs (#49454)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** N/A — internal developer tooling (`tools/hangar`).

## Summary

Fleet Hangar is the local dev-environment control panel (`tools/hangar`,
Go + Wails). This PR expands it into a broader **local dev-services**
toolkit for contributors/QA:

- **Multi-server support** — run up to 3 independent local Fleet servers
in parallel, each on its own git worktree, offset ports, and docker
compose project (server switcher + server-scoped
Server/Logs/Database/Git tabs).
- **SCEP tab** — run local SCEP CA servers using the in-repo
`server/mdm/scep/cmd/scepserver` (built once to a cached binary).
Per-depot profiles, `ca -init`, concurrent start/stop with live logs,
and one-click copy for the SCEP URL / challenge / thumbprint (parsed
from `ca.pem`).
- **MDM assets tab** — run `tools/mdm/assets export` from saved configs;
results list each written file with copy-contents/path + size +
timestamp, plus the `FLEET_MDM_APPLE_*` env block.
- **TUF tab** — drive `tools/tuf/test/main.sh` from platform checkboxes.
Hangar runs the file-server itself (`SKIP_SERVER=1`) so `fleetctl
package` can reach the TUF URL during packaging; streams live build
output; shows ngrok tunnel + TUF-server prerequisites; and offers
kill-server + delete-assets.
- **Supporting work** — DB backups in app-data + cross-server restore;
ngrok live public-URL links + stale-tunnel heal; per-server
open-in-browser; Settings → Troubleshoot cards to reap stray
`scepserver`/TUF-server processes and delete `test_tuf`.

Opening as a **draft for transparency**. All changes are confined to
`tools/hangar/`; nothing touches the Fleet server, agent, or any shipped
code.

**Architecture:** each tab is an `internal/<feature>` package (pure,
unit-tested logic) behind a thin `services/<feature>_service.go` Wails
adapter, reached from the UI as `api.*`. Long-running processes go
through the shared process engine; everything builds from / runs against
the primary repo (Server 1).

# Checklist for submitter

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

- [ ] Changes file added for user-visible changes — N/A: `tools/hangar`
is a developer tool and is not part of a Fleet release.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented, JS inline code is prevented, and untrusted data
interpolated into shell scripts/commands is validated against shell
metacharacters.
- External commands (`scepserver`, `go run ./tools/mdm/assets`, `bash
main.sh`, the backup/restore `docker` invocation) are spawned with
discrete argv slices via the process engine — no shell string
interpolation — so user-supplied values (challenge, enroll secret,
depot/dir paths) can't inject. Backup names are validated to
`[A-Za-z0-9._-]`; server-id path segments are sanitized to
`[A-Za-z0-9_-]` (no traversal); TUF asset deletion is scoped to
`<repo>/test_tuf`.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- Binary builds / one-shot commands run under bounded
`context.WithTimeout`; the TUF-server readiness and ngrok local-API
fetches use short HTTP timeouts; no unbounded loops or retries were
added.
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI — N/A: no Fleet server API
changes.

## Testing

- [x] Added/updated automated tests
- Go unit tests across the new packages: `settings` (SCEP profiles, TUF
config, `migrate` incl. the empty-`servers` case), `scep` (depot/CA
parsing, arg builders), `mdmassets` (export args, `wrote … in …`
parsing, config persistence), `tuf` (env building, file-server args,
asset delete), and `troubleshoot` (live-PID filtering) — plus the
existing backups logic.
  - `tsc --noEmit` clean and `task build` green.
- [ ] Where appropriate, automated tests simulate multiple hosts and
test for host isolation — N/A.
- [x] QA'd all new/changed functionality manually (ongoing local testing
of all three tabs).

## Database migrations

N/A — no database migrations.

## New Fleet configuration settings

N/A — no Fleet server configuration settings (Hangar stores its own
settings in app-data).

## fleetd/orbit/Fleet Desktop

N/A — no fleetd/orbit/Fleet Desktop changes.


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

* **New Features**
* Multi-server support (up to three) with server switcher, server-scoped
health/logs, and server-scoped Docker Compose controls.
* New **Servers** settings section plus per-server configuration
(including ports/compose project) and server-aware start/stop/quit
flows.
* New **SCEP**, **MDM Assets**, and **TUF** tabs for managing
profiles/assets and discovering ngrok URLs.
  * Git worktree listing/creation/removal.
  * Centralized, server-scoped database backup management.
* **Bug Fixes**
* Improved process discovery to skip dead or racing entries and avoid
duplicate docker-compose-up display.
  * Self-healing pruning of stale ngrok tunnel selections.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 17:48:34 -05:00
Magnus Jensen c348feb0d5 fix asset reference issue on ddm upsert with no change (#50638)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves nothing, just something I found.

# 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. (None, as editing profiles is only just released)

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


TO test upload a DDM profile referencing an asset, then try to edit that
profile with identical DDM contents and see mysql error, this PR fixes
that.

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

* **Bug Fixes**
* Improved Apple device management declaration updates to preserve the
existing declaration identity.
* Correctly synchronizes linked asset references when declarations are
updated, including removing outdated references and clearing all
references when none remain.
* **Tests**
* Added coverage for creating, preserving, updating, removing, and
clearing declaration asset references.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 23:50:47 +02:00
Sharon Katz 7737b31069 Add handbook guidance for code review coverage during time off (#50620)
**Related issue:** Closes #49286

# 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`.~ N/A (handbook-only
change)

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

- ~Added/updated automated tests~ N/A (handbook-only change)
- ~Where appropriate, automated tests simulate multiple hosts and test
for host isolation~ N/A

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

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

- ~Confirmed that the fix is not expected to adversely impact load test
results~ N/A
- ~Alerted the release DRI if additional load testing is needed~ N/A

## Summary

Adds a "Code review coverage during time off" section to the Product
groups handbook page. When a small product group (2-3 engineers) has
someone on vacation, this documents the process: start with AI review,
then have the EM find a temporary human reviewer from another group,
preferably one the EM also manages.
2026-08-05 17:13:32 -04:00
George Karr 985ebe3c38 Make dashboard 'Hosts enrolled' platform links keyboard accessible (#48214) (#49839) 2026-08-05 16:01:21 -05:00
George Karr 40d58607bb Fix script/query editor selecting text when scrolling after a single click (#48490) (#49744) 2026-08-05 16:00:56 -05:00
Mike McNeil 0ca1b243f8 Update go-to-market-operations.md (#50467)
Everyone just calls them SLAs
2026-08-05 16:08:36 -04:00
6895697d2a QA: dedicated Windows Autopilot setup experience test + blank enrollment step (#50619)
## What / why

Follow-up to [#49134](https://github.com/fleetdm/fleet/issues/49134)
(Windows Autopilot ESP intermittently hanging on "Account setup" due to
a user-scope ESP node race). Adjusts the release QA template so this
failure mode is caught going forward.

## Changes

Builds out the **Power to PC → Setup experience** row into a dedicated
**Windows Autopilot / Entra OOBE enrollment** test, mirroring the
**Apple at Work → Setup experience** row:

- **Full configuration** run — specifies exactly what to configure so
the enrollment exercises every setup-related item (end user auth, config
profile, OS updates, disk encryption, software), enroll a real Autopilot
host, and verify the ESP completes and all items apply.
- **Blank enrollment** run — enroll into "No team" with **nothing
configured**, repeated **2-3 times**. Because the original bug was an
intermittent race, a single pass doesn't prove correctness. The ESP must
complete and reach the desktop every time (no "Account setup" hang).

The basic Autopilot enroll remains in "MDM enrollment flow" (mirrors
Apple keeping basic ADE enroll there).

Docs-only change to `.github/ISSUE_TEMPLATE/release-qa.md`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Joe Grant <thisisjoegrant@gmail.com>
2026-08-05 13:07:34 -07:00
Jonathan Katz a0805e49d8 Add software installer file size check before upload (#50475)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #42735 
- Exposes max_software_package_size in the `GET /api/v1/fleet/config`
endpoint
- Add frontend logic to use it to deny files that are too big before
they get uploaded

# 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
  - Tested on Chrome, Safari, and Firefox on macOS


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

* **New Features**
* Added a configurable maximum software package size to application
settings.
* Software uploads exceeding the limit are rejected with a clear,
size-specific error message.
  * Packages at or below the configured limit are accepted.
  * Added user-friendly file-size formatting across common units.
* Upload validation accounts for the complete request size, including
scripts and settings.

* **Tests**
* Added coverage for upload validation, boundary conditions, size
formatting, and configuration responses.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 15:57:20 -04:00
ecdf1ff003 Add TeamViewer Host as a Windows Fleet-maintained app (#50553)
**Related issue:** Resolves #50332

Adds **TeamViewer Host** as a Windows Fleet-maintained app.

## The issue's premise was wrong — this needed no new capability

#50332 was blocked on "not in winget." It is in winget:
`TeamViewer.TeamViewer.Host`, published continuously since **June 2023**
(v15.42.8), currently **15.80.4** (merged upstream as
microsoft/winget-pkgs#409335, 2026-07-29). I downloaded the live x64
installer and its SHA256 matches that manifest byte-for-byte.

It reads as absent because it's nested a level deeper than you'd expect
— `manifests/t/TeamViewer/TeamViewer/Host/`, a sibling of the full
client's *version* directories rather than of the publisher's package
directories.

Consequence: this comes off the dependency on #50364, and that FR loses
one of its three examples. The other two (#50328, #50329, OLE DB Driver
18/19) still hold — there is no OLE DB package under any winget
publisher.

## Identity verified against the installer, not winget metadata

Per the `new-fma` golden rule, from the x64 MSI's `Property` and
`Registry` tables:

| Field | Value | Evidence |
|---|---|---|
| `unique_identifier` | `TeamViewer Host` | MSI `ProductName`; no
`ARPDISPLAYNAME`, empty `Registry` table, so this is the ARP DisplayName
|
| publisher | `TeamViewer` | MSI `Manufacturer`, equal to the winget
locale `Publisher` → no `program_publisher` override |
| `installer_scope` | `machine` | `ALLUSERS=1` |
| bootstrapper? | No | no `ARPSYSTEMCOMPONENT` |

Corroborated independently by [silentinstallhq's PSADT
script](https://silentinstallhq.com/teamviewer-host-install-and-uninstall-powershell/),
which detects the app with `Get-InstalledApplication -Name 'TeamViewer
Host'` and uses `/S` for both install and uninstall.

Generated exists query:

```sql
SELECT 1 FROM programs WHERE name = 'TeamViewer Host' AND publisher = 'TeamViewer';
```

No collision with the existing `teamviewer/windows` FMA, which generates
an exact `name = 'TeamViewer'`.

## Why exe + `ignore_hash`, matching the full client

winget offers Host as an NSIS exe and as a nested `wix` MSI inside a
zip. The ingester can't select the zip (`installer.InstallerType` is
`zip`, which never normalizes to `msi`), so the exe is the only
reachable installer.

TeamViewer publishes no version-pinned Host exe —
`TeamViewer_Host_Setup_x64_15.80.4.exe` and the x86 equivalent both 404
— so the manifest's URL is the unpinned `TeamViewer_Host_Setup_x64.exe`
and `ignore_hash: true` is required. This is vendor asymmetry, not a
fixable winget defect: the *full* client does publish pinned exe URLs.
Same reason `teamviewer/windows` already sets `ignore_hash`.

## Correcting the coexistence note in #50332

The issue assumed Host and the full client can co-exist. They can't. The
Host MSI's `LaunchCondition` table blocks the install outright:

> Error 25001: An incompatible TeamViewer package was detected that
conflicts with the current MSI package: TeamViewer_Full 64-bit. Please
manually uninstall this package.

…plus equivalents for Full 32-bit/ARM64, Host ARM64, and the NSIS
installs. **Relevant to validation: the validator host must not already
have `teamviewer/windows` installed.**

## Icons

No `index.ts` change needed — `matchLoosePrefixToKey` treats keys as
whole words at the start, so `"teamviewer host"` matches the existing
`teamviewer` key and inherits the TeamViewer brand icon. Verified
against the real 1,163-key map.

The website resolves its icon from the slug
(`app-icon-${slug}-60x60@2x.png`) with no such fallback, so
`app-icon-teamviewer-host-60x60@2x.png` is added — a copy of the
existing TeamViewer brand asset, since Host ships the same logo.

## Two things for review

1. **The PowerShell is unverified.** Authored on macOS with no
PowerShell available, so install/uninstall have not been executed. The
uninstall script searches ARP by DisplayName instead of a hardcoded key,
and uses the three-shape `UninstallString` parser (TeamViewer's is
unquoted and contains a space in `C:\Program Files\...`, which the older
`.Split('"')` approach in `teamviewer_uninstall.ps1` mishandles).
Validator run is the real check.
2. **Category mismatch with the macOS side.** This uses `Communication`,
matching the merged `teamviewer/windows`. #47121 adds
`teamviewer-host/darwin` with `Productivity`. Worth reconciling — and
that PR will want this same website PNG, so expect a trivial conflict.

`name` is `TeamViewer Host`, matching #47121 so both platforms group
together in the FMA library.

## Testing

- [x] `go test ./cmd/maintained-apps/... ./ee/maintained-apps/...`
passes
- [x] Generator is idempotent — re-running produces no diff and
preserves the `apps.json` description
- [x] `apps.json` is valid JSON with no empty descriptions
- [x] Live installer SHA256 confirmed against the winget manifest
- [ ] FMA validator: install → detect → uninstall on a Windows host
**(pending — needs a host without the full TeamViewer client)**

No shared code changed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Allen Houchins <allenhouchins@mac.com>
2026-08-05 14:04:49 -05:00
Allen Houchins 92aaf1de81 Fix Steam patch policy comparing an empty bundle_short_version (#50428)
**Related issue:** Resolves #50408

## What changed

Steam.app ships without a `CFBundleShortVersionString`, so osquery's
`apps.bundle_short_version` is an empty string:

```
$ /usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" /Applications/Steam.app/Contents/Info.plist
Print: Entry, ":CFBundleShortVersionString", Does Not Exist
$ /usr/libexec/PlistBuddy -c "Print :CFBundleVersion" /Applications/Steam.app/Contents/Info.plist
6.0
```

The generated patch policy compared that column, and
`version_compare('', '6.0')` returns `-1`, so the `< 0` predicate was
always true. The "Steam up to date" policy could never pass on **any**
host with Steam installed, at any version. Meanwhile software inventory
falls back to `bundle_version` and correctly showed Steam as up to date,
so the two features disagreed about the same app on the same host — and
with `install_software: true` the policy repeatedly reinstalled a
version that was already installed.

This adds a per-app override in the homebrew ingester comparing
`bundle_version` (CFBundleVersion `6.0`, which the cask version tracks),
following the pattern already used for `sonos` and the Firefox
pre-release channels:

```diff
-version_compare(bundle_short_version, '6.0') < 0
+version_compare(bundle_version, '6.0') < 0
```

`ee/maintained-apps/outputs/steam/darwin.json` was regenerated with `go
run ./cmd/maintained-apps -slug steam/darwin` — one line changed, no
upstream version drift pulled in.

## Why scoped to one app

The issue suggested changing the shared darwin version column in
`pkg/patch_policy` to `COALESCE(NULLIF(bundle_short_version, ''),
bundle_version)`. I didn't do that. It would be a no-op for the ~300
macOS FMAs that do set a short version, but that generator is
load-bearing for every one of them, and the blast radius isn't justified
by a single broken app. The per-app override is the established
mechanism for exactly this.

Side note for a possible follow-up: `patch_policy_path` exists in both
the homebrew and winget input structs but is never read anywhere — a
dead field. If we want a data-driven way to express these overrides
instead of token checks in Go, that's the hook.

## Reviewer note: existing deployments do not self-heal

`software_installers.patch_query` is snapshotted when the installer is
created, and only refreshes on an FMA version change or an "Edit
software" save. **Steam's cask version is a static `6.0`**, so this
manifest change alone will not fix already-deployed Steam FMAs — the
admin has to re-add or re-save the app. A GitOps re-apply doesn't help
either; `ApplyPolicySpecs` regenerates from the stale installer row.

Closing that gap means either a migration that rewrites stored patch
queries, or refreshing `patch_query` when the manifest changes at the
same version. Both are broader calls than this bug, so I left them out —
happy to file a follow-up if you want it tracked.

The exists query is unaffected — it matches on `bundle_identifier` only,
with no version predicate. That's why install detection and self-service
always worked correctly for Steam.

# 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. <sub>No new interpolation surface: the override formats
the same bundle identifier and cask version the surrounding generator
already formats.</sub>

## Testing

- [x] Added/updated automated tests <sub>New `steam` case in
`TestIngestApps` asserting both the patched and exists queries.</sub>

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

Validated with osquery **5.23.1** — the same version as in the bug
report. `version_compare('', '6.0')` returns `-1` and
`version_compare('6.0', '6.0')` returns `0`, confirming the root cause
directly.

For an end-to-end check against the real `apps` table without planting a
fake Steam.app on a Fleet-enrolled host, I used an already-installed app
with the identical shape (`com.citrix.HDXCast`: empty
`bundle_short_version`, `bundle_version` `24.05.0.3`):

| Query | Host state | Result |
|---|---|---|
| exists | app installed | row → detected  (unaffected by the bug) |
| **old** patched | up to date | **no row → policy FAILS** ← reproduces
the bug |
| **new** patched | up to date | row → policy PASSES  |
| **new** patched | genuinely outdated (available `25.0.0`) | no row →
policy FAILS  |
| **new** patched, verbatim from the regenerated manifest | Steam not
installed | row → PASSES  |

The fourth row is the important one: the fix is not a blanket pass — it
still fails hosts that are genuinely behind.

Not verified: a live host with Steam actually installed (I don't have
one). The `com.citrix.HDXCast` row has byte-identical column semantics,
so I'm confident, but a QA pass on a real Steam host would close it out.

`go test ./cmd/maintained-apps/... ./pkg/patch_policy/...
./ee/maintained-apps/...` passes; `go vet` and `gofmt` clean. I could
not run `make lint-go-incremental` locally — it builds a custom
golangci-lint via `git clone`, which my sandbox blocked, so I'm relying
on CI for that.


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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved Steam patch detection on macOS by using the correct
application version information.
* Steam updates are now accurately recognized in Fleet software
inventory and Homebrew-generated patch policies.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 13:38:20 -05:00
Allen Houchins b8e324383d Document the build-enforced 150-char meta description limit in content skills (#50166)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** N/A

# Checklist for submitter

This PR only edits Claude Code skill files under `.claude/` — no product
code, so most of the template below doesn't apply.

## What changed

Documents the **build-enforced 150-character limit on `<meta
name="description">`** in the content skills that generate that tag.

`website/scripts/build-static-content.js:687` throws `An article page
has an invalid description meta tag` and fails the entire production
build for any page whose description exceeds 150 characters, regardless
of category. Before this PR:

- `fleet-article-formatting` never mentioned the limit at all. It had
**no endmatter section whatsoever**, and `assets/article-template.md`
shipped `<meta name="description" value="">` with no guidance in the
placeholder.
- `fleet-guide-formatting` and
`content-style/references/content-types.md` stated "150 chars max" as
what reads like a style preference, with no indication that going over
breaks the deploy.

So a draft could satisfy every skill self-check and still fail the
build.

Changes:

- **`fleet-article-formatting/SKILL.md`** — new `### Endmatter` section
covering the 150-char limit (naming the enforcing script and the error
message), `articleTitle` matching the H1 exactly, and the no-fabrication
rule for `authorFullName`/`authorGitHubUsername`/`publishedOn`. Added a
matching self-check bullet.
- **`fleet-article-formatting/assets/article-template.md`** — filled in
the empty `description` placeholder with the constraint.
- **`fleet-guide-formatting/SKILL.md`** — the two existing 150-char
mentions now say build-enforced and name the failure mode.
- **`content-style/references/content-types.md`** — same note on the
shared endmatter block both skills point at, so it's stated once at the
source.

Each spot also says to **count** the characters rather than estimate,
which is the actual failure mode: a description that reads like one or
two natural sentences lands just over 150 more often than you'd expect.

## Why

Found the hard way. A case study drafted in
[#50152](https://github.com/fleetdm/fleet/pull/50152) had a
153-character description that read as perfectly reasonable length and
broke `npm run build-for-prod`:

```
Error: Failed compiling markdown content: An article page has an invalid description meta tag
(<meta name="description" value="Hawx automated seasonal iOS onboarding and offboarding with Fleet,
Tines, and Okta, eliminating start-of-season helpdesk floods in a one-month migration.">)
at ".../articles/hawx.md". To resolve, make sure the value of the meta description is less
than 150 characters long.
```

The limit is cheap to respect while drafting and annoying to discover at
deploy time, so it belongs in the skills that write the tag.

## Note for reviewers

The proposed `fleet-case-study-formatting` skill in
[#49917](https://github.com/fleetdm/fleet/pull/49917) is **not touched
here**, deliberately, to avoid a conflict with that open PR. Its
`assets/case-study-template.md` already says "150 chars max" in the
description placeholder, though its `SKILL.md` doesn't mention the
limit. Worth adding the build-enforcement note there before that PR
merges, in that PR rather than this one.

- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`. — N/A, Claude Code
config only, not a product change

## Testing

- [ ] Added/updated automated tests — N/A, markdown/config only
- [x] QA'd manually:
- Traced the constraint to its source at
`website/scripts/build-static-content.js:687` and confirmed the quoted
error text and the `> 150` comparison, so the skills describe real
behavior rather than a remembered rule.
- Confirmed the check applies to all categories (it runs before the
`category === 'case study'` branch), which is why the note went in the
shared `content-types.md` block too.
- Scanned every `<meta name="description">` across `articles/`, `docs/`,
and `handbook/`: **0 pages currently exceed 150 characters**, so this is
preventive documentation only and no existing content needs fixing.
- Read the edited skill files back end-to-end for correct rendering and
no contradictions with surrounding guidance.
2026-08-05 13:38:09 -05:00
Jordan Montgomery 117a7ba1f4 Fix reliability around osquery-perf MDM enrollment (#49687)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #

# Checklist for submitter

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

- [ ] 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**
* Improved macOS, iOS, and iPadOS MDM enrollment reliability by
automatically retrying failed enrollment attempts.
* Added randomized delays between retries to support more resilient
startup behavior.
* Improved handling of user identity generation during macOS MDM
enrollment.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 14:06:58 -04:00
Konstantin Sykulev 6613872eda Terraform for mock AMAPI for loading testing (#48919)
Related issue: Resolves https://github.com/fleetdm/fleet/issues/26225

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

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

- **New Features**
  - Added an Android AMAPI mock service for load testing.
- Added configurable image version selection and optional Google API
request forwarding.
- Added routing for mock and API requests through the internal load
balancer.
- Added secure storage and optional access to Google service-account
credentials.
- Exposed the mock service endpoint for downstream load-test
configuration.
- Configured the load-testing environment to use the new internal proxy
endpoint.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 13:04:19 -05:00
Noah Talerman 34532588c6 Update community PR review process (#50601) 2026-08-05 12:34:00 -05:00
George Karrandtest 1dcad647f9 Fix dark-mode contrast of status-filter dropdown selected-value icon (#47581) (#49622)
**Related issue:** Resolves #47581

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

## What / why

In dark mode, the status-filter dropdown's selected-value icon on the
Hosts page rendered near-black and was barely visible at rest (only
appearing on hover/open).

The leading filter icon is rendered two different ways, and both were
broken in dark mode:

1. **SVG icon** (`iconName="filter-alt"` — PoliciesFilter,
HostsFilterBlock) renders `.dropdown__custom-value .dropdown__icon`. The
base `Dropdown` only applied a theme-aware `fill` on hover/open; at rest
it fell back to a near-black default. Added a rest-state rule (`fill:
$ui-fleet-black-75`) so the icon is theme-aware at rest. Light mode
resolves to the same color as before (no visual change); dark mode now
uses the light shade.

2. **Black PNG** (`icon-filter-v2-black-16x16@2x.png` via `::before` —
DiskEncryptionStatusFilter, BootstrapPackageStatusFilter) is a hardcoded
black glyph that never adapts to the theme. Added `filter: invert(1)`
scoped to `body.dark-mode` so it becomes a light glyph in dark mode
only.

Frontend/SCSS-only change.

## Testing

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

Verify in **dark mode** on the Hosts page:
- Controls → OS settings → Disk encryption → click a status (lands on
`/hosts/manage?...&os_settings_disk_encryption=enforcing`) — the
"Enforcing" filter icon is clearly visible at rest.
- Bootstrap package status filter and policy pass/fail filter icons are
also visible at rest.
- Light mode appearance is unchanged.


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

- **Bug Fixes**
  - Improved visibility of selected status-filter icons in dark mode.
- Updated disk encryption, bootstrap package, and policy status filters
on the Hosts page with clearer, theme-aware icons.
- Improved contrast and consistency for dropdown icons across dark-mode
views, preventing selected icons from appearing nearly black or
difficult to see.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: test <test@test.com>
2026-08-05 12:32:08 -05:00
Noah Talerman 781ba43596 Rename 'Certificate enrollment' to 'Certificate authorities' (#50535) 2026-08-05 10:25:09 -07:00
Allen Houchins bc3eee5f32 Re-add Dell Display and Peripheral Manager Windows FMA, validate on client-OS runner (#50313)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** NA (Windows FMA workstream; follow-up to #49127,
which dropped DDPM)

Re-adds **Dell Display and Peripheral Manager**
(`Dell.DisplayAndPeripheralManager` 2.2.2.8) as a Windows
Fleet-maintained app, and adds a `requires_client_os` routing override
so its CI validation always runs on the `windows-11-arm` runner.

## Why DDPM was dropped before, and why it's viable now

DDPM was dropped from the earlier re-add because its InstallShield setup
aborted with `0x80042000` under every documented silent switch, which
was diagnosed at the time as a .NET-prerequisite/headless-chaining
problem. A new debug run with Dell's own `/CreateDebugLog` switch shows
the real cause: the setup evaluates the OS at `OFUIBefore` and
terminates because the runner reports **Microsoft Windows Server 2025**.
DDPM is a Windows 10/11 client application and refuses to install on
Server SKUs — which is exactly what GitHub's x64 `windows-latest` image
is.

```
OSetUMode() 0 AP:2.2.2.8
OFUIBefore
Os Major10 Minor0
OS - 44444
// End Log File...
```

## `requires_client_os` CI routing

- New optional winget input field `requires_client_os: true` (documented
in `ee/maintained-apps/README.md` and on the Go input struct; ignored by
ingestion).
- `.github/scripts/partition-fma-apps.sh` routes any app with this flag
to `windows-11-arm` — the only GitHub-hosted client-OS Windows runner —
regardless of `installer_arch`. The x64 installer runs there under Prism
emulation; DDPM's gate is the OS SKU, not the architecture.
- Verified locally: partitioning the full 421-app Windows catalog
reroutes only `dell-display-and-peripheral-manager/windows`.

## App identity (verified against the real installer)

- Downloaded `DDPM-Setup_2.2.2.8.exe` from `dl.dell.com` (Chrome UA per
#49123); SHA256 matches the winget manifest.
- Embedded InstallShield `[Application]` block: `Name=Dell Display and
Peripheral Manager`, `Company=Dell Technologies`; ProductCode matches
the manifest GUID. The setup log reports `AP:2.2.2.8` as the registering
version.
- Installs with Dell's documented managed-deployment switches `/Silent
/HeadlessMode=true /TelemetryConsent=false /TurnOffCA` — the final
pre-drop iteration (6d0f2c00af), which also declines telemetry and
disables DDPM's self-updater on Fleet-managed hosts. Uninstalls via
`msiexec /x` on the ProductCode looked up in the registry by
DisplayName.

Input/uninstall script/icon are restored from the pre-drop state; the
install script is the final pre-drop iteration with its root-cause
comment corrected (Server-SKU OS gate, not headless-SYSTEM chaining).
Output regenerated (winget still at 2.2.2.8; script refs verified).

# Checklist for submitter

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

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

## Testing

- [x] QA'd all new/changed functionality manually (partition script
exercised locally over the full catalog and a mixed PR-style slug list;
ingester regenerated with no output drift; `go test
./ee/maintained-apps/ingesters/winget/` passes)
- [ ] `test-fma-windows-pr-only` validates DDPM on the `windows-11-arm`
runner in this PR's CI


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

* **New Features**
* Added Dell Display and Peripheral Manager to the Windows software
catalog, including installation, uninstallation, detection, metadata,
and an app icon.
* Added support for routing applications that require a Windows client
operating system to the appropriate Windows 11 ARM test environment.

* **Documentation**
* Documented Windows client operating system routing behavior and test
environment architecture details.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 12:21:55 -05:00
Dante Catalfamo c9001b4e46 Document Android biometric unlock behavior on BYOD work profiles (#50265)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #49655

Documentation-only change. No server behavior changes.

## What's happening

On a personally-owned work profile (BYOD), Android applies the biometric
values of `keyguardDisabledFeatures` to the work profile lock. By
default the end user has one lock for both the work profile and the host
("Use one lock"), so there is no separate work profile lock to restrict,
and Android restricts the host's lock instead. Fingerprint and face
unlock turn off for the whole host, including the end user's personal
apps.

This is documented Android behavior, per
[`setKeyguardDisabledFeatures`](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,%20int)):

> `KEYGUARD_DISABLE_FINGERPRINT`, `KEYGUARD_DISABLE_FACE` or
`KEYGUARD_DISABLE_IRIS` which affects the managed profile challenge if
there is one, **or the parent user otherwise**.

Fleet never sets `keyguardDisabledFeatures` itself. Fleet's default
Android policy sets only `StatusReportingSettings`, and admin-authored
AMAPI policy is passed through as-is. The reason this still lands on
Fleet is that the profile in the bug report is byte-for-byte the example
Fleet publishes at
`docs/solutions/android/configuration-profiles/disable-face-and-biometrics-unlock.json`,
with no note about the BYOD side effect.

## What changed

- `articles/custom-os-settings.md`: new "Biometric unlock on
personally-owned (BYOD) hosts" subsection under "Special Android
behavior", covering the behavior and the configuration that scopes the
restriction to work.
- `docs/solutions/android/configuration-profiles/README.md`: entries for
the biometrics profile (carrying the caveat) and for the new example.
-
`docs/solutions/android/configuration-profiles/require-separate-work-profile-lock.json`:
new example using `passwordScope: SCOPE_PROFILE` and
`unifiedLockSettings: REQUIRE_SEPARATE_WORK_LOCK`.

The remedy needs no Fleet change: `passwordPolicies` is already in the
Android policy field mask
(`server/mdm/android/service/androidmgmt/policy_field_mask_test.go`), so
Fleet already delivers it.

## Testing

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

Docs-only, so no automated tests were added. Verification done:

- Both the new example profile and the combined snippet in the guide
decode into the real `androidmanagement.Policy` struct with
`DisallowUnknownFields`, confirming every key and nesting level matches
the AMAPI schema Fleet ships.
- The documented status flow (`USER_ACTION` non-compliance on
`passwordPolicies` marks the profile "Failed", then "Verified" once the
end user sets the work lock) is confirmed against
`server/mdm/android/service/pubsub_test.go`.

**Not yet verified on hardware.** I have not run the repro on a physical
BYOD Android host. Before merge, this is worth confirming:

1. On a BYOD Android host with fingerprint unlock configured and a work
profile enrolled, apply `disable-face-and-biometrics-unlock.json`.
Confirm fingerprint disappears as an unlock method device-wide.
2. Add the `passwordPolicies` block from
`require-separate-work-profile-lock.json` to that profile and re-upload.
Confirm Android prompts for a separate work profile lock, and that Fleet
shows the profile "Failed" with `USER_ACTION` on **Host > OS settings**
until the end user sets it.
3. After the end user sets the work lock, confirm the profile moves to
"Verified", fingerprint unlock works again on the personal side, and the
work profile still requires PIN/password.


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

## Summary by CodeRabbit

* **New Features**
* Added an Android configuration profile option that requires a separate
lock for the work profile.
* Applies password policy settings specifically to the work profile
scope.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 13:18:26 -04:00
Allen HouchinsandClaude 5ec4c650d3 Update Evernote maintained app to 11.28.2 (#50583)
**Related issue:** Resolves #

# Checklist for submitter

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

## Testing

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

## Summary

Bumps the Fleet-maintained Evernote (macOS) app from `11.27.5` to
`11.28.2`, the latest version per the [Evernote release
notes](https://evernote.com/release-notes).

- Updated `version` and the embedded `version_compare` target in the
`patched` osquery query in
`ee/maintained-apps/outputs/evernote/darwin.json`.
- `installer_url` and `sha256` are unchanged — Evernote's DMG installer
link always serves the latest build (`sha256: "no_check"`).
- `inputs/homebrew/evernote.json` is frozen and untouched, as required.

---
_Generated by [Claude
Code](https://claude.ai/code/session_015tHhSdANCAv2WdENhRF4hf)_

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-05 12:18:23 -05:00
fleet-releaseandallenhouchins 935118d2ab Update Fleet-maintained apps (#50594)
Automated ingestion of latest Fleet-maintained app data.

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

## Summary by CodeRabbit

* **Updates**
* Updated Akiflow, Lulu, PDFsam Basic, and TextExpander for macOS to
their latest releases.
  * Updated Claude and Rancher Desktop for Windows to newer versions.
  * Updated Firefox Nightly for macOS to the latest nightly build.
* Refreshed installer details and verification data to support the
updated packages.

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

Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
2026-08-05 12:16:24 -05:00
Magnus JensenandCopilot Autofix powered by AI 3cbdff01cd Update Release from AB modal copy and route back to list hosts on Pending (#50558)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #50350 and Resolves #50358 

# 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

* **New Features**
  * Added enrollment-status messaging when releasing a host.
* Pending-enrollment hosts now display a notice that they will also be
removed from Fleet.
  * Added a “Learn More” link to release-device documentation.

* **Bug Fixes**
* Improved navigation after releasing hosts with pending enrollment by
returning to the hosts list.
* Prevented unnecessary host details and activity refreshes when
pending-enrollment hosts are released.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-05 19:16:03 +02:00
Eric 1563aeb70c Website: improve speed of deliver-talk-to-us-form-submission action (#50593)
Changes:
- Updated the model used in the prompt helper calls in the
deliver-talk-to-us-form-submission action and the get-enriched helper to
improve the speed of routing users booking a demo.

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

## Summary by CodeRabbit

* **Improvements**
* Updated location and address enrichment to use an updated language
model, improving the processing of submitted information while
preserving existing form behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 11:42:13 -05:00
c24983294e Update Fleet server config documentation for local storage (#50489)
Related: #39896

Context: 

I found that we use `FLEET_SOFTWARE_INSTALLER_STORE_DIR` env variable in
[render.yaml](https://github.com/fleetdm/fleet/blob/9b51376f83af8c7c2b2335ff0a1ab146ae13238f/render.yaml#L15).
S3 is the best practice and should be used in production, we even have a
[log](https://github.com/fleetdm/fleet/blob/9d0f510a8db6a470ecf83cc0076680c4d518ea7e/cmd/fleet/serve.go#L568)
that says that.

Since we officially support Render deployment, and Render doesn't
support S3, I think we should document this exception.

More context:
https://fleetdm.slack.com/archives/C051QJU3D0V/p1785496835774739

---------

Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com>
Co-authored-by: Robert Fairburn <8029478+rfairburn@users.noreply.github.com>
2026-08-05 11:22:55 -05:00
RachelElysia 8d616e31cb Fleet UI: Flush Self-service search right without Install all button (#50534) 2026-08-05 09:15:15 -07:00
Noah Talerman 30c8362e0e Update sprint review ritual (#50580)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Updated the Product Design review ritual guidance to cover Drafting
board cleanup, milestone updates, and Feature fest board preparation.
* Removed outdated steps related to unestimated and discontinued
stories.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 12:08:55 -04:00
fleet-releaseandallenhouchins d2fe9be461 Update Fleet-maintained apps (#50584)
Automated ingestion of latest Fleet-maintained app data.

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

## Summary by CodeRabbit

* **Updates**
  * Updated Graphviz for Windows to version 15.1.1.
  * Updated PDFsam Basic for Windows to version 6.0.5.0.
  * Updated Visual Studio Code for macOS to version 1.132.0.
  * Updated Wavebox for macOS ARM to version 151.2.148.2.
  * Updated WhatsApp for macOS to version 26.31.19.
  * Refreshed installer details and version checks where applicable.

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

Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
2026-08-05 10:23:17 -05:00
fleet-releaseandallenhouchins 72c224bd78 Update Fleet-maintained apps (#50574)
Automated ingestion of latest Fleet-maintained app data.

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

## Summary by CodeRabbit

* **Updates**
* Refreshed supported macOS and Windows application packages to their
latest releases, including Asana, Chrome, Dropbox, Microsoft 365,
Postman, Thunderbird, Todoist, and many others.
* Updated version detection so devices recognize the new releases and
receive applicable upgrades.
  * Refreshed installer downloads and verification data where required.
* Updated installation instructions for selected applications, including
Duo Desktop, Microsoft Office, Nextcloud, Nudge, Santa, and Tailscale.

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

Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
2026-08-05 09:14:46 -05:00
Jonathan Katz 298146f8c4 Patch when closed: Fix generate-gitops generating invalid file and frontend copy (#50542)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** 
Resolves #50522 
Resolves #50523 

# 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

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**
* Pre-install queries are no longer exported for apps configured to
patch when closed.
* Updated automation activity labels to clearly identify skipped
patches, including the software name when available.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 10:02:26 -04:00
Magnus Jensen 1abeb175f3 AULD: Enrollment insert and backfill osquery query (#50131)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #47714 

# 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 be part of 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

* **New Features**
* Collect and persist macOS software update device identifiers for hosts
during both manual and OTA enrollment flows.
* Added an osquery detail/query to derive the identifier from hardware
properties and upsert it into datastore.
* **Bug Fixes**
* Host deletion now also removes related Apple macOS OS update records.
* **Improved Device Recognition**
* Enhanced Mac model identifier parsing and refined Apple Silicon
detection with expanded test coverage.
* **Reliability**
* Enrollment profile delivery remains unaffected if saving the
identifier fails (errors are logged).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 15:37:05 +02:00
Andrew MellorandMagnus Jensen 192ac4eb51 48093 auld api gitops latest os version (#50213)
**Related issue:** Resolves #48093

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

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

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

- [x] Verified that the setting is exported via `fleetctl
generate-gitops`

- [x] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)


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

* **New Features**
* Added “latest” version enforcement for macOS, iOS, and iPadOS updates
using required `deadline_days`.
* Updates dynamically target each device’s available OS version and
deadline.
  * Configuration and GitOps outputs now include `deadline_days`.

* **Bug Fixes**
* Improved validation when switching update modes or omitting deadline
settings.
* GitOps updates now clear previously stored deadline values when
omitted.
  * Changes to `deadline_days` are detected and applied consistently.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Magnus Jensen <magnus@fleetdm.com>
2026-08-05 12:37:11 +01:00
Rajendra Kadam 5e95589554 Support custom activations and management declarations for DDM profiles (#50280)
**Related issue:** Resolves #49970

Adds custom activations to the single-profile paths for declaration
(DDM) profiles — create, edit, delete and read — and unblocks management
declarations. Part of #48222.

Batch/GitOps is #49972; serving the custom activation to devices is
#49971.

### Custom activations

- `POST /configuration_profiles` and `PATCH
/configuration_profiles/{uuid}` accept an optional `activation` file
part, rejected for any profile type other than an Apple declaration.
- Validation requires an activation `Type` (any
`com.apple.activation.*`, so future Apple types need no Fleet change),
an `Identifier`, and exactly one `StandardConfigurations` entry naming
the configuration it ships with. `Predicate` and every other key are
stored and served verbatim for the device to evaluate.
- Premium-only, unconditionally. `parseAndValidateAppleDeclaration`
requires premium only when a fleet or labels are involved, so an
unassigned unlabeled DDM profile is free today; the activation carries
its own gate.
- The activation's Fleet variables are validated against
`fleetVarsSupportedInDDMDeclarations` — already exactly the set
specified for activations — and associated via
`mdm_configuration_profile_variables.apple_ddm_activation_uuid`.
- Returned base64-encoded on both the list and single-profile endpoints,
per the API reference draft (#49768), and omitted entirely when absent.

What an edit does to a stored activation:

| Request | Result |
| --- | --- |
| activation supplied | replaces the stored one |
| new profile content, no activation | stored one is cleared — this is
how it's removed |
| labels-only edit | stored one is carried forward |

The third row matters: the datastore clears the activation of any
declaration written without one, so a labels-only edit rebuilding the
declaration from the existing row would otherwise silently wipe it.
`GetMDMAppleDeclaration` loads the activation so it can be carried
forward, and there's a test asserting it.

### Management declarations

`com.apple.management.*` uploads are unblocked via a prefix check, so
future management declarations work without a product change. Types to
block go in the existing `ForbiddenDeclTypes` deny list, which is
already evaluated ahead of the prefix. An activation supplied alongside
a management declaration is rejected — those are never activated.

Routing them to the manifest's Management section is #49971's work.

### Notes for review

**Where the non-declaration guard lives differs by path, deliberately.**
Create resolves the profile type in the endpoint from the uploaded file;
edit resolves it in the service from the UUID prefix. The check sits
wherever the type becomes known. Both use the same message so the
mistake reads identically.

**Endpoint-level errors must be returned from behind an authz check.**
The create-path guard originally returned the error straight from the
endpoint, which skips authorization and surfaces to the client as a bare
`forbidden` rather than the validation message. It now goes through
`NewMDMActivationUnsupportedProfile`, alongside the existing
`NewMDMUnsupportedConfigProfile` and `NewMDMInvalidJSONConfigProfile`,
which exist for the same reason. This was caught by the integration
tests, not the unit tests — service-level tests bypass the authz
middleware.

**Activation rows are keyed on `declaration_uuid`, not inserted fresh.**
An edit reuses the row, so the Fleet variable associations hanging off
it survive. The UUID is read back after the upsert rather than reusing
the generated one, since `ON DUPLICATE KEY UPDATE` keeps the existing
row.

**Secrets are expanded for validation but stored unexpanded**, so
validation runs against the document the device receives without
persisting secret values.

`MDMAppleCustomActivation` is the storage type; `MDMAppleDDMActivation`
was already taken by Apple's wire format.

# 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: the feature isn't reachable by users until the DDM sync
work in #49971 lands.

## Testing

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

**Unit** (`server/fleet`): `GetRawActivationValues` and
`ValidateUserProvided` — valid activation, unknown type under the
activation prefix, missing `Type`, a configuration type supplied as an
activation, missing `Identifier`, zero/multiple/mismatched
`StandardConfigurations`, all problems reported at once, plus
`IsManagementDeclaration`.

**Service** (`server/service`): activation accepted, mismatched
configuration rejected, malformed JSON rejected, rejected on a
management declaration, supported Fleet variables recorded, unsupported
rejected, premium required even where the declaration is free. On edit:
activation-only edit keeps content, labels-only edit preserves the
activation, new content without an activation clears it, and exactly one
`edited_declaration_profile` activity fires.

**Datastore** (`server/datastore/mysql`): write, read-back through list
and single get, edit reusing the row, Fleet variable association, and
removal cascading to the variable rows.

**Integration** (`integration_mdm_ddm_test.go`): multipart upload with
an activation, read back and asserted base64-decoded against the raw
response body; the key omitted entirely for a declaration without one;
two management declarations uploaded and coexisting; activation on a
`.mobileconfig` rejected on both create and edit; activation-only
`PATCH` replacing the activation while leaving the declaration
untouched.

The multipart test helper now supports more than one file part — nothing
could build that request before, which is why the decode path was
previously untested. Single-file callers are unchanged.


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

- **New Features**
- Added optional custom activations for Apple DDM configuration
declarations.
- Activations support secrets, Fleet variables, and custom host vitals.
- Activation data appears when viewing or downloading applicable
profiles.
- Activation files can be added, updated, preserved during label-only
edits, or removed during content replacement.
- Management declarations can coexist with supported configuration
declarations.

- **Validation**
- Added checks for declaration matching, supported profile types, file
limits, and Premium licensing.
- Clear errors are provided when activations are used with management
declarations or non-DDM profiles.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 15:29:52 +05:30
33b4efe9c1 Update install script and Fleet-maintained apps (#50499)
Automated ingestion of latest Fleet-maintained app data.

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

## Chores

* Updated numerous maintained application definitions with newer
releases, download links, version checks, and checksums across Windows
and macOS.
* Improved Windows installation reliability by recognizing successful
installations that require a restart.
* Corrected installer log-path handling for paths containing spaces.
* Refreshed metadata for applications including Firefox, Docker Desktop,
Discord, Tailscale, and many others.
* Adjusted Google Credential Provider validation settings to support its
installer distribution.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: allenhouchins <32207388+allenhouchins@users.noreply.github.com>
Co-authored-by: Allen Houchins <allenhouchins@mac.com>
2026-08-04 22:16:49 -05:00
Eric 85692f8238 Website: set historical event source (#50546)
Changes:
- Updated the website's createHistoricalEvent helper to accept an
eventSource input that is used to set the historical event source on
created records.
- Updated places where we create historical events to set a historical
event source
- Updated the accepted contact sources values in the receive-from-clay
webhook
- Updated the deliver-gitops-workshop-request action to log a warning
when a campaign member record cannot be created

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

- **Improvements**
- Improved activity tracking for newsletter subscriptions, signups,
contact forms, workshop requests, webinars, gated content, and page
views.
- Added clearer source details to records for more accurate attribution.
- Expanded support for website, webinar, event, LinkedIn, prospecting,
and GitHub activity sources.
- **Bug Fixes**
- Workshop requests now continue successfully if campaign updates
encounter an error.
- Corrected warning messages and preserved relevant submission details
for troubleshooting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-04 18:26:14 -05:00
Victor Lyuboslavsky a4af4d896c Add default fleet for new Windows MDM enrollments (#41787) (#49922)
Demo: https://www.youtube.com/watch?v=cWxZlu9WuwA
Guide updates: https://github.com/fleetdm/fleet/pull/49603/changes

IT admins can configure the fleet that hosts enrolling through
user-driven Windows MDM enrollment (Windows Autopilot, Entra join) are
automatically assigned to, via the Windows MDM settings page, the
mdm.windows_enrollment.default_fleet config setting, or GitOps.

- New windows_enrollment_config row stores the default team; the config
API surfaces it by fleet name and hydrates reads from the row so team
renames and deletions never serve a stale name. Deleting the fleet
clears the setting.
- New edited_windows_enrollment_default_fleet activity, emitted only
when the value changes.
- The OMA-DM session persists the device-reported SMBIOS serial on
still-unlinked enrollments, and orbit enrollment reverse-links by that
serial and assigns the default fleet before orbit's one-shot
setup-experience init, so the default fleet's software, scripts, and
profiles apply during the Autopilot ESP. The DevDetail and osquery link
paths keep the same assignment as fallbacks, and the EUA-token link path
now shares the same post-link bookkeeping.
- Hosts are only assigned when new to Fleet in this enrollment cycle:
existing hosts, including ones parked in Unassigned, keep their fleet on
re-enrollment, matching macOS ABM behavior.
- GitOps defers applying the setting until teams declared in the same
run are created, and fleetctl generate-gitops exports it.
- Windows MDM settings page redesign per Figma: programmatic enrollment
toggle, User driven enrollment section with the Entra-gated Default
fleet dropdown, and a Migration section.

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

# 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

## Database migrations

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

## 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 support for assigning a default Fleet Premium fleet to new
Windows MDM enrollments, including Autopilot and Entra join.
* Default-fleet settings can be configured, cleared, and managed through
Windows MDM settings and GitOps.
* Assigned fleet software, scripts, and profiles can apply during
out-of-box setup.
  * Added activity-feed visibility for default-fleet changes.
  * Improved Windows enrollment matching using hardware serial numbers.

* **Documentation**
  * Documented default-fleet assignment for Windows enrollment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-04 16:30:02 -05:00
Victor Lyuboslavsky bd601fff84 Fixed nilaway issues (#50405)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #50404 

- Refactored `ListHostSoftware` and `ModifyAppConfig` functions beeing
too big for nilaway
- Added a hard check to make sure all our funcitons/packages are being
analyzed by nilaway

# 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

* **Improvements**
* Improved software inventory filtering for self-service and macOS
applications, producing more accurate results.
* Improved application configuration updates so saved settings and
related system changes are processed more reliably.
* **Quality**
* Added automated checks to identify overly complex functions and help
maintain code quality.
* Updated static analysis tooling and expanded validation coverage with
new tests.
* **Documentation**
* Added a changelog entry describing the latest reliability and
maintainability improvements.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-04 15:41:18 -05:00
LeAnn c49d3d8191 Hide Self-service preview tabs in Edit appearance for Android apps (#50533)
<img width="890" height="562" alt="Screenshot 2026-08-04 at 12 57 28 PM"
src="https://github.com/user-attachments/assets/cb3a0817-13a8-483e-a5ad-d6c430c81f32"
/>

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

# 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

## Summary

Android apps are always self-service and installed from the Play Store
in the end user's work profile — there's no Fleet self-service web view
for them. The "Edit appearance" modal's Preview section still showed a
"Fleet" / "Self-service" tab pair with a browser-style self-service
preview for Android titles, which doesn't reflect what end users
actually see (#44791).

This PR removes the tab nav for Android software titles in
`EditIconModal` — the Preview section now renders just the Fleet card,
with no tabs and no Self-service preview.

## Test plan

- [x] `yarn test` for `EditIconModal.tests.tsx` (added a test asserting
no tabs/Self-service text render for an `android_apps` source, existing
test confirms tabs still render for non-Android)
- [x] Manually verified in a local dev instance: seeded an Android
software title, opened Actions > Edit appearance, confirmed Preview
renders the Fleet card directly with no tabs

(Recreated from #50530, which accidentally included unrelated commits
from a stale branch base.)

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

* **Bug Fixes**
* Removed the misleading Android Self-service preview from the Edit
appearance modal.
* Android app previews now show only the Fleet preview and Version view.
* Other software continues to display both Fleet and Self-service
preview options.
* **Tests**
* Added coverage to verify the correct preview tabs and version display
for Android apps.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-04 13:25:33 -07:00
Steven PalmesanoandRachelElysia 0c1e75ae8a Normalize tags (#48982)
---------

Co-authored-by: RachelElysia <71795832+RachelElysia@users.noreply.github.com>
2026-08-04 12:23:34 -07:00
Lucas Manuel Rodriguez 967d5e69b5 Add lucasmrod to orchestration understanding host vitals (#50492)
Adding myself to help review the changes to the Understanding Host
Vitals documentation (sometimes blocking PRs from being merged).

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

## Summary by CodeRabbit

* **Chores**
* Updated review ownership for the host vitals documentation to include
an additional required reviewer.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-04 16:10:27 -03:00
Sharon Katz a5199593fb Update community contributions process for AI-driven workflow (#50258) 2026-08-04 13:07:39 -05:00
George Karrandtest 1a1e76b012 adding watch for npm publish to release script (#50093)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added an option to resume release publishing after changelog
generation fails.
* Added registry verification to confirm package availability before
continuing publication.

* **Workflow Improvements**
* Release publishing now provides manual instructions for package login
and publishing.
* Supports checking package availability under the selected release tag.

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

Co-authored-by: test <test@test.com>
2026-08-04 13:05:25 -05:00
dependabot[bot] 49c0e80b77 Bump fast-uri from 3.1.4 to 3.1.5 in /tools/fleet-slackbot (#50505) 2026-08-04 13:04:16 -05:00
dependabot[bot] f9b9fefed1 Bump fast-uri from 3.1.4 to 3.1.5 (#50501) 2026-08-04 13:03:58 -05:00
dependabot[bot] 4e7cebf5ac Bump hono from 4.12.32 to 4.13.0 in /tools/fleet-slackbot (#50500) 2026-08-04 13:03:30 -05:00
Carlo DiCelico 5121bbd5df Merge branch '49419-patch-when-closed-ui' into feat/39962-patch-when-closed 2026-08-04 13:57:11 -04:00
Carlo DiCelico aec941a6c9 fix test-preview 2026-08-04 13:53:56 -04:00
Carlo 885540eed1 Patch when closed: frontend (#50437)
**Related issue:** Resolves #49419

Adds the UI for patching Fleet-maintained apps when the app is closed.
The patch toggle becomes a Deploy control with Force install and Patch
checkboxes. Checking Patch reveals a radio group: Patch when app is
closed, Force patch, or End user initiated. The control appears in the
Add software flow, a new Deploy modal, and the edit-policy page. The
change also adds skipped-install copy in the activity feed and install
details, a Self-service toggle for Fleet-maintained apps, and GitOps and
Premium gating.

The PR also includes backend changes that expose the patch policy's
continuous-automation state and a Fleet-maintained app's install query
in the API. The UI reads both to show the correct Deploy options, so
they ship in one PR.

## Testing

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


Eng QA walkthrough [part
1](https://drive.google.com/file/d/1Un-Z4QoTk2eXslQ_b8t95cE11QYq1SUt/view?usp=drive_link),
[part
2](https://drive.google.com/file/d/12_1Eh_RHOJ7RTjXBxFgas0VhKWvhLS0r/view?usp=drive_link)
2026-08-04 13:47:24 -04:00