diff --git a/.github/ISSUE_TEMPLATE/digital-experience-request.md b/.github/ISSUE_TEMPLATE/digital-experience-request.md
deleted file mode 100644
index 97b697ec8037..000000000000
--- a/.github/ISSUE_TEMPLATE/digital-experience-request.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-name: 🌐 Digital Experience request [FKA Website request]
-about: Propose a new feature or enhancement to fleetdm.com.
-title: 'TODO: '
-labels: '#g-digital-experience'
-assignees: ''
-
----
-
-## Goal
-
-| User story |
-|:---------------------------------------------------------------------------|
-| As a _________________________________________,
-| I want to _________________________________________
-| so that I can _________________________________________.
-
->For help creating a user story, see ["Writing a good user story"](https://fleetdm.com/handbook/company/development-groups#writing-a-good-user-story) in the website handbook.
-
-
-## How?
-
-- [ ] TODO
-
-### Context
-
-
-
diff --git a/.github/workflows/test-db-changes.yml b/.github/workflows/test-db-changes.yml
index 2bd89ab82b1e..10d1ec4ddea2 100644
--- a/.github/workflows/test-db-changes.yml
+++ b/.github/workflows/test-db-changes.yml
@@ -40,33 +40,6 @@ jobs:
with:
fetch-depth: 0
- - name: Install Go
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
- with:
- go-version-file: 'go.mod'
-
- - name: Start Infra Dependencies
- # Use & to background this
- run: docker compose up -d mysql_test &
-
- - name: Wait for mysql
- run: |
- echo "waiting for mysql..."
- until docker compose exec -T mysql_test sh -c "mysql -uroot -p\"\${MYSQL_ROOT_PASSWORD}\" -e \"SELECT 1=1\" fleet" &> /dev/null; do
- echo "."
- sleep 1
- done
- echo "mysql is ready"
-
- - name: Verify test schema changes
- run: |
- make dump-test-schema
- if [[ $(git diff server/datastore/mysql/schema.sql) ]]; then
- echo "❌ fail: uncommited changes in schema.sql"
- echo "please run `make dump-test-schema` and commit the changes"
- exit 1
- fi
-
# TODO: This doesn't cover all scenarios since other PRs might
# be merged into `main` after this check has passed.
#
@@ -84,8 +57,8 @@ jobs:
base_ref=$(git tag --list "fleet-v*" --sort=-creatordate | head -n 1)
fi
- all_migrations=($(ls server/datastore/mysql/migrations/tables/20*_*.go | sort -r))
- new_migrations=($(git diff --find-renames --name-only --diff-filter=A $base_ref -- server/datastore/mysql/migrations/tables/20\*_\*.go | sort -r))
+ all_migrations=($(ls server/datastore/mysql/migrations/tables/20*_*.go | sort -r | grep -v '_test.go'))
+ new_migrations=($(git diff --find-renames --name-only --diff-filter=A $base_ref -- server/datastore/mysql/migrations/tables/20\*_\*.go ':(exclude,glob)server/datastore/mysql/migrations/tables/20*_*_test.go' | sort -r))
index=0
for migration in "${new_migrations[@]}"; do
@@ -110,3 +83,31 @@ jobs:
echo "Ref: https://github.com/fleetdm/fleet/blob/main/handbook/engineering/scaling-fleet.md#foreign-keys-and-locking"
exit 1
fi
+
+
+ - name: Install Go
+ uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
+ with:
+ go-version-file: 'go.mod'
+
+ - name: Start Infra Dependencies
+ # Use & to background this
+ run: docker compose up -d mysql_test &
+
+ - name: Wait for mysql
+ run: |
+ echo "waiting for mysql..."
+ until docker compose exec -T mysql_test sh -c "mysql -uroot -p\"\${MYSQL_ROOT_PASSWORD}\" -e \"SELECT 1=1\" fleet" &> /dev/null; do
+ echo "."
+ sleep 1
+ done
+ echo "mysql is ready"
+
+ - name: Verify test schema changes
+ run: |
+ make dump-test-schema
+ if [[ $(git diff server/datastore/mysql/schema.sql) ]]; then
+ echo "❌ fail: uncommited changes in schema.sql"
+ echo "please run `make dump-test-schema` and commit the changes"
+ exit 1
+ fi
\ No newline at end of file
diff --git a/articles/exe-install-scripts.md b/articles/exe-install-scripts.md
new file mode 100644
index 000000000000..3ed2f437191b
--- /dev/null
+++ b/articles/exe-install-scripts.md
@@ -0,0 +1,334 @@
+# Windows EXE install scripts
+
+## What are EXE install scripts?
+
+EXE install scripts are a way to install software on Windows. EXE installers, such as `Figma-124.3.2.exe`, are self-contained packages with all the files and instructions needed to install software on a Windows device. EXE installers are fully customizable and do not follow the same installation process as MSI installers.
+
+For EXE installers, there is no unique script or command that will work for all installers. MSI installers are typically preferred over EXE installers because they provide a standardized installation process, easier silent deployment, and better integration with Windows Installer Service. If available, MSI installers offer more predictable results in enterprise environments.
+
+Some EXE installers and uninstallers require additional switches or flags to run silently. Common flags include `/S`, `/q`, `/quiet`, `/silent`, or `--silent`.
+
+## Device-scoped install scripts
+
+The recommended way to install software on Windows devices is to use device-scoped install scripts. These scripts install the software for all users on the device and run the installation process with administrator privileges.
+
+Fleet defaults to a device-scoped install script when you add software using an EXE installer.
+
+## User-scoped install scripts
+
+Some software can only be installed for a specific user. In this case, you can use user-scoped install scripts. The software is installed only for the user currently logged in, and the installation process is run with the user's privileges.
+
+### Example user-scoped install script
+
+The install script creates a scheduled task that will automatically be run as the current (logged-in) user. The EXE installer is copied to a public directory accessible by the user, ensuring that even non-administrator users can run the scheduled task to complete the installation. After the task finishes, the installer and the task are deleted.
+
+The use of scheduled tasks allows the installer to run with user-level permissions, which is especially useful when installing software for non-admin users without requiring administrator credentials at the time of execution.
+
+Since the installation is run by the current user, the script does not output the installer's messages to the console. If you need to see the output, you can modify the script to redirect it to a file and append it to the script output.
+
+```powershell
+# Some installers require a flag to run silently.
+# Each installer might use a different argument (usually it's "/S" or "/s")
+$installArgs = "/S"
+
+$exeFilePath = "${env:INSTALLER_PATH}"
+
+$exitCode = 0
+
+try {
+
+# Copy the installer to a public folder so that all can access it
+# users
+$exeFilename = Split-Path $exeFilePath -leaf
+Copy-Item -Path $exeFilePath -Destination "${env:PUBLIC}" -Force
+$exeFilePath = "${env:PUBLIC}\$exeFilename"
+
+# Task properties. The task will be started by the logged in user
+$action = New-ScheduledTaskAction -Execute "$exeFilePath" `
+ -Argument "$installArgs"
+$trigger = New-ScheduledTaskTrigger -AtLogOn
+$userName = Get-CimInstance -ClassName Win32_ComputerSystem |
+ Select-Object -expand UserName
+$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries
+
+# Create a task object with the properties defined above
+$task = New-ScheduledTask -Action $action -Trigger $trigger `
+ -Settings $settings
+
+# Register the task
+$taskName = "fleet-install-$exeFilename"
+Register-ScheduledTask "$taskName" -InputObject $task -User "$userName"
+
+# keep track of the start time to cancel if taking too long to start
+$startDate = Get-Date
+
+# Start the task now that it is ready
+Start-ScheduledTask -TaskName "$taskName" -TaskPath "\"
+
+# Wait for the task to be running
+$state = (Get-ScheduledTask -TaskName "$taskName").State
+Write-Host "ScheduledTask is '$state'"
+
+while ($state -ne "Running") {
+ Write-Host "ScheduledTask is '$state'. Waiting to run .exe..."
+
+ $endDate = Get-Date
+ $elapsedTime = New-Timespan -Start $startDate -End $endDate
+ if ($elapsedTime.TotalSeconds -gt 120) {
+ Throw "Timed-out waiting for scheduled task state."
+ }
+
+ Start-Sleep -Seconds 1
+ $state = (Get-ScheduledTask -TaskName "$taskName").State
+}
+
+# Wait for the task to be done
+$state = (Get-ScheduledTask -TaskName "$taskName").State
+while ($state -eq "Running") {
+ Write-Host "ScheduledTask is '$state'. Waiting for .exe to complete..."
+
+ $endDate = Get-Date
+ $elapsedTime = New-Timespan -Start $startDate -End $endDate
+ if ($elapsedTime.TotalSeconds -gt 120) {
+ Throw "Timed-out waiting for scheduled task state."
+ }
+
+ Start-Sleep -Seconds 10
+ $state = (Get-ScheduledTask -TaskName "$taskName").State
+}
+
+# Remove task
+Write-Host "Removing ScheduledTask: $taskName."
+Unregister-ScheduledTask -TaskName "$taskName" -Confirm:$false
+
+} catch {
+ Write-Host "Error: $_"
+ $exitCode = 1
+} finally {
+ # Remove installer
+ Remove-Item -Path $exeFilePath -Force
+}
+
+Exit $exitCode
+```
+
+### Example user-scoped uninstall script
+
+The uninstall script creates a scheduled task that will automatically be run as the current (logged-in) user. The uninstaller creates a separate PowerShell script for the user. After the task finishes, the script and the task are deleted.
+
+Since the uninstall script is run by the current user, it does not output its messages to the console. If you need to see the output, you can modify the main script to redirect it to a file and append it to the output.
+
+```powershell
+# Fleet extracts the name from the installer (EXE) and saves it to PACKAGE_ID
+# variable
+$softwareName = $PACKAGE_ID
+
+# Script to uninstall software as the current logged-in user.
+$userScript = @'
+$softwareName = $PACKAGE_ID
+
+# Using the exact software name here is recommended to avoid
+# uninstalling unintended software.
+$softwareNameLike = "*$softwareName*"
+
+# Some uninstallers require additional flags to run silently.
+# Each uninstaller might use a different argument (usually it's "/S" or "/s")
+$uninstallArgs = "/S"
+
+$uninstallCommand = ""
+$exitCode = 0
+
+try {
+
+$userKey = `
+ 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
+[array]$uninstallKeys = Get-ChildItem `
+ -Path @($userKey) `
+ -ErrorAction SilentlyContinue |
+ ForEach-Object { Get-ItemProperty $_.PSPath }
+
+$foundUninstaller = $false
+foreach ($key in $uninstallKeys) {
+ # If needed, add -notlike to the comparison to exclude certain similar
+ # software
+ if ($key.DisplayName -like $softwareNameLike) {
+ $foundUninstaller = $true
+ # Get the uninstall command. Some uninstallers do not include
+ # 'QuietUninstallString' and require a flag to run silently.
+ $uninstallCommand = if ($key.QuietUninstallString) {
+ $key.QuietUninstallString
+ } else {
+ $key.UninstallString
+ }
+
+ # The uninstall command may contain command and args, like:
+ # "C:\Program Files\Software\uninstall.exe" --uninstall --silent
+ # Split the command and args
+ $splitArgs = $uninstallCommand.Split('"')
+ if ($splitArgs.Length -gt 1) {
+ if ($splitArgs.Length -eq 3) {
+ $uninstallArgs = "$( $splitArgs[2] ) $uninstallArgs".Trim()
+ } elseif ($splitArgs.Length -gt 3) {
+ Throw `
+ "Uninstall command contains multiple quoted strings. " +
+ "Please update the uninstall script.`n" +
+ "Uninstall command: $uninstallCommand"
+ }
+ $uninstallCommand = $splitArgs[1]
+ }
+ Write-Host "Uninstall command: $uninstallCommand"
+ Write-Host "Uninstall args: $uninstallArgs"
+
+ $processOptions = @{
+ FilePath = $uninstallCommand
+ PassThru = $true
+ Wait = $true
+ }
+ if ($uninstallArgs -ne '') {
+ $processOptions.ArgumentList = "$uninstallArgs"
+ }
+
+ # Start the process and track the exit code
+ $process = Start-Process @processOptions
+ $exitCode = $process.ExitCode
+
+ # Prints the exit code
+ Write-Host "Uninstall exit code: $exitCode"
+ # Exit the loop once the software is found and uninstalled.
+ break
+ }
+}
+
+if (-not $foundUninstaller) {
+ Write-Host "Uninstaller for '$softwareName' not found."
+ $exitCode = 1
+}
+
+} catch {
+ Write-Host "Error: $_"
+ $exitCode = 1
+}
+
+Exit $exitCode
+'@
+
+$exitCode = 0
+
+# Create a script in a public folder so that it can be accessed by all users.
+$uninstallScriptPath = "${env:PUBLIC}/uninstall-$softwareName.ps1"
+$taskName = "fleet-uninstall-$softwareName"
+try {
+ Set-Content -Path $uninstallScriptPath -Value $userScript -Force
+
+ # Task properties. The task will be started by the logged in user
+ $action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
+ -Argument "$uninstallScriptPath"
+ $trigger = New-ScheduledTaskTrigger -AtLogOn
+ $userName = Get-CimInstance -ClassName Win32_ComputerSystem |
+ Select-Object -expand UserName
+ $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries
+
+ # Create a task object with the properties defined above
+ $task = New-ScheduledTask -Action $action -Trigger $trigger `
+ -Settings $settings
+
+ # Register the task
+ Register-ScheduledTask "$taskName" -InputObject $task -User "$userName"
+
+ # keep track of the start time to cancel if taking too long to start
+ $startDate = Get-Date
+
+ # Start the task now that it is ready
+ Start-ScheduledTask -TaskName "$taskName" -TaskPath "\"
+
+ # Wait for the task to be running
+ $state = (Get-ScheduledTask -TaskName "$taskName").State
+ Write-Host "ScheduledTask is '$state'"
+
+ while ($state -ne "Running") {
+ Write-Host "ScheduledTask is '$state'. Waiting to uninstall..."
+
+ $endDate = Get-Date
+ $elapsedTime = New-Timespan -Start $startDate -End $endDate
+ if ($elapsedTime.TotalSeconds -gt 120) {
+ Throw "Timed-out waiting for scheduled task state."
+ }
+
+ Start-Sleep -Seconds 1
+ $state = (Get-ScheduledTask -TaskName "$taskName").State
+ }
+
+ # Wait for the task to be done
+ $state = (Get-ScheduledTask -TaskName "$taskName").State
+ while ($state -eq "Running") {
+ Write-Host "ScheduledTask is '$state'. Waiting for .exe to complete..."
+
+ $endDate = Get-Date
+ $elapsedTime = New-Timespan -Start $startDate -End $endDate
+ if ($elapsedTime.TotalSeconds -gt 120) {
+ Throw "Timed-out waiting for scheduled task state."
+ }
+
+ Start-Sleep -Seconds 10
+ $state = (Get-ScheduledTask -TaskName "$taskName").State
+ }
+
+} catch {
+ Write-Host "Error: $_"
+ $exitCode = 1
+} finally {
+ # Remove task
+ Write-Host "Removing ScheduledTask: $taskName."
+ Unregister-ScheduledTask -TaskName "$taskName" -Confirm:$false
+
+ # Remove user script
+ Remove-Item -Path $uninstallScriptPath -Force
+}
+
+Exit $exitCode
+```
+
+## Install script for raw executables
+
+Raw executables without installers are less common but may be used in specific scenarios, such as when a vendor provides a standalone binary file for a lightweight application. In these cases, ensuring all necessary dependencies are in place is important. Additionally, consider cleaning up the source executable after installation to avoid leaving unnecessary files on the system. If you have a raw executable that does not come with an installer, you can use the following script to install it. This script copies the executable to Program Files, which are accessible by all users.
+
+```powershell
+$exeFilePath = "${env:INSTALLER_PATH}"
+
+try {
+
+# extract the name of the executable to use as the sub-directory name
+$exeName = [System.IO.Path]::GetFileName($exeFilePath)
+$subDir = [System.IO.Path]::GetFileNameWithoutExtension($exeFilePath)
+
+$destinationPath = Join-Path -Path $env:ProgramFiles -ChildPath $subDir
+
+# check if the directory does not exist, and create it if necessary
+if (-not (Test-Path -Path $destinationPath)) {
+ New-Item -ItemType Directory -Path $destinationPath
+}
+
+# copy the .exe file to the new sub-directory
+$destinationExePath = Join-Path -Path $destinationPath -ChildPath $exeName
+Copy-Item -Path $exeFilePath -Destination $destinationExePath
+Exit $LASTEXITCODE
+
+} catch {
+ Write-Host "Error: $_"
+ Exit 1
+}
+```
+## Conclusion
+
+EXE install scripts provide a flexible solution for installing software on Windows devices when MSI installers are unavailable. By leveraging the power of PowerShell and scheduled tasks, IT administrators can easily automate both device-scoped and user-scoped installations. Whether you're deploying software for all users on a device or targeting a specific logged-in user, the provided scripts offer a robust starting point for handling EXE installations.
+
+Always verify the EXE installer's specific flags for silent installation for smoother operations, ensure proper permissions are in place, and consider implementing logging for troubleshooting. While MSI installers are generally preferred for their standardized behavior, these scripts allow you to manage even the most customized EXE installs in enterprise environments.
+
+Following this guide will enable you to manage software deployments using EXE install scripts, improving efficiency and ensuring a seamless installation experience across your Windows devices.
+
+
+
+
+
+
+
diff --git a/articles/fleet-now-supports-ios-and-ipados-software-deployment-and-automated-patch-management.md b/articles/fleet-now-supports-ios-and-ipados-software-deployment-and-automated-patch-management.md
index 50ae4e241c48..4280852e116c 100644
--- a/articles/fleet-now-supports-ios-and-ipados-software-deployment-and-automated-patch-management.md
+++ b/articles/fleet-now-supports-ios-and-ipados-software-deployment-and-automated-patch-management.md
@@ -63,8 +63,9 @@ As Mike McNeil, Fleet’s CEO, says: *“Our vision is to empower teams to manag
To learn more about how Fleet can support your organization, visit [fleetdm.com/mdm](https://fleetdm.com/mdm).
-
+
+
diff --git a/articles/fleet-supports-macos-15-sequoia-ios-18-and-ipados-18.md b/articles/fleet-supports-macos-15-sequoia-ios-18-and-ipados-18.md
new file mode 100644
index 000000000000..afde4d97339e
--- /dev/null
+++ b/articles/fleet-supports-macos-15-sequoia-ios-18-and-ipados-18.md
@@ -0,0 +1,29 @@
+# Fleet supports Apple’s latest operating systems: macOS 15 Sequoia, iOS 18, and iPadOS 18
+
+![Fleet supports Apple’s latest operating systems: macOS 15 Sequoia, iOS 18, and iPadOS 18](../website/assets/images/articles/fleet-supports-macos-15-sequoia-ios-18-and-ipados-18-1600x900@2x.jpg)
+
+_Photo by [aditya bhatia](https://www.pexels.com/photo/people-walking-on-a-bridge-between-trees-13809734/)_
+
+Fleet is pleased to announce full support for Apple’s newest operating systems, including macOS 15 Sequoia, iOS 18, and iPadOS 18. With these updates, Fleet ensures seamless management and security capabilities for organizations adopting the latest Apple technology across their device fleet. This release enables IT administrators to confidently manage devices running these new operating systems, leveraging Fleet's robust tools for device monitoring, policy enforcement, and configuration management.
+
+## Noteworthy changes and known issues for macOS 15 Sequoia
+
+macOS 15 Sequoia brings significant changes that may impact device management workflows. Notably, firewall settings are no longer contained in a `.plist` file, resulting in potential reporting issues with osquery. Fleet is working with the osquery community to address this issue and update the `alf` table to correctly report firewall status under Sequoia. For more details on this issue, [follow the progress here](https://github.com/fleetdm/fleet/issues/21802). Additionally, manual installation of unsigned `fleet-osquery.pkg` packages now require extra steps due to changes in Apple's security settings, reflecting a heightened focus on device security.
+
+## Expanding Support for Declarative Device Management (DDM)
+
+As Apple expands the Declarative Device Management (DDM) capabilities with macOS 15 Sequoia, Fleet looks forward to implementing these new functionalities to enhance device management capabilities further. Today, administrators can send DDM JSON payloads directly to hosts, enabling more responsive and granular control over device configurations and settings. Fleet's support for DDM allows organizations to leverage this robust framework to manage devices efficiently without constant communication with the server. For more information on DDM, visit Apple’s [guide to Declarative Device Management](https://support.apple.com/guide/deployment/intro-to-declarative-device-management-depb1bab77f8/1/web/1.0).
+
+## Updates Across macOS, iOS, and iPadOS
+
+Apple has renamed "Profiles" to "Device Management" in all the new operating systems within System Settings. This change affects how administrators and users interact with device management settings on all Apple platforms. For more details on navigating these changes, visit Apple’s [support page](https://it-training.apple.com/tutorials/support/sup530/#Determining-Whether-a-Device-Is-Managed).
+
+Fleet remains committed to supporting Apple's latest advancements, ensuring that your organization can seamlessly integrate and manage devices running macOS 15 Sequoia, iOS 18, and iPadOS 18 with the same reliability and security you expect. Beginning with macOS 16, [Fleet will provide release-day support for major macOS releases](https://fleetdm.com/handbook/engineering#provide-0-day-support-for-major-version-macos-releases), ensuring your fleet is always prepared for the latest updates. Stay tuned for updates as we refine and enhance our support for these new platforms. [Engineering | Fleet handbook](https://fleetdm.com/handbook/engineering#provide-0-day-support-for-major-version-macos-releases)
+
+
+
+
+
+
+
+
diff --git a/articles/how-to-uninstall-fleetd.md b/articles/how-to-uninstall-fleetd.md
new file mode 100644
index 000000000000..1b7a524cd7d9
--- /dev/null
+++ b/articles/how-to-uninstall-fleetd.md
@@ -0,0 +1,34 @@
+# How to uninstall Fleet's agent (fleetd)
+
+This guide walks you through the steps to remove fleetd from your device. After performing these steps, the device will display as an offline host in the Fleet UI until you manually remove it.
+
+## On macOS:
+Run the [cleanup script](https://github.com/fleetdm/fleet/blob/main/orbit/tools/cleanup/cleanup_macos.sh) found in Fleet's GitHub
+
+---
+
+## On Windows:
+Use the "Add or remove programs" dialog to remove Fleet osquery.
+
+![windows_uninstall](https://github.com/user-attachments/assets/4140e62b-f67a-4df6-85b0-430c2c624881)
+
+---
+
+## On Linux:
+
+Using Debian package manager (Debian, Ubuntu, etc.) :
+
+Run ```sudo apt remove fleet-osquery -y```
+
+Using yum Package Manager (RHEL, CentOS, etc.) :
+
+Run ```sudo rpm -e fleet-osquery-X.Y.Z.x86_64```
+
+Are you having trouble uninstalling Fleetd on macOS, Windows, or Linux? Get help on Slack in the [#fleet channel](https://fleetdm.com/slack).
+
+
+
+
+
+
+
diff --git a/articles/how-to-uninstall-osquery.md b/articles/how-to-uninstall-osquery.md
deleted file mode 100644
index c5c54359ab47..000000000000
--- a/articles/how-to-uninstall-osquery.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# How to uninstall osquery
-
-This article walks you through the steps to remove osquery from your device. Remember that if you enrolled this device in a Fleet instance, it would display as an offline host in the Fleet UI until you manually remove it.
-
-## On macOS:
-Open up your terminal and paste the following commands; note that `sudo` is required, and you’ll need administrator privileges to complete this process.
-
-```
-sudo launchctl unload /Library/LaunchDaemons/io.osquery.agent.plist
-sudo rm /Library/LaunchDaemons/io.osquery.agent.plist
-sudo rm -rf /private/var/log/osquery /private/var/osquery
-sudo rm /usr/local/bin/osquery*
-sudo pkgutil --forget io.osquery.agent
-```
-
-These commands stop the running osquery daemon, remove it from your device, and delete the files created by osquery.
-
-And that’s it; you have now removed osquery from your macOS device.
-
----
-
-## On Windows:
-Removing osquery on Windows 10 is a simple process. To get started, open Windows settings and go to Apps. Then find “osquery” and click Uninstall.
-
-![Uninstall osquery](../website/assets/images/articles/how-to-uninstall-osquery-1-607x188@2x.png)
-
-Click Uninstall again to confirm, and osquery will be removed from your Windows device. You might need to restart your computer to complete the uninstall process fully.
-
----
-
-## On Linux:
-
-1. Open your terminal and paste the following commands to stop the running osquery service, uninstall osquery, and clean up files created by osquery.
-
-2. Note that `sudo` is required, and you’ll need administrative privileges to complete this process.
-
-3. Using Debian package manager (Debian, Ubuntu, etc.) :
-
-```
-sudo systemctl stop osqueryd.service
-sudo apt remove osquery
-rm -rf /var/osquery /var/log/osquery /etc/osquery
-```
-
-Using yum Package Manager (RHEL, CentOS, etc.) :
-
-```
-sudo systemctl stop osqueryd.service
-sudo yum remove osquery
-rm -rf /var/osquery /var/log/osquery /etc/osquery
-```
-
-Are you running into trouble uninstalling osquery on macOS, Windows, or Linux? Get help on Slack in the [#fleet channel](https://fleetdm.com/slack).
-
-
-
-
-
-
-
diff --git a/articles/macos-mdm-setup.md b/articles/macos-mdm-setup.md
index bc91ee6a7206..0f32ccb09033 100644
--- a/articles/macos-mdm-setup.md
+++ b/articles/macos-mdm-setup.md
@@ -25,8 +25,7 @@ To connect Fleet to ABM, you have to add an ABM token to Fleet. To add an ABM to
1. Navigate to the **Settings > Integrations > Mobile device management (MDM)** page.
2. Under "Automatic enrollment", click "Add ABM", and then click "Add ABM" again on the next page. Follow the instructions in the modal and upload an ABM token to Fleet.
-When one of your uploaded ABM tokens has expired or is within 30 days of expiring, you will see a warning
-banner at the top of page reminding you to renew your token.
+When one of your uploaded ABM tokens has expired or is within 30 days of expiring, you will see a warning banner at the top of page reminding you to renew your token.
To renew an ABM token:
@@ -53,7 +52,50 @@ If no default team is set for a host platform (macOS, iOS, or iPadOS), then newl
> A host can be transferred to a new (not default) team before it enrolls. In the Fleet UI, you can do this under **Settings** > **Teams**.
-### Simple Certificate Enrollment Protocol (SCEP)
+## Volume Purchasing Program (VPP)
+
+> Available in Fleet Premium
+
+To connect Fleet to Apple's VPP, head to the guide [here](https://fleetdm.com/guides/install-vpp-apps-on-macos-using-fleet).
+
+## Best practice
+
+Most organizations only need one ABM token and one VPP token to manage their macOS, iOS, and iPadOS hosts.
+
+These organizations may need multiple ABM and VPP tokens:
+
+- Managed Service Providers (MSPs)
+- Enterprises that acquire new businesses and as a result inherit new hosts
+- Umbrella organizations that preside over entities with separated purchasing authority (i.e. a hospital or university)
+
+For **MSPs**, the best practice is to have one ABM and VPP connection per client.
+
+The default teams in Fleet for each client's ABM token in Fleet will look like this:
+- macOS: 💻 Client A - Workstations
+- iOS: 📱🏢 Client A - Company-owned iPhones
+- iPadOS:🔳🏢 Client A - Company-owned iPads
+
+Client A's VPP token will be assigned to the above teams.
+
+For **enterprises that acquire**, the best practice is to add a new ABM and VPP connection for each acquisition.
+
+These will default teams in Fleet:
+
+Enterprise ABM token:
+- macOS: 💻 Enterprise - Workstations
+- iOS: 📱🏢 Enterprise - Company-owned iPhones
+- iPadOS:🔳🏢 Enterprise - Company-owned iPads
+
+The enterprises's VPP token will be assigned to the above teams.
+
+Acquisition ABM token:
+- macOS: 💻 Acquisition - Workstations
+- iOS: 📱🏢 Acquisition - Company-owned iPhones
+- iPadOS:🔳🏢 Acquisition - Company-owned iPads
+
+The acquisitions's VPP token will be assigned to the above teams.
+
+## Simple Certificate Enrollment Protocol (SCEP)
Fleet uses SCEP certificates (1 year expiry) to authenticate the requests hosts make to Fleet. Fleet renews each host's SCEP certificates automatically every 180 days.
diff --git a/articles/role-based-access.md b/articles/role-based-access.md
index 0b587e3d8c2a..d147796cdb58 100644
--- a/articles/role-based-access.md
+++ b/articles/role-based-access.md
@@ -48,7 +48,7 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines.
| View all software | ✅ | ✅ | ✅ | ✅ | |
| Add, edit, and delete software | | | ✅ | ✅ | ✅ |
| Download added software | | | ✅ | ✅ | |
-| Install software on hosts | | | ✅ | ✅ | |
+| Install/uninstall software on hosts | | | ✅ | ✅ | |
| Filter software by [vulnerabilities](https://fleetdm.com/docs/using-fleet/vulnerability-processing#vulnerability-processing) | ✅ | ✅ | ✅ | ✅ | |
| Filter hosts by software | ✅ | ✅ | ✅ | ✅ | |
| Filter software by team\* | ✅ | ✅ | ✅ | ✅ | |
@@ -130,7 +130,7 @@ Users with access to multiple teams can be assigned different roles for each tea
| View software | ✅ | ✅ | ✅ | ✅ | |
| Add and delete software | | | ✅ | ✅ | ✅ |
| Download added software | | | ✅ | ✅ | |
-| Install software on hosts | | | ✅ | ✅ | |
+| Install/uninstall software on hosts | | | ✅ | ✅ | |
| Filter software by [vulnerabilities](https://fleetdm.com/docs/using-fleet/vulnerability-processing#vulnerability-processing) | ✅ | ✅ | ✅ | ✅ | |
| Filter hosts by software | ✅ | ✅ | ✅ | ✅ | |
| Filter software | ✅ | ✅ | ✅ | ✅ | |
diff --git a/articles/sysadmin-diaries-gitops-a-strategic-advantage.md b/articles/sysadmin-diaries-gitops-a-strategic-advantage.md
new file mode 100644
index 000000000000..51d087a410df
--- /dev/null
+++ b/articles/sysadmin-diaries-gitops-a-strategic-advantage.md
@@ -0,0 +1,63 @@
+# Sysadmin diaries: GitOps: A strategic advantage for automation, collaboration, and cost savings
+
+![Sysadmin diaries: GitOps: A strategic advantage for automation, collaboration, and cost savings](../website/assets/images/articles/sysadmin-diaries-1600x900@2x.png)
+
+_This diary entry was originally published on [Allen's LinkedIn](https://www.linkedin.com/pulse/gitops-strategic-advantage-automation-collaboration-cost-houchins-a4luf/)._
+
+![GitHub logo and GitHub Actions logo](../website/assets/images/articles/sysadmin-diaries-gitops-a-strategic-advantage-1-312x207@2x.jpg)
+
+For many IT professionals, the idea of GitOps might seem daunting, if not completely foreign. I can relate to this. I’ve spent over two decades contributing at every level of IT, from individual contributor to executive leadership, and until recently, GitOps was something I had never implemented. It felt like a complex, high-barrier concept that no one adequately explained in terms I could quantify.
+
+As an IT leader, I often prioritized immediate business needs over initiatives that seemed more technical or abstract, especially those I didn’t fully understand. GitOps, at first glance, fell into that category. While the term GitOps might be newer, the principles behind it aren’t. Its roots lie in familiar DevOps and Engineering methodologies. GitOps has helped these groups become efficiency wizards orchestrating complex testing, builds, and deployments through centralized code repositories and automations.
+
+Imagine applying those same principles to your entire IT infrastructure and applications. GitOps is something you can approach gradually, finding small wins to build upon, even with the smallest steps. But before you invest any time, why should you care?
+
+GitOps is no longer just for DevOps teams. IT professionals, Information Security and compliance experts, people leaders, and Executives alike should consider it a cornerstone of our operations. It’s time to start thinking about GitOps capabilities as a critical factor in decision-making, whether you’re evaluating new tools or renewing existing ones.
+
+## Information technology
+
+According to *[Okta’s Businesses at Work 2024 report](https://www.okta.com/resources/whitepaper-businesses-at-work/)*, IT teams manage an average of 93 apps globally—some more, some fewer. That’s potentially 93 different systems to context-switch between, each with its own UI, change management process, and configuration quirks. To complicate matters, these systems aren’t usually managed by a single IT team. For instance, network systems might be handled by one group and productivity applications by another, while IT support often requires access across the board.
+
+GitOps changes that dynamic. By centralizing configuration management, GitOps offers full visibility, allowing every team to access the information they need to be more effective. Better yet, it standardizes how contributors interact with systems by using a common “code language,” empowering them to collaborate on areas they wouldn’t usually have administrator rights over. This is one of the most effective ways to break down silos and foster collaboration across traditionally separate groups.
+
+GitOps enables IT teams to unlock greater value through automation, allowing them to focus on more engaging, creative challenges that require human ingenuity—while leaving the repetitive, mundane tasks to the machines. For example, I want to ensure my end users’ devices are running the latest version of Google Chrome. Without GitOps, I’d need to manually monitor for updates and adjust compliance criteria whenever a new version is released.
+
+With GitOps, however, I can automate both the monitoring of Chrome updates and the adjustment of compliance criteria, creating a true “set it and forget it” workflow. This not only saves time but also ensures that compliance is maintained seamlessly, without manual intervention.
+
+![Screenshot of GitHub Actions workflow progress](../website/assets/images/articles/sysadmin-diaries-gitops-a-strategic-advantage-2-1999x680@2x.png)
+
+## Information security & compliance
+
+The best Information Security and Compliance teams aim to protect the company’s assets and customers’ data without negatively impacting user productivity or privacy. However, achieving this balance can be tricky, as security needs often conflict with user autonomy. These teams are also responsible for accessing corporate systems to verify and audit configurations, which can sometimes create friction.
+
+A GitOps-centric environment can help ease this tension by fostering a culture of trust and transparency. Instead of multiple touchpoints, both security teams and end users can access a centralized repository, a single source of truth, for all configuration data. This level of visibility streamlines audits and builds trust, ensuring that security doesn’t feel like “big brother” hovering over end users. It creates an environment where operational teams and users feel empowered, with clear, mutual access to critical information.
+
+![GitOps workflow diagram](../website/assets/images/articles/sysadmin-diaries-gitops-a-strategic-advantage-3-566x415@2x.png)
+
+Most systems offer little or no change management features. At best, they might say, “An admin made a change to this setting” and display what was updated. At worst, they might just say, “An admin made a change” without further details. Not only that, but information security and compliance teams don’t want to hunt for this data across various systems, which leads to the creation of centralized logging systems. These shortcomings also result in teams creating complex ticketing systems to propose, approve, and track changes, inevitably leading to the dreaded change management meeting—a time-consuming and often uninspiring process. They’re typically boring and take us away from more engaging, skill-appropriate tasks. However, With GitOps, every change across every system is tracked in one centralized location. This allows full visibility into each proposed change and its outcome and space for questions and comments. More importantly, anyone can propose changes or solutions, ensuring that the entire team feels involved and invested in decisions that impact them. GitOps doesn’t just streamline the process; it fosters collaboration and ownership in a way that traditional methods can’t.
+
+## Leadership & executives
+
+Let’s face it: you’re juggling competing priorities with constant pressure to increase efficiency and justify spending. While the pitch for GitOps sounds appealing, you’re a realist and know it will require an investment. It may not be strictly financial, but it will demand time and focus from your team. You’ll need to reprioritize commitments to ensure a meaningful return on the effort spent improving efficiency and meeting business demands. This is why GitOps should be introduced as a core strategy from the top down. It requires a shift in mindset and workflow, which might spark a cultural transformation within your organization.
+
+Beyond the tangible benefits, GitOps offers a host of unrealized gains that could have an even bigger impact on your business. Yes, it may be challenging at first, but you’ll be upskilling your team along the way. Learning something new is rarely easy, but support and investing in training will pay off. As your team implements greater automation, you’ll uncover opportunities to streamline processes and eliminate redundant systems, ultimately driving down costs. While licensing reductions are easy to quantify, it’s just as critical for leaders to communicate the story of time and efficiency savings.
+
+Perhaps most importantly, you’ll see a morale boost. Your teams will engage in more meaningful, stimulating work, and the skills they develop in one system will transfer across many others, multiplying their value to the business. This kind of transformation drives productivity and enables your team to become true force multipliers across the entire organization.
+
+## Where do you go from here?
+
+Some of you may already be well along your GitOps journey. If that’s the case, I encourage you to share your insights through conference presentations or by open-sourcing your solutions. By doing so, you can help others navigate similar challenges and showcase the real-world benefits of GitOps.
+
+For those yet to begin, [Fleet](https://fleetdm.com/) is a great place to start. Not only will you be setting up a system that provides comprehensive visibility and insights into all your devices, Fleet also provides an [easy-to-understand GitOps repository to help you get started](https://github.com/fleetdm/fleet-gitops).
+
+I hope this discussion has piqued your interest and given you the confidence to explore GitOps further. It should be at the top of your decision-making criteria during purchasing and renewal cycles for any software or systems you manage. For IT professionals, imagine becoming the hero of work automation and enhancing the services you provide to your customers. For InfoSec and compliance teams, picture gaining faster and deeper visibility into how devices in your environment are configured, whether on-prem or in the cloud, and having one location to run queries and enforce policies. For executives and leadership, envision a more engaged, motivated, and productive team that consistently helps you meet operational goals while driving down costs.
+
+Good luck on your GitOps journey, and don’t hesitate to [reach out if you have questions or want to learn more](https://fleetdm.com/support)!
+
+
+
+
+
+
+
+
diff --git a/changes/18354-update-success-messages b/changes/18354-update-success-messages
new file mode 100644
index 000000000000..98f582dad033
--- /dev/null
+++ b/changes/18354-update-success-messages
@@ -0,0 +1 @@
+* Update success messages for lock, unlock, and wipe commands in the UI.
diff --git a/changes/22159-hide-severity-fleet-free b/changes/22159-hide-severity-fleet-free
new file mode 100644
index 000000000000..ddb47088fa36
--- /dev/null
+++ b/changes/22159-hide-severity-fleet-free
@@ -0,0 +1 @@
+- Hide CVSS severity column from Fleet Free software details > vulnerabilities sections
diff --git a/changes/22197-policy-auto-software-truncation b/changes/22197-policy-auto-software-truncation
new file mode 100644
index 000000000000..4b4740622e6c
--- /dev/null
+++ b/changes/22197-policy-auto-software-truncation
@@ -0,0 +1 @@
+- Fleet UI: Fix policy automation truncation when selecting software to auto-install
\ No newline at end of file
diff --git a/changes/22207-close-team-modal b/changes/22207-close-team-modal
new file mode 100644
index 000000000000..cad918366754
--- /dev/null
+++ b/changes/22207-close-team-modal
@@ -0,0 +1 @@
+- Fix UI bug: Edit team name closes modal
diff --git a/changes/22415-fix-vpp-migration b/changes/22415-fix-vpp-migration
new file mode 100644
index 000000000000..eed21b93dc12
--- /dev/null
+++ b/changes/22415-fix-vpp-migration
@@ -0,0 +1 @@
+* Fixed an issue with the migration adding support for multiple VPP tokens that would happen if a token is removed prior to upgrading Fleet.
diff --git a/changes/22492-msrc-fix b/changes/22492-msrc-fix
new file mode 100644
index 000000000000..4bd6035faaed
--- /dev/null
+++ b/changes/22492-msrc-fix
@@ -0,0 +1 @@
+* Fix MSRC feed pulls (for NVD release builds) in environments where GitHub access is authenticated
diff --git a/cmd/msrc/generate.go b/cmd/msrc/generate.go
index 75909ac4fc27..9af759eb2a72 100644
--- a/cmd/msrc/generate.go
+++ b/cmd/msrc/generate.go
@@ -3,6 +3,7 @@ package main
import (
"context"
"encoding/json"
+ "errors"
"fmt"
"os"
"path/filepath"
@@ -34,13 +35,16 @@ func main() {
panicif(err)
now := time.Now()
- httpC := fleethttp.NewGithubClient()
ctx := context.Background()
- ghAPI := io.NewGitHubClient(httpC, github.NewClient(httpC).Repositories, wd)
- msrcAPI := msrc.NewMSRCClient(httpC, inPath, msrc.MSRCBaseURL)
- fmt.Println("Downloading existing bulletins...")
+ githubHttp := fleethttp.NewGithubClient()
+ ghAPI := io.NewGitHubClient(githubHttp, github.NewClient(githubHttp).Repositories, wd)
+
+ msrcHttp := fleethttp.NewClient() // don't reuse the GitHub client as it has an OAuth token baked in
+ msrcAPI := msrc.NewMSRCClient(msrcHttp, inPath, msrc.MSRCBaseURL)
+
+ fmt.Println("Downloading existing MSRC bulletins...")
eBulletins, err := ghAPI.MSRCBulletins(ctx)
panicif(err)
@@ -61,7 +65,16 @@ func main() {
panicif(err)
}
- fmt.Println("Done.")
+ fmt.Println("Done processing MSRC feed.")
+}
+
+// windowsBulletinGracePeriod returns whether we are within the grace period for a MSRC monthly feed to exist.
+//
+// E.g. September 2024 bulletin was released on the 2nd, thus we add some grace period (5 days)
+// for Microsoft to publish the current month bulletin.
+func windowsBulletinGracePeriod(month time.Month, year int) bool {
+ now := time.Now()
+ return month == now.Month() && year == now.Year() && now.Day() <= 5
}
func update(
@@ -72,15 +85,22 @@ func update(
ghClient io.GitHubAPI,
) ([]*parsed.SecurityBulletin, error) {
fmt.Println("Downloading current feed...")
- f, err := msrcClient.GetFeed(m, y)
+ currentFeed, err := msrcClient.GetFeed(m, y)
if err != nil {
- return nil, err
+ if errors.Is(err, msrc.FeedNotFound) && windowsBulletinGracePeriod(m, y) {
+ fmt.Printf("Current month feed %d-%d was not found, skipping...\n", y, m)
+ } else {
+ return nil, err
+ }
}
- fmt.Println("Parsing current feed...")
- nBulletins, err := msrc.ParseFeed(f)
- if err != nil {
- return nil, err
+ var nBulletins map[string]*parsed.SecurityBulletin
+ if currentFeed != "" {
+ fmt.Println("Parsing current feed...")
+ nBulletins, err = msrc.ParseFeed(currentFeed)
+ if err != nil {
+ return nil, err
+ }
}
var bulletins []*parsed.SecurityBulletin
@@ -118,6 +138,10 @@ func backfill(upToM time.Month, upToY int, client msrc.MSRCAPI) ([]*parsed.Secur
fmt.Printf("Downloading feed for %d-%d...\n", d.Year(), d.Month())
f, err := client.GetFeed(d.Month(), d.Year())
if err != nil {
+ if errors.Is(err, msrc.FeedNotFound) && windowsBulletinGracePeriod(d.Month(), d.Year()) {
+ fmt.Printf("Current month feed %d-%d was not found, skipping...\n", d.Year(), d.Month())
+ continue
+ }
return nil, err
}
diff --git a/docs/Contributing/Building-Fleet.md b/docs/Contributing/Building-Fleet.md
index 2ab34243a45a..368b68d23b46 100644
--- a/docs/Contributing/Building-Fleet.md
+++ b/docs/Contributing/Building-Fleet.md
@@ -38,7 +38,7 @@ sudo npm install -g yarn
# Install nvm to manage node versions (apt very out of date) https://github.com/nvm-sh/nvm#install--update-script
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
# refresh your session before continuing
-nvm install v19.7.0
+nvm install v20.11.1
```
#### Windows
@@ -149,7 +149,7 @@ The following assumes that you already installed [Docker](https://docs.docker.c
To set up a canonical development environment via Docker, run the following from the root of the repository:
```sh
-docker-compose up
+docker compose up
```
> Note: you can customize the DB Docker image via the environment variables FLEET_MYSQL_IMAGE and FLEET_MYSQL_PLATFORM. For example:
@@ -161,12 +161,12 @@ docker-compose up
If you'd like to shut down the virtual infrastructure created by Docker, run the following from the root of the repository:
```sh
-docker-compose down
+docker compose down
```
### Setting up the database tables
-Once you `docker-compose up` and are running the databases, you can build the code and run the following command to create the database tables:
+Once you `docker compose up` and are running the databases, you can build the code and run the following command to create the database tables:
```sh
./build/fleet prepare db --dev
diff --git a/docs/Get started/tutorials-and-guides.md b/docs/Get started/tutorials-and-guides.md
index f83de79f27db..aff2e5a6087c 100644
--- a/docs/Get started/tutorials-and-guides.md
+++ b/docs/Get started/tutorials-and-guides.md
@@ -6,7 +6,7 @@ A collection of guides to help you with Fleet.
- [How to install osquery and enroll Linux devices into Fleet](https://fleetdm.com/guides/how-to-install-osquery-and-enroll-linux-devices-into-fleet)
- [How to install osquery and enroll Windows devices into Fleet](https://fleetdm.com/guides/how-to-install-osquery-and-enroll-windows-devices-into-fleet)
- [Sysadmin diaries: restoring fleetd](https://fleetdm.com/guides/sysadmin-diaries-restoring-fleetd)
-- [How to uninstall osquery](https://fleetdm.com/guides/how-to-uninstall-osquery)
+- [How to uninstall Fleet's agent (fleetd)](https://fleetdm.com/guides/how-to-uninstall-fleetd)
- [Sysadmin diaries: device enrollment](https://fleetdm.com/guides/sysadmin-diaries-device-enrollment)
- [Sysadmin diaries: passcode profiles](https://fleetdm.com/guides/sysadmin-diaries-passcode-profiles)
- [Sysadmin diaries: lost device](https://fleetdm.com/guides/sysadmin-diaries-lost-device)
diff --git a/docs/Get started/why-fleet.md b/docs/Get started/why-fleet.md
index 0918248ac085..e0db75d68759 100644
--- a/docs/Get started/why-fleet.md
+++ b/docs/Get started/why-fleet.md
@@ -1,70 +1,26 @@
# Why Fleet
-## What's it for?
-
-In an industry that views security and IT as a shopping spree rather than a process, it's little wonder that IT and security teams get stuck with bolt-on solutions, misconfigured tools, and disparate workflows.
-
-Fleet helps organizations like Fastly and Gusto reimagine the "easy button."
-
-By simplifying how they do device health, FIM, HIDS, posture assessment, malware detection, vulnerability management, MDM, and the rest, Fleet's API enables teams with thousands of computers to build an IT and security program that works.
-
-### Explore data
-To see what kind of data you can use Fleet to gather, you can check out the [table reference documentation](https://fleetdm.com/tables).
-
-### Out-of-the-box policies
-Fleet includes out-of-the-box support for all [CIS benchmarks for macOS and Windows](https://fleetdm.com/pricing), as well as many [simpler queries](https://fleetdm.com/queries).
-
-Take as much or as little as you need for your organization.
-
-### Supported platforms
-Here are the platforms Fleet currently supports:
+Fleet is an open-source device management platform for Linux, macOS, Windows, Chromebooks, and iOS devices (BYOD or corporate owned.)
-- Linux (all distros)
-- macOS
-- Windows
-- Chromebooks
-- Amazon Web Services (AWS)
-- Google Cloud (GCP)
-- Azure (Microsoft cloud)
-- Data centers
-- Containers (kube, etc)
-- Linux-based IoT devices
-
-## Lighter than air
-Fleet is lightweight and modular. You can use it for security without using it for MDM, and vice versa. You can turn off features you are not using.
-
-### Open by design
-Fleet is dedicated to flexibility, accessibility, and clarity. We think [everyone can contribute](https://fleetdm.com/handbook/company#openness) and that tools should be as easy as possible for everyone to understand.
-
-### Good neighbors
-Ready-to-use, enterprise-friendly [integrations](https://fleetdm.com/integrations) exist for Snowflake, Splunk, GitHub Actions, Vanta, Elastic Jira, Zendesk, and more.
-
-Fleet plays well with Munki, Chef, Puppet, and Ansible, as well as with security tools like Crowdstrike and SentinelOne. For example, you can use the free version of Fleet to quickly report on what hosts are _actually_ running your EDR agent.
-
-
-### Free as in free
-The free version of Fleet will [always be free](https://fleetdm.com/pricing). Fleet is [independently backed](https://linkedin.com/company/fleetdm) and actively maintained with the help of many amazing [contributors](https://github.com/fleetdm/fleet/graphs/contributors).
+## What's it for?
-### Longevity
-The [company behind Fleet](https://fleetdm.com/handbook/company) is founded (and majority-owned) by [true believers in open source](https://fleetdm.com/handbook/company/why-this-way#why-open-source). The company's business model is influenced by GitLab (NYSE: GTLB), with great investors, happy customers, and the capacity to become profitable at any time.
+Managing computers today is getting harder. You have to juggle a mix of operating systems and devices, with a whole bunch of middleman vendors in between.
-In keeping with Fleet's value of openness, [Fleet Device Management's company handbook](https://fleetdm.com/handbook/company) is public and open source. You can read about the [history of Fleet and osquery](https://fleetdm.com/handbook/company#history) and our commitment to improving the product.
+Fleet makes things easier by giving you a single system to manage and secure all your computing devices. You can do MDM, patch stuff, and verify anything—all from one dashboard. It's like having a universal remote control for all your organization's computers.
-
+Fleet is open source, and free features will always be free.
## Is it any good?
-Fleet is used in production by IT and security teams with thousands of laptops and servers. Many deployments support tens of thousands of hosts, and a few large organizations manage deployments as large as 400,000+ hosts.
-## Chat
-Please join us in [MacAdmins Slack](https://www.macadmins.org/) or [osquery Slack](https://fleetdm.com/slack).
+Fleet is used in production by IT and security teams with thousands of laptops and servers. Many deployments support tens of thousands of hosts, and a few large organizations manage deployments as large as 400,000+ hosts.
-The Fleet community is full of [kind and helpful people](https://fleetdm.com/handbook/company#empathy). Whether or not you are a paying customer, if you need help, just ask.
+- **Get what you need:** Fleet lets you work directly with [data](https://fleetdm.com/integrations) and events from the native operating system. It lets you go all the way down to the bare metal. It’s also modular. (You can turn off features you are not using.)
+- **Out of the box:** Ready-to-use integrations exist for the [most common tools](https://fleetdm.com/integrations). You can also build custom workflows with the REST API, webhook events, and the fleetctl command line tool. Or go all in and manage computers [with GitOps](https://fleetdm.com/handbook/company#history).
+- **Good neighbors:** We think tools should be as easy as possible for everyone to understand. We helped [create osquery](https://fleetdm.com/handbook/company#history), and we are committed to improving it.
+- **Free as in free:** The free version of Fleet will [always be free](https://fleetdm.com/pricing). Fleet is independently backed and actively maintained with the help of many amazing contributors.
-
+## Ready to get started?
-## Questions?
-We have answers to the most [common questions](https://fleetdm.com/docs/get-started/faq).
+Deploying Fleet is easy. [Install it](https://fleetdm.com/docs/deploy/deploy-fleet) on a server, or [we can host it](https://fleetdm.com/register) for you. Enroll your devices, and you're set.
diff --git a/frontend/components/AddHostsModal/PlatformWrapper/PlatformWrapper.tsx b/frontend/components/AddHostsModal/PlatformWrapper/PlatformWrapper.tsx
index a2a8ccb1d1c3..7f520ae6440c 100644
--- a/frontend/components/AddHostsModal/PlatformWrapper/PlatformWrapper.tsx
+++ b/frontend/components/AddHostsModal/PlatformWrapper/PlatformWrapper.tsx
@@ -257,7 +257,7 @@ const PlatformWrapper = ({
Run this command with the{" "}
diff --git a/frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx b/frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx
index 1935b38b1133..8b5fec069426 100644
--- a/frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx
+++ b/frontend/pages/ManageControlsPage/Scripts/components/DeleteScriptModal/DeleteScriptModal.tsx
@@ -44,8 +44,8 @@ const DeleteScriptModal = ({