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 -->
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 -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** N/A
## What this does
The `/query-generator` page's osquery-SQL-generation step
([get-llm-generated-sql.js](website/api/controllers/query-generator/get-llm-generated-sql.js))
was on `claude-sonnet-4-6`, which is now one generation behind. This PR:
- Bumps that call to `claude-sonnet-5`. The schema-filtration step stays
on `claude-haiku-4-5`, which is already the latest Haiku release, so no
change needed there.
- Adds `effort` support to the shared [`ai.prompt`
helper](website/api/helpers/ai/prompt.js), forwarded as
`output_config.effort` on Anthropic requests, and sets it to `"low"` for
the SQL-generation call. Effort controls how much the model deliberates
(and how many tokens/how much latency that costs). `"low"` was chosen
because the Haiku pre-filtering step already narrows the osquery schema
down to relevant tables, so the Sonnet step isn't starting from scratch
and doesn't need to spend much effort re-deriving that context.
- Bumps `max_tokens` in the Anthropic branch of the helper from 4096 to
8192. Claude Sonnet 5 turns on adaptive thinking by default when the
`thinking` param is omitted (which this helper does), and `max_tokens`
is a hard cap on *total* output including thinking tokens — at 4096
there was a real risk of thinking tokens eating into the budget and
truncating the JSON response the SQL step needs to return.
- **Fixes a pre-existing bug found while making the above changes:** the
`sqlReport` call passed the system prompt as a bare object-shorthand key
named `systemPromptForQueryGeneration`, but the `ai.prompt` helper's
declared input is `systemPrompt`. Sails silently drops unrecognized keys
passed to `.with(...)`, so the "Return ONLY a raw JSON object..." system
prompt was never actually reaching the model for this call. This has
been broken since the query generator was switched to Anthropic
(`f7c20c4731`); the sibling `filteredTables` call above it was
unaffected since it passes `systemPrompt` positionally. Now fixed to
`systemPrompt: systemPromptForQueryGeneration`.
## Why
Claude Sonnet 5 follows structured/constrained instructions (don't alias
tables, use `LIKE` with wildcards, only reference documented columns,
etc.) more literally than 4.6, which should make the generated SQL more
reliable. It's priced the same or cheaper than 4.6 during the current
introductory period.
## Trade-offs called out for review
- Thinking being on by default adds some latency versus the old
(thinking-off) behavior on 4.6. This call is not currently streamed
(`sails.helpers.http.post`, single blocking call over a socket), so any
added thinking time is invisible wait time for the user rather than a
visible "thinking" indicator. `effort: "low"` should keep this modest,
but worth confirming with a manual QA pass on a few representative
questions before merging.
- Only the SQL-generation call was migrated. The schema-filtration call
also runs on an Anthropic model, but Haiku 4.5 doesn't support
`output_config.effort` (added `effort` is a no-op if passed to it), so
it was left as-is.
# 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
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
## Testing
- [ ] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [ ] QA'd all new/changed functionality manually
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Improved AI-generated SQL responses with an updated language model.
* Added adaptive effort controls for supported AI requests.
* Increased response capacity to support more detailed generated
results.
* Improved handling of AI responses to provide more reliable results
when content includes different response formats.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Eric <eashaw@sailsjs.com>
Changes:
- updated the submit button on the "Talk to us" form ("Talk to an
engineer" » "Pick a time")
- Updated the GitHub webhook to add ~ga4-annotation labels to pull
requests that change the contact page
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Updated the contact form button label to “Pick a time” for clearer
scheduling intent.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the website to support two new usage statistics sent by Fleet
servers: `numHostsFleetMDMEnrolledWindows` and
`numHostsFleetMDMEnrolledMacOS`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Usage analytics now track Fleet MDM-enrolled host counts separately
for macOS and Windows.
* Historical usage records include these platform-specific enrollment
totals.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the contact source used for contacts created by the
deliver-webinar-access-request action (Webinar » Website - Gated video)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Webinar access requests are now categorized as “Website - Gated video”
in Salesforce.
- Updated contact and account records use the new source label
consistently.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Added a new landing page: /capex-savings
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a CapEx savings page available at `/capex-savings`.
* Added guidance on device refresh cycles, hardware performance, and
recommended replacement timing.
* Added a savings calculator for device cost, refresh cycle, and fleet
size, with estimated annual savings and assumptions.
* Added responsive layouts, imagery, calls to action, and
mobile-friendly calculator controls.
* Added supporting content on refresh recommendations, Fleet hardware
performance, and device lifecycle planning.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the contact source used for contacts created from workshop
requests
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Workshop requests are now correctly identified as “Website - Workshop
request” in CRM records, improving source tracking and reporting.
* Workshop request contacts are treated as form-based, ensuring the most
recent campaign member status is set to **Registered**.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated deliver-talk-to-us-form-submission to return a different
Salesforce user ID if territory information could not be found.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated the fallback “Talk to us” form submission contact-routing
behavior when territory information is unavailable or returns an
unexpected value, including changes to the default Calendly meeting link
and related warning messaging.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
https://github.com/fleetdm/confidential/issues/16947
Changes:
- Updated the get-territory-user-id helper to accept `website` and
`numberOfEmployees` inputs
- Updated the deliver-talk-to-us-form-submission action to send website
and number of employees to the get-territory-user-id helper, and updated
the `bookingUrlByUserId` dictionary.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved territory routing for “Talk to us” submissions by using
employee count, city, and website details.
* Updated routing logic to direct submissions to the appropriate
Calendly booking link.
* Preserved existing validation and error handling for incomplete or
unexpected territory lookup results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Issue
#50013
## Description
The Microsoft compliance proxy controller
(`website/api/controllers/microsoft-proxy/receive-redirect-from-microsoft.js`)
called `JSON.parse` on response bodies from Microsoft's Partner
Compliance and Graph APIs without checking for empty bodies or
unexpected response shapes. When Microsoft returned an unexpected
response — for example, a 2xx status with an empty body, which can
happen on partial-setup tenant states or when API permissions on the
enterprise app haven't been fully consented — the controller threw a raw
`SyntaxError: Unexpected end of JSON input` that surfaced verbatim in
the Fleet UI as the `setup_error` string, giving admins a Node.js stack
trace instead of a useful message.
Changes:
- Added explicit empty-body checks before `JSON.parse` at both
API-response parse sites, with a friendly `setup_error` message pointing
at the likely causes (partial setup / missing API permissions).
- On parse failure, expanded the diagnostic log to include response
status code, body length, and a 200-char body snippet so we can diagnose
future occurrences from server logs instead of asking admins to
reproduce.
- Added defensive checks on `parsedPoliciesResponse.value` and
`parsedGroupResponse.value` before indexing — previously
`parsedPoliciesResponse.value[0].Id` would throw `TypeError` if
Microsoft returned a well-formed response missing the expected shape.
**Note for reviewers:** The new `sails.log.warn` calls interpolate the
runtime tenant ID (`informationAboutThisTenant.entraTenantId`) — same
pattern as the existing log at line 209 that logs `fleetInstanceUrl`.
Heroku logs will contain tenant IDs when these error paths fire, which
is intentional so infra can grep by tenant when triaging. If we'd rather
rely on request-correlation IDs and keep tenant IDs out of logs, happy
to make that a follow-up.
## Screenrecording
## Testing
- [ ] Sanity-checked locally by inducing an empty response body
- [ ] Verified no changes to the happy-path flow
- [ ] Verified existing setup_error strings that the Fleet UI checks for
(admin-did-not-consent, missing-conditional-access-group) are unchanged
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved Microsoft integration setup handling when API responses are
empty, invalid, or missing expected data.
* Added clearer setup error messages for missing policies or the “Fleet
conditional access” group.
* Enhanced diagnostics to help identify response-related setup failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the quote shown on the contact page (and disabled the unused
personalization on the page)
- Removed the "What will you be using Fleet for" question on the "Talk
to us" form on the contact page
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Simplified the “Talk to us” form by removing the “What will you be
using Fleet for?” question.
* Added an organization employee-count field with required numeric
validation.
* Streamlined form prefilling and submission details for returning
users.
* Updated the testimonial section to display a consistent customer story
and logo.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes: https://github.com/fleetdm/fleet/issues/47653
Changes:
- Updated the contact page to only display the "Talk to us" form if a
user visits it with a `?talkToUs` query string.
- Updated all "Get a demo" buttons to go to `/contact?talkToUs`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a dedicated “Talk to us” contact experience.
* Updated “Get a demo,” “Talk to sales,” and “Talk to an engineer” links
across the site to open the appropriate contact form directly.
* **Bug Fixes**
* Improved contact form selection so the requested form displays
consistently across supported pages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the delete-android-device, get-android-device,
issue-command-on-android-device, and modify-android-device actions to
return a `deviceNotFound` response to Fleet servers when the Android
management API returns a 404 response.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Improved Android device management error handling.
- Device deletion, retrieval, command issuance, and modification now
clearly report when the requested device cannot be found.
- Prevents missing devices from being reported as generic errors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the error logged in `register-one-fleet-instance-using-vpp`
action when a Fleet license key cannot be verified to include the
error's message.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved error reporting when Fleet license verification fails,
providing more specific details to support troubleshooting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes: https://github.com/fleetdm/confidential/issues/16847
Changes:
- Added a new page, AI-powered IT (/ai)
- Added links to the new page to the homepage, /linux-management,
/infrastructure-as-code, /device-management, and
/visibility-and-reporting pages
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added an “AI-powered IT” page at `/ai`, including structured marketing
content, responsive hero imagery, and clear calls to action.
* Added an “AI-powered IT” entry to the Solutions navigation and updated
key page CTAs to link to `/ai`.
* **Style**
* Introduced and refined responsive `section-buttons`/button-group
layouts across multiple pages.
* Added dedicated styling for the new AI in IT page and adjusted related
feature-with-image spacing for better mobile presentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
Closes: https://github.com/fleetdm/fleet/issues/46496
Changes:
- Updated the website's custom hook to create a Google API auth client
and make it available at `sails.googleAuthClient`
- Updated Android proxy endpoints to use the shared Google API auth
client.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Optimized Google API authentication handling for Android management
features to improve system performance and reliability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Related issue:** Resolves#47699
## Testing
- [x] QA'd all new/changed functionality manually
## What & why
Entra conditional access is becoming available to self-hosted Fleet
Premium instances, which don't have the shared `MS-API-KEY` that
cloud-managed customers use. This makes the `microsoft-proxy/*`
endpoints reachable without that key by dropping the `is-cloud-customer`
policy gate (and the now-unused shared-secret config comments / policy
file).
A replacement auth mechanism for the proxy is tracked separately in
#47702.
> Split out of #49414 so the website change can ship independently.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Security / Access Control**
* Updated Microsoft proxy access handling to bypass the prior
cloud-customer check for matching requests.
* **Configuration**
* Removed unused cloud-customer compliance proxy shared-secret settings.
* **Bug Fixes**
* Improved compliance partner tenant creation by detecting existing
tenants using the provided Entra tenant ID and corrected the success
message text.
* **Data Model**
* Removed uniqueness enforcement for stored fleet instance URLs to
prevent avoidable conflicts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Eric <eashaw@sailsjs.com>
Changes:
- Updated the website's Android proxy's create-android-signup-url
endpoint to log a more detailed message if Google returns a 429 (rate
limit exceeded) response in the get-is-enterprise-managed-by-fleet
helper
Related to: https://github.com/fleetdm/fleet/issues/41908
Changes:
- Updated Android proxy endpoints (`create-android-enrollment-token`,
`create-enterprise-webapp`, `delete-android-device`,
`get-android-device`, `get-android-devices`,
`get-enterprise-applications`, `issue-command-on-android-device`,
`modify-android-device`, `modify-android-policies`, and
`modify-enterprise-app-policy`) to send requests to the Android
Management API without verifying that an enterprise is still managed by
Fleet with the getIsEnterpriseManagedByFleet helper, and to return a
`enterpriseNotAccessible` (notFound) response to Fleet servers if the
Android management API returns a 403 response.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved Android management flows to handle authorization failures
more consistently.
* Requests now return a clearer “not accessible” response when access to
an Android enterprise is denied.
* Several Android device, app, policy, and enterprise actions now
surface this response instead of falling back to generic errors.
* Streamlined Android enterprise operations by removing an extra
pre-check, letting the API response determine the final outcome.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated webhook sender classification to reflect the current list of
recognized bot and maintainer accounts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added support for contacts associated with the “Event - 2026-07 PSU
MacAdmins” source.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- Add the related story/sub-task/bug number, like Resolves#123, or
remove if NA -->
**Related issue:** NA (found via Aikido SAST triage)
## What changed
`GET /redirect-vanta-authorization-request` is a public, unauthenticated
endpoint that set signed cookies and then redirected the browser to the
caller-supplied `vantaAuthorizationRequestURL` with no validation.
Because the redirect target came straight from a query parameter, the
endpoint could be abused as an open redirect: an attacker could craft a
`https://fleetdm.com/redirect-vanta-authorization-request?...&vantaAuthorizationRequestURL=https://evil.example.com`
link that bounces a victim to an arbitrary domain (phishing). The only
prior gate was a `VantaConnection.findOne({vantaSourceId})` lookup,
which does not bind the source ID to the redirect target and is
satisfiable by anyone who has ever initiated a Vanta connection.
This adds a host/scheme allowlist before redirecting. The legitimate
destination is always `https://app.vanta.com/oauth/authorize?...`
(constructed server-side in `create-vanta-authorization-request.js`), so
the endpoint now only redirects when the parsed URL is `https:` and its
host is `app.vanta.com`; otherwise it returns `badRequest`.
# Checklist for submitter
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
## Testing
- [x] QA'd all new/changed functionality manually
Legitimate flow (redirect target `https://app.vanta.com/...`) still
redirects as before; a target on any other host or a non-`https` scheme
now returns `badRequest` instead of redirecting.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved safety for authorization redirects by validating the
destination before sending users onward.
* Redirects now only proceed when the target uses a secure connection
and the approved site.
* Invalid or malformed redirect links now return a clear bad-request
response instead of continuing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the "Test Fleet website" and "Deploy Fleet website" workflows
to include the full git history when checking out the repo.
- Updated the website's build-static-content script to use git to build
lastModifiedAt timestamps for Markdown and YAML files on the website.
- Updated the article template page and article category pages to show a
timestamp of when an article's Markdown file was last changed, if it was
updated >3 days after it was published.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Articles now conditionally display an **Updated** timestamp when they
were substantially modified after publication.
* The **Updated** indicator is shown on both article listing pages and
individual article pages (including mobile/desktop headers).
* **Bug Fixes**
* Timestamp rendering is now more consistent, helping readers
distinguish original publish dates from later edits.
* **Styling**
* Added styling to support the new “updated timestamp” label and
timestamp formatting within article cards.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Retires old success stories and redirects `/success-stories` to
`/customers`.
@eashaw, is there anything else / different that needs to be done to
retire these old pages? I suspect there will still be some article
category artifacts hanging around.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Updated story-related redirects so visitors are sent to the customers
page instead of older story URLs.
* Fixed deprecated device-management “fleet user story” links to land on
the customers page.
* Adjusted article page metadata and category resolution so the “success
stories” category no longer uses the previous titles/descriptions or
friendly-name mapping.
* **Chores**
* Updated static-content build rules for allowed category values and
adjusted how certain category URL prefixes are generated.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Eric <eashaw@sailsjs.com>
Closes: https://github.com/fleetdm/fleet/issues/48142
Changes:
- Added two new attributes to the website's platform record:
`workshopDetails`, an array containing formatted event details to be
used on the /workshops page, and `workshopDetailsLastUpdatedAt`, a JS
timestamp representing when workshop event details were last retrieved
from the EventBrite API
- Update the website's bootstrap configuration to create a platform
record
- Updated the view action for the workshops page to load workshop event
details from the database if they were updated less than two hours ago.
Changes:
- updated the URL for the /gitops-workshop page to be /workshops, and
added a redirect
- Updated the workshops page to render cards for "Apple administrator
workshop" events
- Updated the content and layout of the /workshops page to match the
latest wireframes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Launched a new **Workshops** page with a refreshed hero and
carousel-driven experience.
* Updated upcoming workshops to label event type (e.g., GitOps vs Apple
administrator) and display event details with correct links.
* **Bug Fixes**
* Updated routing so the new Workshops page is the primary destination.
* Kept the old workshop URL working by redirecting it to the new page
(and ensured the page remains accessible without needing to be signed
in).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Related to: https://github.com/fleetdm/fleet/issues/48052
Changes:
- Added a JSON `pageFaqForSeo` to the device management page's view
action
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added schema.org FAQ structured data to the device management page to
improve search visibility and enable richer search results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Changes
- Deleted 52 anonymous case study article files from the `articles/`
directory
- Removed all anonymous case study sections (financial services,
technology & SaaS, security/IT/healthcare/other) from
`handbook/marketing/fleet-social-proof.md`
- Removed 21 redirect entries from `website/config/routes.js` that
pointed to these removed case studies
The named customer stories (Stripe, Foursquare, Faire, Thumbtack,
Deputy, Fastly) and customer testimonials are preserved.
---
Built for [Irena
Reedy](https://fleetdm.slack.com/archives/D0APYC9R9SL/p1783033337222849?thread_ts=1775761161.561979&cid=D0APYC9R9SL)
by [Kilo for Slack](https://kilo.ai/slack)
---------
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Irena Reedy <irena@fleetdm.com>
Co-authored-by: Eric <eashaw@sailsjs.com>
Related to https://github.com/fleetdm/fleet/issues/48114
Related to https://github.com/fleetdm/fleet/issues/47386
Changes:
- Added a new exit to seven Android proxy endpoints `managementApiError`
that is used when the Android management API responds with a transient
5xx error (502, 503, and 504).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved handling of temporary Android Management API failures by
returning a dedicated, retry-friendly error outcome for transient 5xx
responses (502/503/504).
* Updated enrollment, web app creation, device deletion/modification,
command issuance, policy changes, and enterprise app policy updates to
surface clearer, more specific failure messages instead of generic
errors.
* Makes it easier to identify issues that may resolve on retry.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Related to: https://github.com/fleetdm/fleet/issues/48052
Changes:
- Added a JSON FAQ to the security and control pages header
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added FAQ structured data (JSON-LD) to the “Security and control” page
to enhance search engine understanding and visibility.
* The page layout now conditionally renders the FAQ JSON-LD script in
the document head when available.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated internal webhook handling configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- Adds a new testimonial quote from Ed Merrett (Director, Security &
TechOps @ Harmonic Security) to `handbook/company/testimonials.yml`
- Wires up the testimonial to appear at the end of the quote carousels
on both `/security-and-control` and `/visibility-and-reporting` pages
- Adds a placeholder profile image for the testimonial author
**Quote:** "We use Fleet Device Management. Basically, osquery is the
answer."
**Note:** The profile image
(`testimonial-author-ed-merrett-48x48@2x.png`) is a placeholder
transparent PNG. Replace with Ed Merrett's actual profile photo when
available.
---
Built for [Mike
McNeil](https://fleetdm.slack.com/archives/D0AFASLRHNU/p1781716393012429?thread_ts=1780459268.285059&cid=D0AFASLRHNU)
by [Kilo for Slack](https://kilo.ai/slack)
---------
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Mike McNeil <mikermcneil@users.noreply.github.com>
Co-authored-by: Eric <eashaw@sailsjs.com>
Changes:
- Added api/responses/notFound.js, an updated version of the notFound
response built into Sails that sets a `hideFooter` page local variable
to hide the website footer on the 404 page.
- Updated the styles and layout of the 404 page to match the latest
wireframes.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Completely redesigned the 404 error page with refreshed content and a
more modern layout.
* Added new visual styling, including animated interactive elements on
the 404 page.
* **Bug Fixes**
* Improved 404 response handling to consistently return the correct
status for JSON requests and render the 404 page when available.
* Ensures the 404 page can render cleanly even if view rendering fails,
and hides the footer for a cleaner error-page presentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the get-enriched helper to not use deleted locations returned
from Coresignal when including information about a company's
headquarters.
Changes:
- Added a new page: /security-and-control
- Added a link to the new page in the "Solutions" header dropdown menu
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## New Features
* Added a new "Security & control" page featuring security solutions
overview, product features including software inventory and autonomous
remediation capabilities, customer testimonials, and call-to-action
sections. The page is accessible via the updated website navigation
menu.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
Changes:
- Updated the get-territory-user-id helper to not require a country
input, but to throw an error if one is not provided. This is done to
replace the default usageError that is thrown by helpers with an error
that provides more information about the provided inputs
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Improved input validation error handling for territory lookups to
provide clearer error messages during runtime.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Changes:
- Updated the testimonials shown on the visibility and reporting page.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Updates**
* Modified the selection and order of testimonials displayed on the
Visibility and reporting page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Related to: https://github.com/fleetdm/fleet/issues/47391
Changes:
- Updated the receive-from-github webhook to log a warning and return a
200 response when a request to the GitHub GraphQL API to find issue
details fails.
Related to: https://github.com/fleetdm/confidential/issues/16303
Changes:
- Added a new Salesforce helper: getTerritoryUserId, a helper that
returns the ID of the Salesforce user associated with a provided
location (state, country, city)
- Updated the deliver-talk-to-us-form-submission action to send ICP
users to one of five different Calendly events based on their company's
headquarters location.
- Updated the get-enriched helper to include company headquarters
information when enriching a user.
Closes: https://github.com/fleetdm/fleet/issues/42891
Changes:
- Added support for two new usage statistics, `gitOpsModeEnabled` and
`gitOpsModeExceptions`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated analytics infrastructure to support expanded configuration
tracking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes: https://github.com/fleetdm/fleet/issues/46872
Changes:
- Updated the `productCategories` value of the testimonial from Adam
Pippert to show it on the /software-management page.
- Updated the order of testimonials on the homepage,
/software-management, /device-management, and /linux-management
Closes: https://github.com/fleetdm/fleet/issues/45687
Changes:
- Updated the orchestration page to be at /visibility-and-reporting, and
updated the content and layout to match the latest wireframes
- Added a redirect for /orchestration going to /visibility-and-reporting
- Removed unused images
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Launched redesigned "Visibility & Reporting" marketing page: new hero,
CTAs, feature sections, testimonials (including scrollable tweets), and
parallax background.
* Added site navigation entry for "Visibility & reporting" and redirect
from /orchestration to /visibility-and-reporting.
* **Style**
* New responsive heading styles and a dedicated page stylesheet for
improved layout, spacing, and mobile behavior.
* **Behavior**
* Testimonials payload simplified — personalization-driven headline
variations removed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes: https://github.com/fleetdm/confidential/issues/16057
Changes:
- Added `email-application-submitted`, an email template that is used to
reply to users who fill out the "Apply" form
- Updated the `deliver-application-submission` action to return an
`invalidEmailDomain` response if a user's email address is on the
bannedEmailDomainsForContactFormSubmissions list, and to send a "Thank
you for applying to Fleet" email to the user who submitted the form.
- Stubbed a new custom config variable: `applicationReplyEmailAddress`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Applicants receive a "Thanks for applying to Fleet" confirmation email
with a personalized greeting and ~7-day expectation.
* Added an application-submitted email template and preview using the
email layout.
* **Improvements**
* Added a hidden honeypot field to the application form; submissions
with it filled are silently discarded.
* Added email-domain validation with a specific form error and clearer
error rendering.
* Redirected jobs to the internal handbook open-positions section.
* **Chores**
* Added a commented placeholder for an application reply email setting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes: https://github.com/fleetdm/fleet/issues/45686
Changes:
- updated layout and content of the /device-management page to match the
latest positioning/wireframes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added testimonial block with scrollable tweets and responsive brand
logo grid
* Introduced new feature sections: patching, real-time compliance,
change management, transparency, and flexible deployment
* **Updates**
* Full redesign of the device management page: layout, typography,
spacing, responsive behavior, and testimonial/tweet styling
* Updated hero copy and primary CTA to “Talk to an engineer”
* **Removals**
* Removed desktop/mobile comparison table, legacy feature blocks, video
modal, and swag request form
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added support for website swag request contacts in webhook processing,
enabling the system to accept and validate requests from this new
contact source type.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->