diff --git a/.github/workflows/deploy-fleet-website.yml b/.github/workflows/deploy-fleet-website.yml
index 0b5e657a0f..e88d8ebd3f 100644
--- a/.github/workflows/deploy-fleet-website.yml
+++ b/.github/workflows/deploy-fleet-website.yml
@@ -31,7 +31,7 @@ jobs:
strategy:
matrix:
- node-version: [14.x]
+ node-version: [16.x]
steps:
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v2
@@ -47,7 +47,7 @@ jobs:
# Set the Node.js version
- name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e # v1
+ uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
@@ -58,6 +58,9 @@ jobs:
with:
go-version: 1.19
+ # Download top-level dependencies and build Storybook in the website's assets/ folder
+ - run: npm install --legacy-peer-deps && npm run build-storybook -- -o ./website/assets/storybook --loglevel verbose
+
# Now start building!
# > …but first, get a little crazy for a sec and delete the top-level package.json file
# > i.e. the one used by the Fleet server. This is because require() in node will go
diff --git a/.github/workflows/test-website.yml b/.github/workflows/test-website.yml
index cf2470efdb..89e36b621a 100644
--- a/.github/workflows/test-website.yml
+++ b/.github/workflows/test-website.yml
@@ -8,6 +8,7 @@ on:
- 'handbook/**'
- 'schema/**'
- 'articles/**'
+ - '.github/workflows/test-website.yml'
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
@@ -28,17 +29,21 @@ jobs:
strategy:
matrix:
- node-version: [14.x]
+ node-version: [16.x]
steps:
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v2
# Set the Node.js version
- name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e # v1
+ uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
+
+ # Download top-level dependencies and build Storybook in the website's assets/ folder.
+ - run: npm install --legacy-peer-deps && npm run build-storybook -- -o ./website/assets/storybook --loglevel verbose
+
# Now start building!
# > …but first, get a little crazy for a sec and delete the top-level package.json file
# > i.e. the one used by the Fleet server. This is because require() in node will go
diff --git a/.goreleaser.yml b/.goreleaser.yml
index d44c472f20..e7cc4a6e47 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -59,9 +59,7 @@ archives:
- id: fleet
builds:
- fleet
- name_template: fleet_v{{.Version}}_{{.Os}}
- replacements:
- darwin: macos
+ name_template: fleet_v{{.Version}}_{{- if eq .Os "darwin" }}macos{{- else }}{{ .Os }}{{ end }}
format_overrides:
- goos: windows
format: zip
@@ -70,18 +68,14 @@ archives:
- id: fleetctl
builds:
- fleetctl
- name_template: fleetctl_v{{.Version}}_{{.Os}}
- replacements:
- darwin: macos
+ name_template: fleetctl_v{{.Version}}_{{- if eq .Os "darwin" }}macos{{- else }}{{ .Os }}{{ end }}
wrap_in_directory: true
- id: fleetctl-zip
builds:
- fleetctl
- name_template: fleetctl_v{{.Version}}_{{.Os}}
+ name_template: fleetctl_v{{.Version}}_{{- if eq .Os "darwin" }}macos{{- else }}{{ .Os }}{{ end }}
format: zip
- replacements:
- darwin: macos
wrap_in_directory: true
dockers:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 23d06b070c..a4834bfa4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,97 @@
+## Fleet 4.34.0 (Jul 11, 2023)
+
+* Added execution of programmatic Windows MDM enrollment on eligible devices when Windows MDM is enabled.
+
+* Microsoft MDM Enrollment Protocol: Added support for the RequestSecurityToken messages.
+
+* Microsoft MDM Enrollment Protocol: Added support for the DiscoveryRequest messages.
+
+* Microsoft MDM Enrollment Protocol: Added support for the GetPolicies messages.
+
+* Added `enabled_windows_mdm` and `disabled_windows_mdm` activities when a user turns on/off Windows MDM.
+
+* Added support to enable and configure Windows MDM and to notify devices that are able to programmatically enroll.
+
+* Added ability to turn Windows MDM on and off from the Fleet UI.
+
+* Added enable and disable Windows MDM activity UI.
+
+* Updated MDM detail query ingestion to switch MDM profiles from "verifying" or "verified" status to "failed" status when osquery reports that this profile is not installed on the host.
+
+* Added notification and execution of programmatic Windows MDM unenrollment on eligible devices when Windows MDM is disabled.
+
+* Added the `FLEET_DEV_MDM_ENABLED` environment variable to enable the Windows MDM feature during its development and beta period.
+
+* Added the `mdm_enabled` feature flag information to the response payload of the `PATCH /config` endpoint.
+
+* When creating a PolicySpec, return the proper HTTP status code if the team is not found.
+
+* Added CPEMatchingRule type, used for correcting false positives caused by incorrect entries in the NVD dataset.
+
+* Optimized macOS CIS query "Ensure Appropriate Permissions Are Enabled for System Wide Applications" (5.1.5).
+
+* Updated macOS CIS policies 5.1.6 and 5.1.7 to use a new fleetd table `find_cmd` instead of relying on the osquery `file` table to improve performance.
+
+* Implemented the privacy_preferences table for the Fleetd Chrome extension.
+
+* Warnings in fleetctl now go to stderr instead of stdout.
+
+* Updated UI for transferred hosts activity items.
+
+* Added Organization support URL input on the setting page organization info form.
+
+* Added improved ABM 400 error message to the UI.
+
+* Hide any osquery tables or columns from Fleet UI that has hidden set to true to match Fleet website.
+
+* Ignore casing in SAML response for display name. For example the display name attribute can be provided now as `displayname` or `displayName`.
+
+* Provide feedback to users when `fleetctl login` is using EMAIL and PASSWORD environment variables.
+
+* Added a new activity `transferred_hosts` created when hosts are transferred to a new team (or no team).
+
+* Added milliseconds to the timestamp of auto-generated team name when creating a new team in `GET /mdm/apple/profiles/match`.
+
+* Improved dashboard loading states.
+
+* Improved UI for selecting targets.
+
+* Made sure that all configuration profiles and commands are sent to devices if MDM is turned on, even if the device never turned off MDM.
+
+* Fixed bug when reading filevault key in osquery and created new Fleet osquery extension table to read the file directly rather than via filelines table.
+
+* Fixed UI bug on host details and device user pages that caused the software search to not work properly when searching by CVE.
+
+* Fixed not validating the schema used in the Metadata URL.
+
+* Fixed improper HTTP status code if SMTP is invalid.
+
+* Fixed false positives for iCloud on macOS.
+
+* Fixed styling of copy message when copying fields.
+
+* Fixed a bug where an empty file uploaded to `POST /api/latest/fleet/mdm/apple/setup/eula` resulted in a 500; now returns a 400 Bad Request.
+
+* Fixed vulnerability dropdown that was hiding if no vulnerabilities.
+
+* Fixed scroll behavior with disk encryption status.
+
+* Fixed empty software image in sandbox mode.
+
+* Fixed improper HTTP status code when `fleet/forgot_password` endpoint is rate limited.
+
+* Fixed MaxBurst limit parameter for `fleet/forgot_password` endpoint.
+
+* Fixed a bug where reading from the replica would not read recent writes when matching a set of MDM profiles to a team (the `GET /mdm/apple/profiles/match` endpoint).
+
+* Fixed an issue that displayed Nudge to macOS hosts if MDM was configured but MDM features weren't turned on for the host.
+
+* Fixed tooltip word wrapping on the error cell in the macOS settings table.
+
+* Fixed extraneous loading spinner rendering on the software page.
+
+* Fixed styling bug on setup caused by new font being much wider.
+
## Fleet 4.33.1 (Jun 20, 2023)
* Fixed ChromeOS add host instructions to use variable Fleet URL.
diff --git a/CODEOWNERS b/CODEOWNERS
index 5e00194c41..ff8a4141ad 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,95 +1,70 @@
-# Go engineers are automatically added as reviewers when changes are made to go
-# files or related backend files.
+##############################################################################################
+# ██████╗ ██████╗ ██████╗ ███████╗ ██████╗ ██╗ ██╗███╗ ██╗███████╗██████╗ ███████╗
+# ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔═══██╗██║ ██║████╗ ██║██╔════╝██╔══██╗██╔════╝
+# ██║ ██║ ██║██║ ██║█████╗ ██║ ██║██║ █╗ ██║██╔██╗ ██║█████╗ ██████╔╝███████╗
+# ██║ ██║ ██║██║ ██║██╔══╝ ██║ ██║██║███╗██║██║╚██╗██║██╔══╝ ██╔══██╗╚════██║
+# ╚██████╗╚██████╔╝██████╔╝███████╗╚██████╔╝╚███╔███╔╝██║ ╚████║███████╗██║ ██║███████║
+# ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝╚══════╝
+##############################################################################################
+# ⛔ This file indicates REQUIRED reviewers for changes to certain file paths in this repo.
+#
+# > How? This "requiredness" is provided natively by GitHub. If a team is specified, then
+# > the logic behaves slightly differently. See GitHub's latest documentation on CODEOWNERS
+# > for more information.
+#
+# ⚠️ For file paths not listed, the DRI is indicated elsewhere (website/config/custom.js).
+# (In either case, the DRI is automatically requested for review when changes are proposed.)
+#
+# ✅ Some paths also have multiple individuals who are allowed to make changes without review,
+# even though they are not the DRI. These are called "maintainers".
+#
+# For more information on how this works, see:
+# - What is a DRI and how is this configured? https://fleetdm.com/handbook/company/why-this-way#why-direct-responsibility
+# - Historical context: https://github.com/fleetdm/fleet/pull/12786
+##############################################################################################
+
+
+##############################################################################################
+# Golang files and other files related to the core product backend.
+# (1 or more Golang-literate engineers is required to review changes.)
+# FUTURE: Look for a way to not have this notify every single person in this "github team".
+##############################################################################################
*.go @fleetdm/go
go.sum @fleetdm/go
go.mod @fleetdm/go
/server/ @fleetdm/go
/cmd/ @fleetdm/go
-# Compliance
-/ee/cis/ @sharon-fdm @lucasmrod @marcosd4h @rachelElysia
-
-# MDM
-/ee/tools/puppet @roperzh @gillespi314 @mna @georgekarrv
-
-# React engineers are automatically added as reviewers when changes are made to react files
+##############################################################################################
+# React files and other files related to the core product frontend.
+# (1 or more React-literate engineers is required to review changes.)
+# FUTURE: Look for a way to not have this notify every single person in this "github team".
+##############################################################################################
/frontend/ @fleetdm/frontend
-# Infra/terraform
-*.tf @edwardsb @zwinnerman-fleetdm @rfairburn
-/infrastructure/ @zwinnerman-fleetdm @edwardsb @rfairburn
-/charts/ @zwinnerman-fleetdm @edwardsb @rfairburn
-/terraform @zwinnerman-fleetdm @edwardsb @rfairburn
+##############################################################################################
+# Config as code for infrastructure, internal security and IT use cases, and more.
+# (1 or more infra-literate engineers is required to review changes.)
+# FUTURE: Look for a way to not have this notify every single person in this "github team".
+##############################################################################################
+/infrastructure/ @fleetdm/infra
+/charts/ @fleetdm/infra
+/terraform/ @fleetdm/infra
-# GitHub issue templates
-/.github/ISSUE_TEMPLATE @mikermcneil
-
-# Codeowners file
-/CODEOWNERS @mikermcneil
-
-# Changelog
-/CHANGELOG.md @spokanemac
-
-# Fleet documentation (who is auto-requested as reviewer for changes to docs?)
+##############################################################################################
+# Key handbook pages w/ required reviewers
+#
+# (Especially useful for paths that tend to end up in PRs with lots of other reviewers)
+##############################################################################################
+/handbook/company/development-groups.md @mikermcneil
+/handbook/company/why-this-way.md @mikermcneil
+/handbook/company/README.md @mikermcneil
+/handbook/business-operations/README.md @mikermcneil
/docs/ @rachaelshaw
+/schema/ @rachaelshaw #« Data tables (osquery/fleetd schema) documentation
+CHANGELOG.md @lukeheath
-# REST API reference documentation
-/docs/Using-Fleet/REST-API.md @rachaelshaw
-/docs/Contributing/API-for-contributors.md @rachaelshaw
-# Standard query library YAML
-/docs/01-Using-Fleet/standard-query-library/standard-query-library.yml @zwass
-# Expanded table documentation
-/schema @eashaw
-
-# Articles
-/articles @jarodreyes
-
-# Website
-/website/ @eashaw
-/website/views/ @eashaw
-/website/assets/ @eashaw
-
-# Features table
-# - CEO is DRI for pricing
-# - Mo is DRI for features table
-# - Eric is DRI for website frontend code
-/website/views/pages/pricing.ejs @mikermcneil
-/handbook/product/pricing-features-table.yml @mikermcneil
-
-# Website redirects and URLs
-/website/config/routes.js @mikermcneil @eashaw
-
-# Website backend, scripts, deps
-/website/api/ @mikermcneil @eashaw
-/website/config/ @mikermcneil @eashaw
-/website/scripts/ @mikermcneil @eashaw
-/website/package.json @mikermcneil @eashaw
-
-# GitHub brandfront
-/README.md @mikermcneil
-
-# NPM brandfront (npmjs.com/package/fleetctl)
-/tools/fleetctl-npm/README.md @mikermcneil
-
-# Handbook
-/handbook/company @mikermcneil
-/handbook/company/* @mikermcneil
-/handbook/business-operations @mikermcneil
-/handbook/business-operations/* @mikermcneil
-/handbook/engineering @lukeheath
-/handbook/engineering/* @lukeheath
-/handbook/product @zhumo
-/handbook/product/* @zhumo
-/handbook/customers @alexmitchelliii
-/handbook/customers/* @alexmitchelliii
-/handbook/marketing @jarodreyes
-/handbook/marketing/* @jarodreyes
-/handbook/README.md @mikermcneil # « This is the "Table of contents"
-
-#
-# For configuration that determines auto-approval + auto-unfreezing, so that contributors
-# can merge their own PRs without additional approval, please see the latest version of:
-# https://github.com/fleetdm/fleet/blob/74f65447b718663bd04df31ea1da28915d98792c/website/config/custom.js#L88-L128
-#
+# ℹ️ But wait, there's more!
+# See the comments up top to learn where else DRIs and maintainers are configured.
diff --git a/README.md b/README.md
index 2f39ac6026..e6332f1ddd 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Open-source platform for IT and security teams with thousands of computers. Designed for APIs, GitOps, webhooks, YAML, and humans.
-
+
## What's it for?
@@ -56,7 +56,7 @@ In keeping with Fleet's value of openness, [Fleet Device Management's company ha
-## Is it any good?
+## 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.
diff --git a/articles/deploying-fleet-on-render.md b/articles/deploying-fleet-on-render.md
index 337ac5f2cf..ccbe413709 100644
--- a/articles/deploying-fleet-on-render.md
+++ b/articles/deploying-fleet-on-render.md
@@ -19,9 +19,13 @@ First let’s get these dependencies up and running on Render.
Fleet uses MySQL as the datastore to organize host enrollment and other metadata around serving Fleet. Start by forking [https://github.com/edwardsb/render-mysql](https://github.com/edwardsb/render-mysql), then create a new private service within Render. When prompted for the repository — enter your fork’s URL here.
-
+
*Private Service component in Render*
+Your private service should look like this:
+
+*Private Service settings in Render*
+
This private service will run MySQL, our database, so let’s give it a fitting name, something like “fleet-mysql”.
We’re also going to need to set up some environment variables and a disk to mount. Expand “Advanced” and enter the following:
@@ -39,6 +43,10 @@ We’re also going to need to set up some environment variables and a disk to mo
- Mount Path: `/var/lib/mysql`
- Size: `50GB`
+Once you've setup your mysql service on Render we will need to copy the address. You can find that here:
+
+*mysql address on Render*
+
---
## Redis
@@ -73,7 +81,7 @@ Give it the following environment variables:
Additionally we’ll configure the following so Render knows how to build our app and make sure its healthy:
-
+
- Health Check Path: `/healthz`
- Docker Build Context Directory: `.`
@@ -97,7 +105,9 @@ Fleet is up and running, head to your public URL.
You should be prompted with a setup page, where you can enter your name, email, and password. Run through those steps and you should have an empty hosts page waiting for you.
-You’ll find the enroll-secret after clicking “Add New Hosts”. This is a special secret the host will need to register to your Fleet instance. Once you have the enroll-secret you can use `fleetctl` to create Orbit installers, which makes installing and updating osquery super simple. [Download fleetctl](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.3.0) and try the following command (Docker require) on your terminal:
+You’ll find the enroll-secret after clicking “Add hosts”. This is a special secret the host will need to register to your Fleet instance. Once you have the enroll-secret you can use `fleetctl` to generate installers, which makes installing and updating osquery super simple.
+
+To install `fleetctl`, which is the command line interface (CLI) used to communicate between your computer and Fleet, you either run `npm install -g fleetctl` or [download fleetctl](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.3.0) from Github. Once it's installed try the following command (Docker require) on your terminal:
```
fleetctl package --type=msi --enroll-secret --fleet-url https://.onrender.com
diff --git a/articles/embracing-the-future-declarative-device-management.md b/articles/embracing-the-future-declarative-device-management.md
new file mode 100644
index 0000000000..134266ef1a
--- /dev/null
+++ b/articles/embracing-the-future-declarative-device-management.md
@@ -0,0 +1,65 @@
+# Embracing the future: Declarative Device Management
+
+
+
+As a Mac administrator, managing a fleet of Apple devices across your organization requires consistency and airtight security. With a variety of system services and background tasks to oversee, the challenge is not only to maintain uniform configurations but also to keep the organization's data secure. Recognizing these challenges, Apple has advanced a powerful new approach - Declarative Device Management (DDM).
+
+DDM is a paradigm shift in device management, enabling a more efficient and secure administration of macOS devices. It allows for tamper-resistant configurations and ensures simplified monitoring of system services and background tasks.
+
+In this blog post, we dive into Apple's forthcoming DDM in macOS Sonoma. Specifically, we'll explore how it will alter the way you manage system services, certificates and identities, and how it transitions you from traditional Mobile Device Management (MDM) systems. Whether you're an experienced Mac admin or just getting started, hopefully, this guide will provide some insights into DDM for you and your organization. Let's dive in!
+
+
+## Declarative device management for system services
+
+DDM paves the way for a secure and reliable mechanism to manage system services. Using tamper-resistant system configuration files for different system services ensures uniform and secure configurations across all devices. Declarative Device Management provides an added layer of protection against accidental changes by users.
+
+For instance, system services like sshd, sudo, PAM, CUPS, Apache httpd, bash and Z-shells will be able to adopt managed service configuration files to ensure consistency and compliance. The configuration files reference a data asset that provides a ZIP archive of SSH keys that is downloaded and expanded into a tamper-resistant, service-specific location when required conditions are met—for example, FileVault is enabled—and are always prioritized over any default or overridden system configuration.
+
+
+## Monitoring and compliance rules for background tasks
+
+DDM provides an excellent way of keeping track of background tasks. A new status item in this coming release reports the list of installed background tasks, making it easier to verify that required tasks are running and unwanted tasks aren't.
+
+In addition, the FileVault enabled state of the macOS boot volume is reported, allowing you to install sensitive configurations only when it is safe to proceed. With these features, you can ensure compliance and consistency across all macOS devices in your organization.
+
+
+## Secure access with certificates and identities
+
+Certificates and identities play a crucial role in ensuring secure access to organizational resources. In this context, DDM provides a more efficient mechanism for managing certificates and identities using its declaration data model.
+
+Certificates and identities are defined as asset declarations, which various configurations can reference. This eliminates the need for duplicating certificates and identities across multiple profiles, thereby reducing management overhead.
+
+
+## A new paradigm: software updates
+
+Apple's DDM introduces a redefined software update process, which marks another significant step forward in device management.
+
+Traditionally, administrators have faced considerable challenges in managing software updates. However, with DDM, this process has been dramatically simplified. The Declarative model handles scheduling and applying updates, allowing administrators to specify the desired state – for instance, maintaining the latest software version – and leave the rest to DDM.
+
+To improve upon this functionality, Fleet, with its osquery integration, allows admins to monitor the status of these updates in real time. It provides critical insights about the update process, such as software versions, pending updates, and the update history. These features make the software update process significantly more manageable and transparent.
+
+DDM represents an important advancement in how we manage and understand software updates. It not only will streamline administrative tasks but also elevates the overall security, performance, and integrity of the devices Mac admins manage.
+
+
+## Seamless transition from MDM to DDM
+
+Transitioning from traditional MDM to DDM will be a challenge. However, DDM provides a smooth transition without causing disruption or leaving a management gap. This is achieved by allowing DDM to take over the management of already installed MDM profiles without the need to remove them.
+
+
+## Fleet + osquery + DDM = 💗
+
+The innovations introduced with DDM, including the new software update process, represent a paradigm shift in device management. Fleet's MDM solution, powered by osquery, complements these changes and offers a GitOps-driven management platform for Mac admins.
+
+As we continue to navigate this evolving landscape, we have tools that equip us better than ever to handle the challenges and complexities of modern device management. This new era presents opportunities for enhanced security, control, and efficiency in managing our devices.
+
+Fleet is transforming how we manage and secure devices. Offering an open-core, cross-platform solution, Fleet is committed to empowering Mac admins with the tools they need to meet the challenges of today's and tomorrow's device management. Through its powerful and versatile platform, Fleet is illuminating the path forward in device management.
+
+
+
+
+
+
+
+
+
+
diff --git a/articles/fleet-4.34.0.md b/articles/fleet-4.34.0.md
new file mode 100644
index 0000000000..fdfd08f380
--- /dev/null
+++ b/articles/fleet-4.34.0.md
@@ -0,0 +1,134 @@
+# Fleet 4.34.0 | ChromeOS tables, CIS Benchmark load testing.
+
+
+
+Fleet 4.34.0 is live. Check out the full [changelog](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.33.0) or continue reading to get the highlights.
+For upgrade instructions, see our [upgrade guide](https://fleetdm.com/docs/deploying/upgrading-fleet) in the Fleet docs.
+
+## Highlights
+
+* Fleet adds support for ChromeOS
+* Boosted compliance with 'verified' status
+
+
+### Additional tables for ChromeOS
+
+In line with Fleet's value of 🟢 Results, we work relentlessly to enhance your experience. Our aim is to deliver results, focusing on pragmatic and meaningful improvements. With this in mind, we are delighted to introduce new ChromeOS-specific tables: screenlock, system_state, privacy_preferences, and disk_info. These additions not only represent our commitment to iterative progress but also our dedication to enhancing Fleet's utility for managing and understanding your ChromeOS devices better.
+
+
+### Load testing CIS Benchmarks for macOS
+
+Embodying Fleet's values of 🟠 Ownership and 🟢 Results, our team is always ready to tackle challenges head-on for the sake of delivering a reliable and high-performing product. Recently, we pondered the performance impact of running the comprehensive set of 100 CIS Benchmarks for macOS, known colloquially as "eating our own dogfood."
+
+Upon digging deeper, our engineers identified CIS queries 5.1.5, 5.1.6, and 5.1.7 as the three primary outliers in terms of CPU usage and memory footprint. These queries were found to be causing process terminations due to high resource usage.
+
+The queries, which are designed to verify appropriate permissions for system-wide applications (5.1.5) and ensure no world-writable files exist in the System Folder (5.1.6) or Library Folder (5.1.7), had to be refined for efficiency.
+
+With a clear focus on achieving results and owning the challenges we face, this rigorous load testing has led not only to the improvement of the 5.1.5, 5.1.6, and 5.1.7 queries but also to the development of additional tooling for future load testing. This is another stride in our continued effort to enhance Fleet and osquery's performance, reliability, and user experience.
+
+
+## More new features, improvements, and bug fixes
+
+* Added execution of programmatic Windows MDM enrollment on eligible devices when Windows MDM is enabled.
+
+* Microsoft MDM Enrollment Protocol: Added support for the RequestSecurityToken messages.
+
+* Microsoft MDM Enrollment Protocol: Added support for the DiscoveryRequest messages.
+
+* Microsoft MDM Enrollment Protocol: Added support for the GetPolicies messages.
+
+* Added `enabled_windows_mdm` and `disabled_windows_mdm` activities when a user turns on/off Windows MDM.
+
+* Added support to enable and configure Windows MDM and to notify devices that are able to programmatically enroll.
+
+* Added ability to turn Windows MDM on and off from the Fleet UI.
+
+* Added enable and disable Windows MDM activity UI.
+
+* Updated MDM detail query ingestion to switch MDM profiles from "verifying" or "verified" status to "failed" status when osquery reports that this profile is not installed on the host.
+
+* Added notification and execution of programmatic Windows MDM unenrollment on eligible devices when Windows MDM is disabled.
+
+* Added the `FLEET_DEV_MDM_ENABLED` environment variable to enable the Windows MDM feature during its development and beta period.
+
+* Added the `mdm_enabled` feature flag information to the response payload of the `PATCH /config` endpoint.
+
+* When creating a PolicySpec, return the proper HTTP status code if the team is not found.
+
+* Added CPEMatchingRule type, used for correcting false positives caused by incorrect entries in the NVD dataset.
+
+* Optimized macOS CIS query "Ensure Appropriate Permissions Are Enabled for System Wide Applications" (5.1.5).
+
+* Updated macOS CIS policies 5.1.6 and 5.1.7 to use a new fleetd table `find_cmd` instead of relying on the osquery `file` table to improve performance.
+
+* Implemented the privacy_preferences table for the Fleetd Chrome extension.
+
+* Warnings in fleetctl now go to stderr instead of stdout.
+
+* Updated UI for transferred hosts activity items.
+
+* Added Organization support URL input on the setting page organization info form.
+
+* Added improved ABM 400 error message to the UI.
+
+* Hide any osquery tables or columns from Fleet UI that has hidden set to true to match Fleet website.
+
+* Ignore casing in SAML response for display name. For example, the display name attribute can be provided now as `displayname` or `displayName`.
+
+* Provide feedback to users when `fleetctl login` is using EMAIL and PASSWORD environment variables.
+
+* Added a new activity `transferred_hosts` created when hosts are transferred to a new team (or no team).
+
+* Added milliseconds to the timestamp of the auto-generated team name when creating a new team in `GET /mdm/apple/profiles/match`.
+
+* Improved dashboard loading states.
+
+* Improved UI for selecting targets.
+
+* Made sure that all configuration profiles and commands are sent to devices if MDM is turned on, even if the device never turned off MDM.
+
+* Fixed bug when reading FileVault key in osquery and created new Fleet osquery extension table to read the file directly rather than via filelines table.
+
+* Fixed UI bug on host details and device user pages that caused the software search to not work properly when searching by CVE.
+
+* Fixed not validating the schema used in the Metadata URL.
+
+* Fixed improper HTTP status code if SMTP is invalid.
+
+* Fixed false positives for iCloud on macOS.
+
+* Fixed styling of copy message when copying fields.
+
+* Fixed a bug where an empty file uploaded to `POST /api/latest/fleet/mdm/apple/setup/eula` resulted in a 500; now returns a 400 Bad Request.
+
+* Fixed vulnerability dropdown that was hiding if no vulnerabilities.
+
+* Fixed scroll behavior with disk encryption status.
+
+* Fixed empty software image in sandbox mode.
+
+* Fixed improper HTTP status code when `fleet/forgot_password` endpoint is rate limited.
+
+* Fixed MaxBurst limit parameter for `fleet/forgot_password` endpoint.
+
+* Fixed a bug where reading from the replica would not read recent writes when matching a set of MDM profiles to a team (the `GET /mdm/apple/profiles/match` endpoint).
+
+* Fixed an issue that displayed Nudge to macOS hosts if MDM was configured but MDM features weren't turned on for the host.
+
+* Fixed tooltip word wrapping on the error cell in the macOS settings table.
+
+* Fixed extraneous loading spinner rendering on the software page.
+
+* Fixed styling bug on setup caused by new font being much wider.
+
+
+## Ready to upgrade?
+
+Visit our [Upgrade guide](https://fleetdm.com/docs/deploying/upgrading-fleet) in the Fleet docs for instructions on updating to Fleet 4.34.0.
+
+
+
+
+
+
+
diff --git a/articles/psu-macadmins-conference-2023.md b/articles/psu-macadmins-conference-2023.md
new file mode 100644
index 0000000000..b8fddd0687
--- /dev/null
+++ b/articles/psu-macadmins-conference-2023.md
@@ -0,0 +1,49 @@
+# Mac admins summer camp ⛺ at PSU MacAdmins Conference 2023
+
+[](https://mdoyvr.com/)
+
+Hello there, macOS admins! Let's talk about the upcoming PSU MacAdmins Conference 2023 (aka Summer Camp for Mac Admins). PSUMAC is July 18-21 at Penn State University. Hope to see you there.
+
+
+## What's on the agenda?
+
+PSU MacAdmins is not your typical conference. There are loads of technical sessions diving deep into various aspects of macOS administration. You can get your hands dirty with topics like:
+
+
+* system security—(think password management)
+* file encryption
+* network security
+* macOS deployment
+* configuration management
+* software delivery
+
+
+And that's not all. There are sessions on managing macOS systems better, where you can learn about user management, group policies, and troubleshooting. Plus, there's plenty of opportunity to explore the latest macOS tools and technologies—ever wanted to get the scoop on Device Management, Munki, or macOS Deployment? Well, now's your chance!
+
+One unique aspect I'm personally excited about is the _Hallway Track_. The hallway track, aka seeing fellow Mac Admins in passing between sessions 🤣, at meals, and at evening events, is a fantastic opportunity to interact with colleagues from different industries and skill levels. What better way to learn than through conversation and shared experiences, right?
+
+And it's not all work and no play. One of the dinners will be on Penn State's Building Business Meadow. I hear there will be various lawn games to play, but no lawn darts 🎯. Penn State's beautiful Arboretum is just across the street and will be open until dusk. Also, don't forget to stop by the [Berkey Creamery](https://creamery.psu.edu/) for a generous scoop of the highest butterfat ice cream 🍨 you will find (and, yes, you can have ice cream shipped home).
+
+
+## Presenter highlight
+
+I'm excited to say that I'll be sharing some of my experiences at Fleet and beyond in a session on Thursday, July 20, at 9:00 am. My talk, "[Cross-platform open-source monitoring and reporting](https://sched.co/1MmXv)", will focus on how combining Fleet and osquery can provide real-time data from endpoints and proactively trigger support tickets or notifications when a computer encounters issues. It's a topic close to my heart, and I'm eager to share what I've learned.
+
+Another must-see is Greg Neagle's talk at 10:45 am the same day, titled "[The Past, Present, and Future of Munki](https://sched.co/1OIYF)." If you don't know, Greg manages macOS devices at Walt Disney Animation Studios and is the primary developer of Munki. He'll be sharing some fantastic insights into Munki's development journey, its current standing, and where it's headed next. I'm told there'll even be an opportunity for attendees to contribute to Munki's future, so make sure not to miss it!
+
+
+## Come say hi to Fleet (and get some cool swag)
+
+Here at Fleet, we're super excited to be sponsoring this conference. Supporting the MacAdmin community is what we're all about. Not only are we sponsoring the conference, but we're also backing Greg's presentation. Don't forget to swing by our booth—we've got some fun stickers and swag you might like!
+
+In a nutshell, the [PSU MacAdmins Conference 2023](https://macadmins.psu.edu/) is shaping up to be an event packed with valuable insights and networking opportunities. I'm excited to see all of you there, and here's to learning and growing together in our macOS admin journey!
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/down-arrow.png b/assets/images/down-arrow.png
deleted file mode 100644
index 443ecdcdd1..0000000000
Binary files a/assets/images/down-arrow.png and /dev/null differ
diff --git a/assets/images/icon-accordion-collapse-black-16x16@2x.png b/assets/images/icon-accordion-collapse-black-16x16@2x.png
deleted file mode 100644
index d89ec4e652..0000000000
Binary files a/assets/images/icon-accordion-collapse-black-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-accordion-collapse-blue-16x16@2x.png b/assets/images/icon-accordion-collapse-blue-16x16@2x.png
deleted file mode 100644
index d89ec4e652..0000000000
Binary files a/assets/images/icon-accordion-collapse-blue-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-action-check-16x15@2x.png b/assets/images/icon-action-check-16x15@2x.png
deleted file mode 100644
index 3211203c47..0000000000
Binary files a/assets/images/icon-action-check-16x15@2x.png and /dev/null differ
diff --git a/assets/images/icon-action-disable-14x14@2x.png b/assets/images/icon-action-disable-14x14@2x.png
deleted file mode 100644
index aad0332243..0000000000
Binary files a/assets/images/icon-action-disable-14x14@2x.png and /dev/null differ
diff --git a/assets/images/icon-apple-black-24x24@2x.png b/assets/images/icon-apple-black-24x24@2x.png
deleted file mode 100644
index 50f389ab87..0000000000
Binary files a/assets/images/icon-apple-black-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-apple-vibrant-blue-24x24@2x.png b/assets/images/icon-apple-vibrant-blue-24x24@2x.png
deleted file mode 100644
index 4dd07cfd50..0000000000
Binary files a/assets/images/icon-apple-vibrant-blue-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-close-dark-blue-grey-16x16@2x.png b/assets/images/icon-close-dark-blue-grey-16x16@2x.png
deleted file mode 100644
index c45d9d9c28..0000000000
Binary files a/assets/images/icon-close-dark-blue-grey-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-close-fleet-purple-16x16@2x.png b/assets/images/icon-close-fleet-purple-16x16@2x.png
deleted file mode 100644
index 106ac9e468..0000000000
Binary files a/assets/images/icon-close-fleet-purple-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-collapse-blue-16x16@2x.png b/assets/images/icon-collapse-blue-16x16@2x.png
deleted file mode 100644
index d89ec4e652..0000000000
Binary files a/assets/images/icon-collapse-blue-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-darwin-fleet-black-16x16@2x.png b/assets/images/icon-darwin-fleet-black-16x16@2x.png
deleted file mode 100644
index 4e2c79585c..0000000000
Binary files a/assets/images/icon-darwin-fleet-black-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-issue-fleet-black-16x16@2x.png b/assets/images/icon-issue-fleet-black-16x16@2x.png
deleted file mode 100644
index 7cb03cfc43..0000000000
Binary files a/assets/images/icon-issue-fleet-black-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-low-disk-space-32x19@2x.png b/assets/images/icon-low-disk-space-32x19@2x.png
deleted file mode 100644
index 2328156453..0000000000
Binary files a/assets/images/icon-low-disk-space-32x19@2x.png and /dev/null differ
diff --git a/assets/images/icon-mac-48x48@2x.png b/assets/images/icon-mac-48x48@2x.png
deleted file mode 100644
index a27e2bd9e4..0000000000
Binary files a/assets/images/icon-mac-48x48@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-admin-white-24x24@2x.png b/assets/images/icon-main-admin-white-24x24@2x.png
deleted file mode 100644
index 88b87a717c..0000000000
Binary files a/assets/images/icon-main-admin-white-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-help-white-24x24@2x.png b/assets/images/icon-main-help-white-24x24@2x.png
deleted file mode 100644
index 6ea026223a..0000000000
Binary files a/assets/images/icon-main-help-white-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-hosts-white-24x24@2x.png b/assets/images/icon-main-hosts-white-24x24@2x.png
deleted file mode 100644
index 548f5d8135..0000000000
Binary files a/assets/images/icon-main-hosts-white-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-hosts@2x-16x16@2x.png b/assets/images/icon-main-hosts@2x-16x16@2x.png
deleted file mode 100644
index 915d4d80e0..0000000000
Binary files a/assets/images/icon-main-hosts@2x-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-logout-white-24x24@2x.png b/assets/images/icon-main-logout-white-24x24@2x.png
deleted file mode 100644
index 5880603c58..0000000000
Binary files a/assets/images/icon-main-logout-white-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-packs-white-24x24@2x.png b/assets/images/icon-main-packs-white-24x24@2x.png
deleted file mode 100644
index c4c8a4e1d9..0000000000
Binary files a/assets/images/icon-main-packs-white-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-packs@2x-16x16@2x.png b/assets/images/icon-main-packs@2x-16x16@2x.png
deleted file mode 100644
index c26515bd22..0000000000
Binary files a/assets/images/icon-main-packs@2x-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-policies-16x16@2x.png b/assets/images/icon-main-policies-16x16@2x.png
deleted file mode 100644
index 2ca393ed8f..0000000000
Binary files a/assets/images/icon-main-policies-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-queries@2x-16x16@2x.png b/assets/images/icon-main-queries@2x-16x16@2x.png
deleted file mode 100644
index 2a14097813..0000000000
Binary files a/assets/images/icon-main-queries@2x-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-main-query-white-24x24@2x.png b/assets/images/icon-main-query-white-24x24@2x.png
deleted file mode 100644
index b6def88877..0000000000
Binary files a/assets/images/icon-main-query-white-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-missing-hosts-28x24@2x.png b/assets/images/icon-missing-hosts-28x24@2x.png
deleted file mode 100644
index 08a60ad65c..0000000000
Binary files a/assets/images/icon-missing-hosts-28x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-plus-purple-32x32@2x.png b/assets/images/icon-plus-purple-32x32@2x.png
deleted file mode 100644
index 44997f7e83..0000000000
Binary files a/assets/images/icon-plus-purple-32x32@2x.png and /dev/null differ
diff --git a/assets/images/icon-search-fleet-black-16x16@2x.png b/assets/images/icon-search-fleet-black-16x16@2x.png
deleted file mode 100644
index 923a571e2e..0000000000
Binary files a/assets/images/icon-search-fleet-black-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-software-16x16@2x.png b/assets/images/icon-software-16x16@2x.png
deleted file mode 100644
index f731b0b910..0000000000
Binary files a/assets/images/icon-software-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-windows-48x48@2x.png b/assets/images/icon-windows-48x48@2x.png
deleted file mode 100644
index d325a309ff..0000000000
Binary files a/assets/images/icon-windows-48x48@2x.png and /dev/null differ
diff --git a/assets/images/icon-windows-black-24x24@2x.png b/assets/images/icon-windows-black-24x24@2x.png
deleted file mode 100644
index f0aa38c98f..0000000000
Binary files a/assets/images/icon-windows-black-24x24@2x.png and /dev/null differ
diff --git a/assets/images/icon-windows-fleet-black-16x16@2x.png b/assets/images/icon-windows-fleet-black-16x16@2x.png
deleted file mode 100644
index e3233d8a4c..0000000000
Binary files a/assets/images/icon-windows-fleet-black-16x16@2x.png and /dev/null differ
diff --git a/assets/images/icon-windows-vibrant-blue-24x24@2x.png b/assets/images/icon-windows-vibrant-blue-24x24@2x.png
deleted file mode 100644
index 5de3e9280f..0000000000
Binary files a/assets/images/icon-windows-vibrant-blue-24x24@2x.png and /dev/null differ
diff --git a/changes/10292-optimize-macos-cis-query-5.1.5 b/changes/10292-optimize-macos-cis-query-5.1.5
deleted file mode 100644
index 63ff07e47a..0000000000
--- a/changes/10292-optimize-macos-cis-query-5.1.5
+++ /dev/null
@@ -1 +0,0 @@
-* Optimize macOS CIS query "Ensure Appropriate Permissions Are Enabled for System Wide Applications" (5.1.5).
diff --git a/changes/11037-privacy_preferences-chromeos-table b/changes/11037-privacy_preferences-chromeos-table
deleted file mode 100644
index be1c659b88..0000000000
--- a/changes/11037-privacy_preferences-chromeos-table
+++ /dev/null
@@ -1 +0,0 @@
-* Implement the privacy_preferences table for the Fleetd Chrome extension
diff --git a/changes/11355-software-page-rendering-bugs b/changes/11355-software-page-rendering-bugs
deleted file mode 100644
index e0ee3a148c..0000000000
--- a/changes/11355-software-page-rendering-bugs
+++ /dev/null
@@ -1 +0,0 @@
-- Fix a bug where an extraneous loading spinner was rendered on the Software page.
diff --git a/changes/11655-hide-osquery-table-info b/changes/11655-hide-osquery-table-info
deleted file mode 100644
index abb6d9b3dc..0000000000
--- a/changes/11655-hide-osquery-table-info
+++ /dev/null
@@ -1 +0,0 @@
-- Hide any osquery tables or columns from Fleet UI that has hidden set to true to match Fleet website
diff --git a/changes/11927-vuln-false-positive-icloud b/changes/11927-vuln-false-positive-icloud
deleted file mode 100644
index 0ca4fcfd6b..0000000000
--- a/changes/11927-vuln-false-positive-icloud
+++ /dev/null
@@ -1,3 +0,0 @@
-- Added CPEMatchingRule type, used for correcting false positives caused by incorrect entries in the
- NVD dataset.
-- Fixed false positives for iCloud on macOS.
diff --git a/changes/12310-setup-styling b/changes/12310-setup-styling
deleted file mode 100644
index 4a17a3c5f3..0000000000
--- a/changes/12310-setup-styling
+++ /dev/null
@@ -1 +0,0 @@
-Fix styling bug on setup caused by new font being much wider
diff --git a/changes/12368-copy-message b/changes/12368-copy-message
deleted file mode 100644
index b2b7b17bfd..0000000000
--- a/changes/12368-copy-message
+++ /dev/null
@@ -1 +0,0 @@
-- Fix styling of copy message when copying fields
diff --git a/changes/12420-handle-policies-with-invalid-queries-desktop-endpoint b/changes/12420-handle-policies-with-invalid-queries-desktop-endpoint
new file mode 100644
index 0000000000..9385222293
--- /dev/null
+++ b/changes/12420-handle-policies-with-invalid-queries-desktop-endpoint
@@ -0,0 +1,2 @@
+- If a policy was defined with an invalid query, the desktop endpoint should count that policy as a
+ failed policy.
diff --git a/changes/12480-puppet-module-changes b/changes/12480-puppet-module-changes
new file mode 100644
index 0000000000..a9a7371b1a
--- /dev/null
+++ b/changes/12480-puppet-module-changes
@@ -0,0 +1 @@
+* Improve the reporting of the puppet module to only report as changed profiles that actually changed during a run.
diff --git a/changes/12481-profile-redelivery-v2 b/changes/12481-profile-redelivery-v2
new file mode 100644
index 0000000000..84612e93c9
--- /dev/null
+++ b/changes/12481-profile-redelivery-v2
@@ -0,0 +1 @@
+* Improved delivery of Apple MDM profiles by not re-sending `InstallProfile` commands if a host switches teams but the profile contents are the same.
diff --git a/changes/12532-puppet-module-team-assignment b/changes/12532-puppet-module-team-assignment
new file mode 100644
index 0000000000..c3cb0564a8
--- /dev/null
+++ b/changes/12532-puppet-module-team-assignment
@@ -0,0 +1 @@
+* Changed how team assignment works for the Puppet module, for more details see the [README](https://github.com/fleetdm/fleet/blob/main/ee/tools/puppet/fleetdm/README.md)
diff --git a/changes/12570-mask-webhook-url-logs b/changes/12570-mask-webhook-url-logs
new file mode 100644
index 0000000000..b86d5d399a
--- /dev/null
+++ b/changes/12570-mask-webhook-url-logs
@@ -0,0 +1 @@
+- Updated server logging for webhook requests to mask URL query values if the query param name includes "secret", "token", "key", "password".
diff --git a/changes/12582-nudge-mdm b/changes/12582-nudge-mdm
deleted file mode 100644
index 4656110d23..0000000000
--- a/changes/12582-nudge-mdm
+++ /dev/null
@@ -1 +0,0 @@
-* Fixed an issue that displayed Nudge to macOS hosts if MDM was configured but MDM features weren't turned on for the host
diff --git a/changes/12608-force-fv b/changes/12608-force-fv
new file mode 100644
index 0000000000..b0257ce47e
--- /dev/null
+++ b/changes/12608-force-fv
@@ -0,0 +1 @@
+* Set `DeferForceAtUserLoginMaxBypassAttempts` to `1` in the default FileVault profile installed by Fleet.
diff --git a/changes/bug-10720-ratelimits-should-return-proper-status-code b/changes/bug-10720-ratelimits-should-return-proper-status-code
deleted file mode 100644
index 0ecf815db1..0000000000
--- a/changes/bug-10720-ratelimits-should-return-proper-status-code
+++ /dev/null
@@ -1,3 +0,0 @@
-- If the `fleet/forgot_password` endpoint is rate limited it should return the proper HTTP status
- code.
-- Fixed MaxBurst limit parameter for `fleet/forgot_password` endpoint.
diff --git a/changes/bug-10867-output-warns-to-stdout b/changes/bug-10867-output-warns-to-stdout
deleted file mode 100644
index 5fc2bf7263..0000000000
--- a/changes/bug-10867-output-warns-to-stdout
+++ /dev/null
@@ -1 +0,0 @@
-- Warnings in fleetctl should go to stderr instead of stdout.
diff --git a/changes/bug-11636-vuln-dropdown b/changes/bug-11636-vuln-dropdown
deleted file mode 100644
index db1a094732..0000000000
--- a/changes/bug-11636-vuln-dropdown
+++ /dev/null
@@ -1 +0,0 @@
-- Fix vuln dropdown that was hiding if no vulnerabilities
diff --git a/changes/bug-11898-targets-selector-styling b/changes/bug-11898-targets-selector-styling
deleted file mode 100644
index 74d487378b..0000000000
--- a/changes/bug-11898-targets-selector-styling
+++ /dev/null
@@ -1 +0,0 @@
-Cleaner UI for selecting targets
diff --git a/changes/bug-12108-weird-scroll-behavior b/changes/bug-12108-weird-scroll-behavior
deleted file mode 100644
index 91817c5b9a..0000000000
--- a/changes/bug-12108-weird-scroll-behavior
+++ /dev/null
@@ -1 +0,0 @@
-- Fix funky scroll behavior with disk encryption status
diff --git a/changes/bug-12308-sandbox-software-image b/changes/bug-12308-sandbox-software-image
deleted file mode 100644
index b1ac9b07d1..0000000000
--- a/changes/bug-12308-sandbox-software-image
+++ /dev/null
@@ -1 +0,0 @@
-- Fix empty software image in sandbox mode
diff --git a/changes/bug-12332-dashboard-loading-state b/changes/bug-12332-dashboard-loading-state
deleted file mode 100644
index 526bdfbdb7..0000000000
--- a/changes/bug-12332-dashboard-loading-state
+++ /dev/null
@@ -1 +0,0 @@
-- Clean up dashboard loading states
diff --git a/changes/bug-12403-fix-post-eula-status-code b/changes/bug-12403-fix-post-eula-status-code
deleted file mode 100644
index 4f444e35ca..0000000000
--- a/changes/bug-12403-fix-post-eula-status-code
+++ /dev/null
@@ -1 +0,0 @@
-* Fixed a bug where an empty file uploaded to `POST /api/latest/fleet/mdm/apple/setup/eula` resulted in a 500, now returns a 400 Bad Request.
diff --git a/changes/bug-2642-fix-msrc-error b/changes/bug-2642-fix-msrc-error
deleted file mode 100644
index 6b0465cb4e..0000000000
--- a/changes/bug-2642-fix-msrc-error
+++ /dev/null
@@ -1 +0,0 @@
-- Don't use the MSRC scanner on non-windows OS.
diff --git a/changes/bug-2790-return-proper-status-code b/changes/bug-2790-return-proper-status-code
deleted file mode 100644
index 61c1aaa0be..0000000000
--- a/changes/bug-2790-return-proper-status-code
+++ /dev/null
@@ -1 +0,0 @@
-- When creating a PolicySpec, return the proper HTTP status code if the Team is not found.
\ No newline at end of file
diff --git a/changes/bug-2888-return-proper-status-code-if-smtp-invalid b/changes/bug-2888-return-proper-status-code-if-smtp-invalid
deleted file mode 100644
index 3e13217052..0000000000
--- a/changes/bug-2888-return-proper-status-code-if-smtp-invalid
+++ /dev/null
@@ -1 +0,0 @@
-- Return the proper HTTP status code if SMTP is invalid.
diff --git a/changes/bug-2888-validate-metadataurl b/changes/bug-2888-validate-metadataurl
deleted file mode 100644
index 2800f5931b..0000000000
--- a/changes/bug-2888-validate-metadataurl
+++ /dev/null
@@ -1 +0,0 @@
-- When setting up SSO, validate the scheme used in the Metadata URL
diff --git a/changes/bug-add-mdm-feature-flag-in-modify-appconfig b/changes/bug-add-mdm-feature-flag-in-modify-appconfig
deleted file mode 100644
index b9c1f6788e..0000000000
--- a/changes/bug-add-mdm-feature-flag-in-modify-appconfig
+++ /dev/null
@@ -1 +0,0 @@
-* Added the `mdm_enabled` feature flag information to the response payload of the `PATCH /config` endpoint.
diff --git a/changes/critical-bug-12743-observer+-run-new-query b/changes/critical-bug-12743-observer+-run-new-query
new file mode 100644
index 0000000000..d27222ccbf
--- /dev/null
+++ b/changes/critical-bug-12743-observer+-run-new-query
@@ -0,0 +1 @@
+- UI Fix: Observer + should be able to run any query by clicking create new query
diff --git a/changes/issue-11861-filevault-key b/changes/issue-11861-filevault-key
deleted file mode 100644
index 75adc53f85..0000000000
--- a/changes/issue-11861-filevault-key
+++ /dev/null
@@ -1,2 +0,0 @@
-- Fixed bug when reading filevault key in osquery and created new Fleet osquery
- extension table to read the file directly rather than via filelines table.
diff --git a/changes/issue-11932-improve-abm-400-error b/changes/issue-11932-improve-abm-400-error
deleted file mode 100644
index 3d6fc2a0cb..0000000000
--- a/changes/issue-11932-improve-abm-400-error
+++ /dev/null
@@ -1 +0,0 @@
-- add improved ABM 400 error message to the UI
diff --git a/changes/issue-11952-UI-for-windows-mdm-on-off b/changes/issue-11952-UI-for-windows-mdm-on-off
deleted file mode 100644
index 4a6eaa7f6e..0000000000
--- a/changes/issue-11952-UI-for-windows-mdm-on-off
+++ /dev/null
@@ -1 +0,0 @@
-- add ability to turn windows mdm on and off from the fleet UI
diff --git a/changes/issue-12053-dark-and-light-mode-logo b/changes/issue-12053-dark-and-light-mode-logo
new file mode 100644
index 0000000000..90074397fa
--- /dev/null
+++ b/changes/issue-12053-dark-and-light-mode-logo
@@ -0,0 +1 @@
+- add dark and light mode logo uploads and show the appropriate logo to the macOS mdm migration flow
diff --git a/changes/issue-12129-activity-transferred-hosts b/changes/issue-12129-activity-transferred-hosts
deleted file mode 100644
index 11c8197385..0000000000
--- a/changes/issue-12129-activity-transferred-hosts
+++ /dev/null
@@ -1 +0,0 @@
-* Added a new activity `transferred_hosts` created when hosts are transferred to a new team (or no team).
diff --git a/changes/issue-12168-update-macos-mdm-setup-uo b/changes/issue-12168-update-macos-mdm-setup-uo
new file mode 100644
index 0000000000..71f41c686c
--- /dev/null
+++ b/changes/issue-12168-update-macos-mdm-setup-uo
@@ -0,0 +1 @@
+- update macos mdm setup UI in fleet UI
diff --git a/changes/issue-12257-windows-mdm-feature-flag b/changes/issue-12257-windows-mdm-feature-flag
deleted file mode 100644
index 4c9f3d2392..0000000000
--- a/changes/issue-12257-windows-mdm-feature-flag
+++ /dev/null
@@ -1 +0,0 @@
-* Added the `FLEET_DEV_MDM_ENABLED` environment variable to enable the Windows MDM feature during its development and beta period.
diff --git a/changes/issue-12259-windows-mdm-settings b/changes/issue-12259-windows-mdm-settings
deleted file mode 100644
index ba95180f7e..0000000000
--- a/changes/issue-12259-windows-mdm-settings
+++ /dev/null
@@ -1 +0,0 @@
-* Added support to enable and configure Windows MDM and to notify devices that are able to programmatically enroll.
diff --git a/changes/issue-12260-trigger-windows-mdm-enrollment b/changes/issue-12260-trigger-windows-mdm-enrollment
deleted file mode 100644
index 771bed72e6..0000000000
--- a/changes/issue-12260-trigger-windows-mdm-enrollment
+++ /dev/null
@@ -1 +0,0 @@
-* Added execution of programmatic Windows MDM enrollment on eligible devices when Windows MDM is enabled.
diff --git a/changes/issue-12261-microsoft-mdm-discovery-endpoint b/changes/issue-12261-microsoft-mdm-discovery-endpoint
deleted file mode 100644
index 805a2e4907..0000000000
--- a/changes/issue-12261-microsoft-mdm-discovery-endpoint
+++ /dev/null
@@ -1 +0,0 @@
-* Microsoft MDM Enrollment Protocol: Added support for the DiscoveryRequest messages
diff --git a/changes/issue-12262-microsoft-mdm-policy-endpoint b/changes/issue-12262-microsoft-mdm-policy-endpoint
deleted file mode 100644
index 690d09b700..0000000000
--- a/changes/issue-12262-microsoft-mdm-policy-endpoint
+++ /dev/null
@@ -1 +0,0 @@
-* Microsoft MDM Enrollment Protocol: Added support for the GetPolicies messages
diff --git a/changes/issue-12263-microsoft-mdm-enroll-endpoint b/changes/issue-12263-microsoft-mdm-enroll-endpoint
deleted file mode 100644
index 06b1e2cb0b..0000000000
--- a/changes/issue-12263-microsoft-mdm-enroll-endpoint
+++ /dev/null
@@ -1 +0,0 @@
-* Microsoft MDM Enrollment Protocol: Added support for the RequestSecurityToken messages
diff --git a/changes/issue-12288-windows-mdm-activities b/changes/issue-12288-windows-mdm-activities
deleted file mode 100644
index 4b82ab8528..0000000000
--- a/changes/issue-12288-windows-mdm-activities
+++ /dev/null
@@ -1 +0,0 @@
-* Added `enabled_windows_mdm` and `disabled_windows_mdm` activities when a user turns on/off Windows MDM.
diff --git a/changes/issue-12289-add-enable-disable-windows-activtiy-UI b/changes/issue-12289-add-enable-disable-windows-activtiy-UI
deleted file mode 100644
index c270d96a9d..0000000000
--- a/changes/issue-12289-add-enable-disable-windows-activtiy-UI
+++ /dev/null
@@ -1 +0,0 @@
-- add enable and disable windows mdm activity UI
diff --git a/changes/issue-12297-ui-transferred-hosts-activity b/changes/issue-12297-ui-transferred-hosts-activity
deleted file mode 100644
index cbfcf1e25f..0000000000
--- a/changes/issue-12297-ui-transferred-hosts-activity
+++ /dev/null
@@ -1 +0,0 @@
-- Updated UI for transferred hosts activity items.
\ No newline at end of file
diff --git a/changes/issue-12330-mdm-verification-failed b/changes/issue-12330-mdm-verification-failed
deleted file mode 100644
index afeba36053..0000000000
--- a/changes/issue-12330-mdm-verification-failed
+++ /dev/null
@@ -1,2 +0,0 @@
-- Updated MDM detail query ingestion to switch MDM profiles from "verifying" or "verified"
- status to "failed" status when osquery reports that this profile is not installed on the host.
diff --git a/changes/issue-12342-trigger-windows-mdm-unenrollment b/changes/issue-12342-trigger-windows-mdm-unenrollment
deleted file mode 100644
index 78f4d9003f..0000000000
--- a/changes/issue-12342-trigger-windows-mdm-unenrollment
+++ /dev/null
@@ -1 +0,0 @@
-* Added notification and execution of programmatic Windows MDM unenrollment on eligible devices when Windows MDM is disabled.
diff --git a/changes/issue-12392-use-primary b/changes/issue-12392-use-primary
deleted file mode 100644
index 71a5c5e51a..0000000000
--- a/changes/issue-12392-use-primary
+++ /dev/null
@@ -1,2 +0,0 @@
-* Fixed a bug where reading from the replica would not read recent writes when matching a set of MDM profiles to a team (the `GET /mdm/apple/profiles/match` endpoint).
-* Added milliseconds to the timestamp of auto-generated team name when creating a new team in `GET /mdm/apple/profiles/match`.
diff --git a/changes/issue-12473-fix-tooltip-line-breaking-on-table-cell b/changes/issue-12473-fix-tooltip-line-breaking-on-table-cell
deleted file mode 100644
index 55781d4974..0000000000
--- a/changes/issue-12473-fix-tooltip-line-breaking-on-table-cell
+++ /dev/null
@@ -1 +0,0 @@
-- fix tooltip word wrapping on the error cell in the macOS settings table
diff --git a/changes/issue-12529-mdm-counts-off b/changes/issue-12529-mdm-counts-off
new file mode 100644
index 0000000000..7d8236f3a4
--- /dev/null
+++ b/changes/issue-12529-mdm-counts-off
@@ -0,0 +1 @@
+- Updated ingestion of host detail queries for MDM so hosts that report empty results are counted as "Off".
\ No newline at end of file
diff --git a/changes/issue-12568-add-org-support-url-input b/changes/issue-12568-add-org-support-url-input
deleted file mode 100644
index 586b727ab1..0000000000
--- a/changes/issue-12568-add-org-support-url-input
+++ /dev/null
@@ -1 +0,0 @@
-- add Organization support URL input on the setting page Organization info form.
diff --git a/changes/issue-12589-host-details-software-search b/changes/issue-12589-host-details-software-search
deleted file mode 100644
index fdbf0e75a2..0000000000
--- a/changes/issue-12589-host-details-software-search
+++ /dev/null
@@ -1,2 +0,0 @@
-- Fixed UI bug on host details and device user pages that caused the software search to not work
- properly when searching by CVE.
diff --git a/changes/issue-12600-windows-installer b/changes/issue-12600-windows-installer
new file mode 100644
index 0000000000..a5cb01d398
--- /dev/null
+++ b/changes/issue-12600-windows-installer
@@ -0,0 +1 @@
+* Add MSI installer deployement support through MS-MDM
diff --git a/changes/issue-12604-azure-tos-endpoint b/changes/issue-12604-azure-tos-endpoint
new file mode 100644
index 0000000000..11f6f7a41f
--- /dev/null
+++ b/changes/issue-12604-azure-tos-endpoint
@@ -0,0 +1 @@
+* Adding support for MDM TOS endpoint
diff --git a/changes/issue-12613-azure-jwt-support b/changes/issue-12613-azure-jwt-support
new file mode 100644
index 0000000000..75c117501c
--- /dev/null
+++ b/changes/issue-12613-azure-jwt-support
@@ -0,0 +1 @@
+* Adding support for Azure JWT tokens
diff --git a/changes/issue-12614-adding-support-for-sts-auth-endpoint b/changes/issue-12614-adding-support-for-sts-auth-endpoint
new file mode 100644
index 0000000000..fc8b751257
--- /dev/null
+++ b/changes/issue-12614-adding-support-for-sts-auth-endpoint
@@ -0,0 +1 @@
+* Adding support for Windows MDM STS Auth Endpoint
diff --git a/changes/mdm-turn-on b/changes/mdm-turn-on
deleted file mode 100644
index 0fae47d7a1..0000000000
--- a/changes/mdm-turn-on
+++ /dev/null
@@ -1 +0,0 @@
-* Make sure that all configuration profiles and commands are sent to devices if MDM is turned on, even if the device never turned off MDM.
diff --git a/changes/provide-feedback-fleetctl-login-when-using-env-vars b/changes/provide-feedback-fleetctl-login-when-using-env-vars
deleted file mode 100644
index bb46f22c69..0000000000
--- a/changes/provide-feedback-fleetctl-login-when-using-env-vars
+++ /dev/null
@@ -1 +0,0 @@
-* Provide feedback to users when `fleetctl login` is using EMAIL and PASSWORD environment variables.
diff --git a/changes/sso-display-name-case b/changes/sso-display-name-case
deleted file mode 100644
index 9df3502db9..0000000000
--- a/changes/sso-display-name-case
+++ /dev/null
@@ -1 +0,0 @@
-- Ignore casing in SAML response for display name. For example the display name attribute can be provided now as `displayname` or `displayName`.
diff --git a/changes/use-custom-table-for-macos-cis-5.1.6-and-5.1.7 b/changes/use-custom-table-for-macos-cis-5.1.6-and-5.1.7
deleted file mode 100644
index 8825608f96..0000000000
--- a/changes/use-custom-table-for-macos-cis-5.1.6-and-5.1.7
+++ /dev/null
@@ -1 +0,0 @@
-* For performance reasons, update macOS CIS policies 5.1.6 and 5.1.7 to use a new fleetd table `find_cmd` instead of relying on the osquery `file` table.
diff --git a/charts/fleet/Chart.yaml b/charts/fleet/Chart.yaml
index c9763a9fd8..f2bf04d399 100644
--- a/charts/fleet/Chart.yaml
+++ b/charts/fleet/Chart.yaml
@@ -8,4 +8,4 @@ version: v5.0.1
home: https://github.com/fleetdm/fleet
sources:
- https://github.com/fleetdm/fleet.git
-appVersion: v4.33.1
+appVersion: v4.34.0
diff --git a/charts/fleet/values.yaml b/charts/fleet/values.yaml
index acf07184f9..988330312e 100644
--- a/charts/fleet/values.yaml
+++ b/charts/fleet/values.yaml
@@ -2,7 +2,7 @@
# All settings related to how Fleet is deployed in Kubernetes
hostName: fleet.localhost
replicas: 3 # The number of Fleet instances to deploy
-imageTag: v4.33.1 # Version of Fleet to deploy
+imageTag: v4.34.0 # Version of Fleet to deploy
podAnnotations: {} # Additional annotations to add to the Fleet pod
serviceAccountAnnotations: {} # Additional annotations to add to the Fleet service account
resources:
diff --git a/cmd/fleetctl/apply_test.go b/cmd/fleetctl/apply_test.go
index cad7412781..c2175f87d6 100644
--- a/cmd/fleetctl/apply_test.go
+++ b/cmd/fleetctl/apply_test.go
@@ -128,7 +128,7 @@ func TestApplyTeamSpecs(t *testing.T) {
ds.TeamByNameFunc = func(ctx context.Context, name string) (*fleet.Team, error) {
team, ok := teamsByName[name]
if !ok {
- return nil, sql.ErrNoRows
+ return nil, ¬FoundError{}
}
return team, nil
}
@@ -1344,11 +1344,7 @@ func TestApplyMacosSetup(t *testing.T) {
ds.TeamByNameFunc = func(ctx context.Context, name string) (*fleet.Team, error) {
team, ok := teamsByName[name]
if !ok {
- // TeamByName in the real Datastore does not return notFoundError, it
- // returns ErrNoRows directly, we're a bit inconsistent with that at
- // the moment. This is important as ApplyTeamSpecs checks if TeamByName
- // returns an error that wraps ErrNoRows (and not an IsNotFound).
- return nil, sql.ErrNoRows
+ return nil, ¬FoundError{}
}
clone := *team
return &clone, nil
@@ -2052,7 +2048,7 @@ func TestApplySpecs(t *testing.T) {
ds.TeamByNameFunc = func(ctx context.Context, name string) (*fleet.Team, error) {
team, ok := teamsByName[name]
if !ok {
- return nil, sql.ErrNoRows
+ return nil, ¬FoundError{}
}
return team, nil
}
diff --git a/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json b/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json
index 2d61d42b26..e6ae712e28 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json
+++ b/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json
@@ -1,114 +1,115 @@
{
- "kind": "config",
- "apiVersion": "v1",
- "spec": {
- "org_info": {
- "org_name": "",
- "org_logo_url": "",
- "contact_url": "https://fleetdm.com/company/contact"
- },
- "server_settings": {
- "server_url": "",
- "live_query_disabled": false,
- "enable_analytics": false,
- "deferred_save_host": false
- },
- "smtp_settings": {
- "enable_smtp": false,
- "configured": false,
- "sender_address": "",
- "server": "",
- "port": 0,
- "authentication_type": "",
- "user_name": "",
- "password": "",
- "enable_ssl_tls": false,
- "authentication_method": "",
- "domain": "",
- "verify_ssl_certs": false,
- "enable_start_tls": false
- },
- "host_expiry_settings": {
- "host_expiry_enabled": false,
- "host_expiry_window": 0
- },
- "features": {
- "enable_host_users": true,
- "enable_software_inventory": false
- },
- "sso_settings": {
- "entity_id": "",
- "issuer_uri": "",
- "idp_image_url": "",
- "metadata": "",
- "metadata_url": "",
- "idp_name": "",
- "enable_jit_provisioning": false,
- "enable_jit_role_sync": false,
- "enable_sso": false,
- "enable_sso_idp_login": false
- },
- "fleet_desktop": {
- "transparency_url": "https://fleetdm.com/transparency"
- },
- "vulnerability_settings": {
- "databases_path": "/some/path"
- },
- "webhook_settings": {
- "host_status_webhook": {
- "enable_host_status_webhook": false,
- "destination_url": "",
- "host_percentage": 0,
- "days_count": 0
- },
- "failing_policies_webhook": {
- "enable_failing_policies_webhook": false,
- "destination_url": "",
- "policy_ids": null,
- "host_batch_size": 0
- },
- "vulnerabilities_webhook": {
- "enable_vulnerabilities_webhook": false,
- "destination_url": "",
- "host_batch_size": 0
- },
- "interval": "0s"
- },
- "integrations": {
- "jira": null,
- "zendesk": null
- },
- "mdm": {
- "apple_bm_terms_expired": false,
- "apple_bm_enabled_and_configured": false,
- "enabled_and_configured": false,
- "apple_bm_default_team": "",
- "windows_enabled_and_configured": false,
- "macos_updates": {
- "minimum_version": null,
- "deadline": null
- },
- "macos_migration": {
- "enable": false,
- "mode": "",
- "webhook_url": ""
- },
- "macos_settings": {
- "custom_settings": null,
- "enable_disk_encryption": false
- },
- "macos_setup": {
- "bootstrap_package": null,
- "enable_end_user_authentication": false,
- "macos_setup_assistant": null
- },
- "end_user_authentication": {
- "entity_id": "",
- "issuer_uri": "",
- "metadata": "",
- "metadata_url": "",
- "idp_name": ""
- }
- }
- }
+ "kind": "config",
+ "apiVersion": "v1",
+ "spec": {
+ "org_info": {
+ "org_name": "",
+ "org_logo_url": "",
+ "org_logo_url_light_background": "",
+ "contact_url": "https://fleetdm.com/company/contact"
+ },
+ "server_settings": {
+ "server_url": "",
+ "live_query_disabled": false,
+ "enable_analytics": false,
+ "deferred_save_host": false
+ },
+ "smtp_settings": {
+ "enable_smtp": false,
+ "configured": false,
+ "sender_address": "",
+ "server": "",
+ "port": 0,
+ "authentication_type": "",
+ "user_name": "",
+ "password": "",
+ "enable_ssl_tls": false,
+ "authentication_method": "",
+ "domain": "",
+ "verify_ssl_certs": false,
+ "enable_start_tls": false
+ },
+ "host_expiry_settings": {
+ "host_expiry_enabled": false,
+ "host_expiry_window": 0
+ },
+ "features": {
+ "enable_host_users": true,
+ "enable_software_inventory": false
+ },
+ "sso_settings": {
+ "entity_id": "",
+ "issuer_uri": "",
+ "idp_image_url": "",
+ "metadata": "",
+ "metadata_url": "",
+ "idp_name": "",
+ "enable_jit_provisioning": false,
+ "enable_jit_role_sync": false,
+ "enable_sso": false,
+ "enable_sso_idp_login": false
+ },
+ "fleet_desktop": {
+ "transparency_url": "https://fleetdm.com/transparency"
+ },
+ "vulnerability_settings": {
+ "databases_path": "/some/path"
+ },
+ "webhook_settings": {
+ "host_status_webhook": {
+ "enable_host_status_webhook": false,
+ "destination_url": "",
+ "host_percentage": 0,
+ "days_count": 0
+ },
+ "failing_policies_webhook": {
+ "enable_failing_policies_webhook": false,
+ "destination_url": "",
+ "policy_ids": null,
+ "host_batch_size": 0
+ },
+ "vulnerabilities_webhook": {
+ "enable_vulnerabilities_webhook": false,
+ "destination_url": "",
+ "host_batch_size": 0
+ },
+ "interval": "0s"
+ },
+ "integrations": {
+ "jira": null,
+ "zendesk": null
+ },
+ "mdm": {
+ "apple_bm_terms_expired": false,
+ "apple_bm_enabled_and_configured": false,
+ "enabled_and_configured": false,
+ "apple_bm_default_team": "",
+ "windows_enabled_and_configured": false,
+ "macos_updates": {
+ "minimum_version": null,
+ "deadline": null
+ },
+ "macos_migration": {
+ "enable": false,
+ "mode": "",
+ "webhook_url": ""
+ },
+ "macos_settings": {
+ "custom_settings": null,
+ "enable_disk_encryption": false
+ },
+ "macos_setup": {
+ "bootstrap_package": null,
+ "enable_end_user_authentication": false,
+ "macos_setup_assistant": null
+ },
+ "end_user_authentication": {
+ "entity_id": "",
+ "issuer_uri": "",
+ "metadata": "",
+ "metadata_url": "",
+ "idp_name": ""
+ }
+ }
+ }
}
diff --git a/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml b/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml
index 8db7811ede..1c0d778685 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml
+++ b/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml
@@ -41,6 +41,7 @@ spec:
entity_id: ""
org_info:
org_logo_url: ""
+ org_logo_url_light_background: ""
org_name: ""
contact_url: https://fleetdm.com/company/contact
server_settings:
diff --git a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json
index 6ff8616594..2030db5afe 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json
+++ b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json
@@ -1,176 +1,177 @@
{
- "kind": "config",
- "apiVersion": "v1",
- "spec": {
- "org_info": {
- "org_name": "",
- "org_logo_url": "",
- "contact_url": "https://fleetdm.com/company/contact"
- },
- "server_settings": {
- "server_url": "",
- "live_query_disabled": false,
- "enable_analytics": false,
- "deferred_save_host": false
- },
- "smtp_settings": {
- "enable_smtp": false,
- "configured": false,
- "sender_address": "",
- "server": "",
- "port": 0,
- "authentication_type": "",
- "user_name": "",
- "password": "",
- "enable_ssl_tls": false,
- "authentication_method": "",
- "domain": "",
- "verify_ssl_certs": false,
- "enable_start_tls": false
- },
- "host_expiry_settings": {
- "host_expiry_enabled": false,
- "host_expiry_window": 0
- },
- "features": {
- "enable_host_users": true,
- "enable_software_inventory": false
- },
- "mdm": {
- "apple_bm_default_team": "",
- "apple_bm_terms_expired": false,
- "apple_bm_enabled_and_configured": false,
- "enabled_and_configured": false,
- "windows_enabled_and_configured": false,
- "macos_updates": {
- "minimum_version": null,
- "deadline": null
- },
- "macos_migration": {
- "enable": false,
- "mode": "",
- "webhook_url": ""
- },
- "macos_settings": {
- "custom_settings": null,
- "enable_disk_encryption": false
- },
- "macos_setup": {
- "bootstrap_package": null,
- "enable_end_user_authentication": false,
- "macos_setup_assistant": null
- },
- "end_user_authentication": {
- "entity_id": "",
- "issuer_uri": "",
- "metadata": "",
- "metadata_url": "",
- "idp_name": ""
- }
- },
- "sso_settings": {
- "enable_jit_provisioning": false,
- "enable_jit_role_sync": false,
- "entity_id": "",
- "issuer_uri": "",
- "idp_image_url": "",
- "metadata": "",
- "metadata_url": "",
- "idp_name": "",
- "enable_sso": false,
- "enable_sso_idp_login": false
- },
- "fleet_desktop": {
- "transparency_url": "https://fleetdm.com/transparency"
- },
- "vulnerability_settings": {
- "databases_path": "/some/path"
- },
- "webhook_settings": {
- "host_status_webhook": {
- "enable_host_status_webhook": false,
- "destination_url": "",
- "host_percentage": 0,
- "days_count": 0
- },
- "failing_policies_webhook": {
- "enable_failing_policies_webhook": false,
- "destination_url": "",
- "policy_ids": null,
- "host_batch_size": 0
- },
- "vulnerabilities_webhook": {
- "enable_vulnerabilities_webhook": false,
- "destination_url": "",
- "host_batch_size": 0
- },
- "interval": "0s"
- },
- "integrations": {
- "jira": null,
- "zendesk": null
- },
- "update_interval": {
- "osquery_detail": "1h0m0s",
- "osquery_policy": "1h0m0s"
- },
- "vulnerabilities": {
- "databases_path": "",
- "periodicity": "0s",
- "cpe_database_url": "",
- "cpe_translations_url": "",
- "cve_feed_prefix_url": "",
- "current_instance_checks": "",
- "disable_data_sync": false,
- "recent_vulnerability_max_age": "0s",
- "disable_win_os_vulnerabilities": false
- },
- "license": {
- "tier": "free",
- "expiration": "0001-01-01T00:00:00Z"
- },
- "logging": {
- "debug": true,
- "json": false,
- "result": {
- "plugin": "filesystem",
- "config": {
- "enable_log_compression": false,
- "enable_log_rotation": false,
- "result_log_file": "/dev/null",
- "status_log_file": "/dev/null",
- "audit_log_file": "/dev/null",
- "max_size": 500,
- "max_age": 0,
- "max_backups": 0
- }
- },
- "status": {
- "plugin": "filesystem",
- "config": {
- "enable_log_compression": false,
- "enable_log_rotation": false,
- "result_log_file": "/dev/null",
- "status_log_file": "/dev/null",
- "audit_log_file": "/dev/null",
- "max_size": 500,
- "max_age": 0,
- "max_backups": 0
- }
- },
- "audit": {
- "plugin": "filesystem",
- "config": {
- "enable_log_compression": false,
- "enable_log_rotation": false,
- "result_log_file": "/dev/null",
- "status_log_file": "/dev/null",
- "audit_log_file": "/dev/null",
- "max_size": 500,
- "max_age": 0,
- "max_backups": 0
- }
- }
- }
- }
+ "kind": "config",
+ "apiVersion": "v1",
+ "spec": {
+ "org_info": {
+ "org_name": "",
+ "org_logo_url": "",
+ "org_logo_url_light_background": "",
+ "contact_url": "https://fleetdm.com/company/contact"
+ },
+ "server_settings": {
+ "server_url": "",
+ "live_query_disabled": false,
+ "enable_analytics": false,
+ "deferred_save_host": false
+ },
+ "smtp_settings": {
+ "enable_smtp": false,
+ "configured": false,
+ "sender_address": "",
+ "server": "",
+ "port": 0,
+ "authentication_type": "",
+ "user_name": "",
+ "password": "",
+ "enable_ssl_tls": false,
+ "authentication_method": "",
+ "domain": "",
+ "verify_ssl_certs": false,
+ "enable_start_tls": false
+ },
+ "host_expiry_settings": {
+ "host_expiry_enabled": false,
+ "host_expiry_window": 0
+ },
+ "features": {
+ "enable_host_users": true,
+ "enable_software_inventory": false
+ },
+ "mdm": {
+ "apple_bm_default_team": "",
+ "apple_bm_terms_expired": false,
+ "apple_bm_enabled_and_configured": false,
+ "enabled_and_configured": false,
+ "windows_enabled_and_configured": false,
+ "macos_updates": {
+ "minimum_version": null,
+ "deadline": null
+ },
+ "macos_migration": {
+ "enable": false,
+ "mode": "",
+ "webhook_url": ""
+ },
+ "macos_settings": {
+ "custom_settings": null,
+ "enable_disk_encryption": false
+ },
+ "macos_setup": {
+ "bootstrap_package": null,
+ "enable_end_user_authentication": false,
+ "macos_setup_assistant": null
+ },
+ "end_user_authentication": {
+ "entity_id": "",
+ "issuer_uri": "",
+ "metadata": "",
+ "metadata_url": "",
+ "idp_name": ""
+ }
+ },
+ "sso_settings": {
+ "enable_jit_provisioning": false,
+ "enable_jit_role_sync": false,
+ "entity_id": "",
+ "issuer_uri": "",
+ "idp_image_url": "",
+ "metadata": "",
+ "metadata_url": "",
+ "idp_name": "",
+ "enable_sso": false,
+ "enable_sso_idp_login": false
+ },
+ "fleet_desktop": {
+ "transparency_url": "https://fleetdm.com/transparency"
+ },
+ "vulnerability_settings": {
+ "databases_path": "/some/path"
+ },
+ "webhook_settings": {
+ "host_status_webhook": {
+ "enable_host_status_webhook": false,
+ "destination_url": "",
+ "host_percentage": 0,
+ "days_count": 0
+ },
+ "failing_policies_webhook": {
+ "enable_failing_policies_webhook": false,
+ "destination_url": "",
+ "policy_ids": null,
+ "host_batch_size": 0
+ },
+ "vulnerabilities_webhook": {
+ "enable_vulnerabilities_webhook": false,
+ "destination_url": "",
+ "host_batch_size": 0
+ },
+ "interval": "0s"
+ },
+ "integrations": {
+ "jira": null,
+ "zendesk": null
+ },
+ "update_interval": {
+ "osquery_detail": "1h0m0s",
+ "osquery_policy": "1h0m0s"
+ },
+ "vulnerabilities": {
+ "databases_path": "",
+ "periodicity": "0s",
+ "cpe_database_url": "",
+ "cpe_translations_url": "",
+ "cve_feed_prefix_url": "",
+ "current_instance_checks": "",
+ "disable_data_sync": false,
+ "recent_vulnerability_max_age": "0s",
+ "disable_win_os_vulnerabilities": false
+ },
+ "license": {
+ "tier": "free",
+ "expiration": "0001-01-01T00:00:00Z"
+ },
+ "logging": {
+ "debug": true,
+ "json": false,
+ "result": {
+ "plugin": "filesystem",
+ "config": {
+ "enable_log_compression": false,
+ "enable_log_rotation": false,
+ "result_log_file": "/dev/null",
+ "status_log_file": "/dev/null",
+ "audit_log_file": "/dev/null",
+ "max_size": 500,
+ "max_age": 0,
+ "max_backups": 0
+ }
+ },
+ "status": {
+ "plugin": "filesystem",
+ "config": {
+ "enable_log_compression": false,
+ "enable_log_rotation": false,
+ "result_log_file": "/dev/null",
+ "status_log_file": "/dev/null",
+ "audit_log_file": "/dev/null",
+ "max_size": 500,
+ "max_age": 0,
+ "max_backups": 0
+ }
+ },
+ "audit": {
+ "plugin": "filesystem",
+ "config": {
+ "enable_log_compression": false,
+ "enable_log_rotation": false,
+ "result_log_file": "/dev/null",
+ "status_log_file": "/dev/null",
+ "audit_log_file": "/dev/null",
+ "max_size": 500,
+ "max_age": 0,
+ "max_backups": 0
+ }
+ }
+ }
+ }
}
diff --git a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml
index 1ca389bdb7..9d3bf00ace 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml
+++ b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml
@@ -80,6 +80,7 @@ spec:
plugin: filesystem
org_info:
org_logo_url: ""
+ org_logo_url_light_background: ""
org_name: ""
contact_url: https://fleetdm.com/company/contact
server_settings:
diff --git a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml
index 0fc824aad9..4fc311a8dd 100644
--- a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml
+++ b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml
@@ -41,6 +41,7 @@ spec:
entity_id: ""
org_info:
org_logo_url: ""
+ org_logo_url_light_background: ""
org_name: "Fleet"
contact_url: "https://fleetdm.com/company/contact"
server_settings:
diff --git a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml
index f4a36b668c..72b5d2c599 100644
--- a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml
+++ b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml
@@ -41,6 +41,7 @@ spec:
entity_id: ""
org_info:
org_logo_url: ""
+ org_logo_url_light_background: ""
org_name: Fleet
contact_url: https://fleetdm.com/company/contact
server_settings:
diff --git a/cmd/osquery-perf/agent.go b/cmd/osquery-perf/agent.go
index 529c9c7412..32504c8680 100644
--- a/cmd/osquery-perf/agent.go
+++ b/cmd/osquery-perf/agent.go
@@ -9,14 +9,10 @@ import (
"errors"
"flag"
"fmt"
- "io"
"log"
"math/rand"
"net/http"
"os"
- "path"
- "path/filepath"
- "runtime"
"strconv"
"strings"
"sync"
@@ -32,33 +28,77 @@ import (
"github.com/valyala/fasthttp"
)
-//go:embed *.tmpl
-var templatesFS embed.FS
+var (
+ //go:embed *.tmpl
+ templatesFS embed.FS
-//go:embed *.software
-var softwareFS embed.FS
+ //go:embed *.software
+ macOSVulnerableSoftwareFS embed.FS
-var vulnerableSoftware []fleet.Software
+ //go:embed ubuntu_2204-software.json.bz2
+ ubuntuSoftwareFS embed.FS
+ //go:embed windows_11-software.json.bz2
+ windowsSoftwareFS embed.FS
-func init() {
- vulnerableSoftwareData, err := softwareFS.ReadFile("vulnerable.software")
+ macosVulnerableSoftware []fleet.Software
+ windowsSoftware []map[string]string
+ ubuntuSoftware []map[string]string
+)
+
+func loadMacOSVulnerableSoftware() {
+ macOSVulnerableSoftwareData, err := macOSVulnerableSoftwareFS.ReadFile("macos_vulnerable.software")
if err != nil {
- log.Fatal("reading vulnerable software file: ", err)
+ log.Fatal("reading vulnerable macOS software file: ", err)
}
- lines := bytes.Split(vulnerableSoftwareData, []byte("\n"))
+ lines := bytes.Split(macOSVulnerableSoftwareData, []byte("\n"))
for _, line := range lines {
parts := bytes.Split(line, []byte("##"))
if len(parts) < 2 {
fmt.Println("skipping", string(line))
continue
}
- vulnerableSoftware = append(vulnerableSoftware, fleet.Software{
+ macosVulnerableSoftware = append(macosVulnerableSoftware, fleet.Software{
Name: strings.TrimSpace(string(parts[0])),
Version: strings.TrimSpace(string(parts[1])),
Source: "apps",
})
}
- log.Printf("Loaded %d vulnerable software\n", len(vulnerableSoftware))
+ log.Printf("Loaded %d vulnerable macOS software\n", len(macosVulnerableSoftware))
+}
+
+func loadSoftwareItems(fs embed.FS, path string) []map[string]string {
+ bz2, err := fs.Open(path)
+ if err != nil {
+ panic(err)
+ }
+
+ type softwareJSON struct {
+ Name string `json:"name"`
+ Version string `json:"version"`
+ Release string `json:"release,omitempty"`
+ Arch string `json:"arch,omitempty"`
+ }
+ var softwareList []softwareJSON
+ // ignoring "G110: Potential DoS vulnerability via decompression bomb", as this is test code.
+ if err := json.NewDecoder(bzip2.NewReader(bz2)).Decode(&softwareList); err != nil { //nolint:gosec
+ panic(err)
+ }
+
+ softwareRows := make([]map[string]string, 0, len(softwareList))
+ for _, s := range softwareList {
+ softwareRows = append(softwareRows, map[string]string{
+ "name": s.Name,
+ "version": s.Version,
+ "source": "programs",
+ })
+ }
+ return softwareRows
+}
+
+func init() {
+ loadMacOSVulnerableSoftware()
+ windowsSoftware = loadSoftwareItems(windowsSoftwareFS, "windows_11-software.json.bz2")
+ ubuntuSoftware = loadSoftwareItems(ubuntuSoftwareFS, "ubuntu_2204-software.json.bz2")
}
type Stats struct {
@@ -748,99 +788,6 @@ func (a *agent) hostUsers() []map[string]string {
return users
}
-func extract(src, dst string) {
- srcF, err := os.Open(src)
- if err != nil {
- panic(err)
- }
- defer srcF.Close()
-
- dstF, err := os.Create(dst)
- if err != nil {
- panic(err)
- }
- defer dstF.Close()
-
- r := bzip2.NewReader(srcF)
- // ignoring "G110: Potential DoS vulnerability via decompression bomb", as this is test code.
- _, err = io.Copy(dstF, r) //nolint:gosec
- if err != nil {
- panic(err)
- }
-}
-
-func loadSoftware(platform string, ver string) []map[string]string {
- _, exFilename, _, ok := runtime.Caller(0)
- if !ok {
- panic("No caller information")
- }
- exDir := path.Dir(exFilename)
-
- srcPath := filepath.Join(
- exDir,
- "..",
- "..",
- "server",
- "vulnerabilities",
- "testdata",
- platform,
- "software",
- fmt.Sprintf("%s_%s-software.json.bz2", platform, ver),
- )
-
- tmpDir, err := os.MkdirTemp("", "osquery-perf")
- if err != nil {
- panic(err)
- }
- defer os.RemoveAll(tmpDir)
- dstPath := filepath.Join(tmpDir, fmt.Sprintf("%s-software.json", ver))
-
- extract(srcPath, dstPath)
-
- type softwareJSON struct {
- Name string `json:"name"`
- Version string `json:"version"`
- Release string `json:"release,omitempty"`
- Arch string `json:"arch,omitempty"`
- }
-
- var software []softwareJSON
- contents, err := os.ReadFile(dstPath)
- if err != nil {
- log.Printf("reading vuln software for %s %s: %s\n", platform, ver, err)
- return nil
- }
-
- err = json.Unmarshal(contents, &software)
- if err != nil {
- log.Printf("unmarshalling vuln software for %s %s:%s", platform, ver, err)
- return nil
- }
-
- var r []map[string]string
- for i, fi := range software {
- installedPath := ""
- if i%2 == 0 {
- installedPath = fmt.Sprintf("/some/path/%s", fi.Name)
- }
- r = append(r, map[string]string{
- "name": fi.Name,
- "version": fi.Version,
- "source": "osquery-perf",
- "installed_path": installedPath,
- })
- }
- return r
-}
-
-func (a *agent) softwareWindows11() []map[string]string {
- return loadSoftware("windows", "11")
-}
-
-func (a *agent) softwareUbuntu2204() []map[string]string {
- return loadSoftware("ubuntu", "2204")
-}
-
func (a *agent) softwareMacOS() []map[string]string {
var lastOpenedCount int
commonSoftware := make([]map[string]string, a.softwareCount.common)
@@ -887,7 +834,7 @@ func (a *agent) softwareMacOS() []map[string]string {
}
randomVulnerableSoftware := make([]map[string]string, a.softwareCount.vulnerable)
for i := 0; i < len(randomVulnerableSoftware); i++ {
- sw := vulnerableSoftware[rand.Intn(len(vulnerableSoftware))]
+ sw := macosVulnerableSoftware[rand.Intn(len(macosVulnerableSoftware))]
var lastOpenedAt string
if l := a.genLastOpenedAt(&lastOpenedCount); l != nil {
lastOpenedAt = l.Format(time.UnixDate)
@@ -1245,7 +1192,7 @@ func (a *agent) processQuery(name, query string) (handled bool, results []map[st
case name == hostDetailQueryPrefix+"software_windows":
ss := fleet.OsqueryStatus(rand.Intn(2))
if ss == fleet.StatusOK {
- results = a.softwareWindows11()
+ results = windowsSoftware
}
return true, results, &ss, nil
case name == hostDetailQueryPrefix+"software_linux":
@@ -1253,7 +1200,7 @@ func (a *agent) processQuery(name, query string) (handled bool, results []map[st
if ss == fleet.StatusOK {
switch a.os {
case "ubuntu_22.04":
- results = a.softwareUbuntu2204()
+ results = ubuntuSoftware
}
}
return true, results, &ss, nil
diff --git a/cmd/osquery-perf/vulnerable.software b/cmd/osquery-perf/macos_vulnerable.software
similarity index 100%
rename from cmd/osquery-perf/vulnerable.software
rename to cmd/osquery-perf/macos_vulnerable.software
diff --git a/cmd/osquery-perf/ubuntu_2204-software.json.bz2 b/cmd/osquery-perf/ubuntu_2204-software.json.bz2
new file mode 100644
index 0000000000..ea9cc3399d
Binary files /dev/null and b/cmd/osquery-perf/ubuntu_2204-software.json.bz2 differ
diff --git a/cmd/osquery-perf/windows_11-software.json.bz2 b/cmd/osquery-perf/windows_11-software.json.bz2
new file mode 100644
index 0000000000..589e2e500f
Binary files /dev/null and b/cmd/osquery-perf/windows_11-software.json.bz2 differ
diff --git a/docs/Contributing/API-Versioning.md b/docs/Contributing/API-Versioning.md
index 32aa06626d..8dc8deeb1a 100644
--- a/docs/Contributing/API-Versioning.md
+++ b/docs/Contributing/API-Versioning.md
@@ -107,3 +107,4 @@ This will mean that the following are the only valid paths after this point:
And the code doesn't have to specify `.StartingAtVersion("2021-12")` anymore.
+
diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md
index e95197f32a..881c7f8496 100644
--- a/docs/Contributing/API-for-contributors.md
+++ b/docs/Contributing/API-for-contributors.md
@@ -671,12 +671,13 @@ This endpoint stores a profile to be assigned to a host at some point in the fut
#### Parameters
-| Name | Type | In | Description |
-| ------------ | ------ | ---- | ----------------------------------------------------------- |
-| external_host_identifier | string | body | **Required**. The identifier of the host as generated by the external service (e.g. Puppet). |
-| host_uuid | string | body | **Required**. The UUID of the host. |
-| profile | string | body | **Required**. The base64-encoded .mobileconfig content of the MDM profile. |
-| group | string | body | The group label associated with that profile. This information is used to generate team names if they need to be created. |
+| Name | Type | In | Description |
+| ------------ | ------- | ---- | ----------------------------------------------------------- |
+| external_host_identifier | string | body | **Required**. The identifier of the host as generated by the external service (e.g. Puppet). |
+| host_uuid | string | body | **Required**. The UUID of the host. |
+| profile | string | body | **Required**. The base64-encoded .mobileconfig content of the MDM profile. |
+| group | string | body | The group label associated with that profile. This information is used to generate team names if they need to be created. |
+| exclude | boolean | body | Whether to skip delivering the profile to this host. |
#### Example
@@ -689,7 +690,8 @@ This endpoint stores a profile to be assigned to a host at some point in the fut
"external_host_identifier": "id-01234",
"host_uuid": "c0532a64-bec2-4cf9-aa37-96fe47ead814",
"profile": "",
- "group": "Workstations"
+ "group": "Workstations",
+ "exclude": false
}
```
@@ -2222,6 +2224,7 @@ Device-authenticated routes are routes used by the Fleet Desktop application. Un
- [Get device's transparency URL](#get-devices-transparency-url)
- [Download device's MDM manual enrollment profile](#download-devices-mdm-manual-enrollment-profile)
- [Migrate device to Fleet from another MDM solution](#migrate-device-to-fleet-from-another-mdm-solution)
+- [Trigger FileVault key escrow](#trigger-filevault-key-escrow)
#### Get device's host
@@ -2656,6 +2659,28 @@ Signals the Fleet server to send a webbook request with the device UUID and seri
---
+#### Trigger FileVault key escrow
+
+Sends a signal to Fleet Desktop to initiate a FileVault key escrow. This is useful for setting the escrow key initially as well as in scenarios where a token rotation is required. **Requires Fleet Premium license**
+
+`POST /api/v1/fleet/device/{token}/rotate_encryption_key`
+
+##### Parameters
+
+| Name | Type | In | Description |
+| ----- | ------ | ---- | ---------------------------------- |
+| token | string | path | The device's authentication token. |
+
+##### Example
+
+`POST /api/v1/fleet/device/abcdef012456789/rotate_encryption_key`
+
+##### Default response
+
+`Status: 204`
+
+---
+
## Downloadable installers
@@ -2790,3 +2815,4 @@ If the Fleet instance is provided required parameters to complete setup.
```
+
diff --git a/docs/Contributing/Adding-new-endpoints.md b/docs/Contributing/Adding-new-endpoints.md
index 9fe56f6ba0..4a86d26ee6 100644
--- a/docs/Contributing/Adding-new-endpoints.md
+++ b/docs/Contributing/Adding-new-endpoints.md
@@ -269,3 +269,4 @@ The logic here is that if there are any parameters in the Request struct that ha
expected, and the absence of it results in an error.
+
diff --git a/docs/Contributing/Automatically-generating-UI-component-boilerplate.md b/docs/Contributing/Automatically-generating-UI-component-boilerplate.md
index 80ad32d3b8..9cef3a93a2 100644
--- a/docs/Contributing/Automatically-generating-UI-component-boilerplate.md
+++ b/docs/Contributing/Automatically-generating-UI-component-boilerplate.md
@@ -16,3 +16,4 @@ You can also run `./generate -h` for information about the other options availab
specifying destination.
+
diff --git a/docs/Contributing/Building-Fleet.md b/docs/Contributing/Building-Fleet.md
index bc1caa19c4..5f6348fcde 100644
--- a/docs/Contributing/Building-Fleet.md
+++ b/docs/Contributing/Building-Fleet.md
@@ -229,3 +229,4 @@ dlv debug --build-flags '-tags=full' --headless \
```
+
diff --git a/docs/Contributing/Committing-Changes.md b/docs/Contributing/Committing-Changes.md
index bc02bc32c4..e34c4e75e1 100644
--- a/docs/Contributing/Committing-Changes.md
+++ b/docs/Contributing/Committing-Changes.md
@@ -102,3 +102,4 @@ Keep in mind that the commit title and description are what developers see when
Keeping to around 80 character line lengths helps with rendering when folks have narrow, tiled terminal windows.
+
diff --git a/docs/Contributing/Configuration-for-contributors.md b/docs/Contributing/Configuration-for-contributors.md
index ee768c96ed..0c978f82c5 100644
--- a/docs/Contributing/Configuration-for-contributors.md
+++ b/docs/Contributing/Configuration-for-contributors.md
@@ -362,3 +362,4 @@ Whether the SMTP server's SSL certificates should be verified. This can be turne
```
+
diff --git a/docs/Contributing/Deploying-chrome-test-ext.md b/docs/Contributing/Deploying-chrome-test-ext.md
new file mode 100644
index 0000000000..7a30649fb1
--- /dev/null
+++ b/docs/Contributing/Deploying-chrome-test-ext.md
@@ -0,0 +1,68 @@
+# Deploying ChromeOS test extensions to enrolled Chromebooks
+
+As part of validating any ChromeOS extension, run this process to force-install the extension on Chromebooks for debugging.
+
+## Build the extension
+
+### Bump the extension version
+
+Modify the version field at the top of the [`package.json`](https://github.com/fleetdm/fleet/blob/main/ee/fleetd-chrome/package.json) file in `ee/fleetd-chrome`
+
+Update the version in [`updates.xml`](https://github.com/fleetdm/fleet/blob/main/ee/fleetd-chrome/updates.xml) to match the `package.json` version.
+
+### Build the distribution folder
+
+```
+cd ee/fleetd-chrome
+yarn run build
+```
+
+### Pack the extension
+
+Navigate to chrome://extensions in your Chrome web browser.
+- In developer mode, select "Pack extension"
+- Set "Extension root directory" to the newly-created `ee/fleetd-chrome/dist` folder
+- Press "Pack extension" (key name will auto-generate)
+
+### Load the new extension to the Chrome web browser
+
+- Open the finder app
+- Drag and drop the `ee/fleetd-chrome/dist.crx` binary file on top of a Chrome web browser window
+- Press "Add Extension"
+- Verify that the extension works
+- **Copy the `appid` for later use**
+
+## Run a local server to make the new extension available
+
+### Edit update.xml
+Open `ee/fleetd-chrome/update.xml` in your text editor and modify:
+- The version.
+- The `appid` (copied previously). This will only be done for debug versions. For production, we will keep the original ID we have.
+
+### Create the server
+
+```
+cd ee/fleetd-chrome
+python3 -m http.server
+```
+- Verify that it works by going to http://localhost:8000 to see the files.
+
+```
+cd ee/fleetd-chrome
+npm install -g localtunnel
+lt --port 8000 --subdomain test-new-tables
+```
+- In your web browser go to: http://test-new-tables.loca.lt
+- Click the hazard link on item number 1 (below the big button "Click To Submit"). From the new page, copy the IP and paste it into the previous page in the window.
+- Open `ee/fleetd-chrome/update.xml` in your text editor and modify the codebase to use the newly created URL (in this example: http://test-new-tables.loca.lt/dist.crx).
+
+### Deploy the extension using Google Admin
+
+> Follow the instructions [here](https://fleetdm.com/docs/using-fleet/adding-hosts#add-chromebooks-with-the-fleetd-chrome-extension) for installing the fleetd Chrome extension, with the following modifications:
+> + Select the "ChromeOSTesting" group.
+> + For "Extension ID", use the ID previously copied.
+> + For "Installation URL", use `http://test-new-tables.loca.lt/updates.xml`.
+> + Remove the filters (the filters with our `appid`).
+> + For "Policy for extensions", copy over the JSON from the original extension.
+
+
diff --git a/docs/Contributing/FAQ.md b/docs/Contributing/FAQ.md
index 59832d0346..2731f819b0 100644
--- a/docs/Contributing/FAQ.md
+++ b/docs/Contributing/FAQ.md
@@ -92,3 +92,5 @@ If you also have Orbit running on hosts, it will need access to these API endpoi
* `/api/fleet/orbit/device_token`
* `/api/fleet/orbit/ping`
* `/api/osquery/log`
+
+
\ No newline at end of file
diff --git a/docs/Contributing/Fleet-UI-Testing.md b/docs/Contributing/Fleet-UI-Testing.md
index 6be3293d15..5a52b53370 100644
--- a/docs/Contributing/Fleet-UI-Testing.md
+++ b/docs/Contributing/Fleet-UI-Testing.md
@@ -328,3 +328,4 @@ in that we believe tests should resemble real-world usage as closely as possible
// TODO
+
diff --git a/docs/Contributing/Migrations.md b/docs/Contributing/Migrations.md
index 139188f73d..deacec368c 100644
--- a/docs/Contributing/Migrations.md
+++ b/docs/Contributing/Migrations.md
@@ -46,3 +46,4 @@ Move the migration file from [server/datastore/mysql/migrations/tables/](https:/
Proceed as for table migrations, editing and running the newly created migration file.
+
diff --git a/docs/Contributing/Orbit-development-and-release-strategy.md b/docs/Contributing/Orbit-development-and-release-strategy.md
index 544615da73..6fa407bd3d 100644
--- a/docs/Contributing/Orbit-development-and-release-strategy.md
+++ b/docs/Contributing/Orbit-development-and-release-strategy.md
@@ -29,4 +29,5 @@ This allows some flexibility when developing new features in Orbit and Fleet.
1. Orbit components (Orbit itself, Fleet Desktop and osqueryd) must be released to FleetDM's TUF before new Fleet server releases are available in Github.
2. When the new Fleet server version doesn't support older Orbit versions (see [Nice to have](#nice-to-have)), the release notes must document their minimum supported Orbit version. This is for users that use Orbit with auto-updates disabled or they pin to a specific channel. These users would need to first update Orbit in their devices and then proceed to upgrade Fleet server.
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Contributing/README.md b/docs/Contributing/README.md
index 4ce97c2171..ec4c669436 100644
--- a/docs/Contributing/README.md
+++ b/docs/Contributing/README.md
@@ -24,5 +24,8 @@ Learn how to add fake data to your development instance.
### [API for contributors](./API-for-contributors.md)
Get to grips with Fleet API routes. This documentation is helpful for developing or contributing to Fleet.
+### [Deploying ChromeOS test extensions](./Deploying-chrome-test-ext.md)
+Learn how to deploy a test version of the fleetd Chrome extension for debug purposes.
+
### [FAQ](./FAQ.md)
Find commonly asked questions and answers about contributing to Fleet as part of our community.
diff --git a/docs/Contributing/Releasing-Fleet.md b/docs/Contributing/Releasing-Fleet.md
index 44558a41c6..826598d00e 100644
--- a/docs/Contributing/Releasing-Fleet.md
+++ b/docs/Contributing/Releasing-Fleet.md
@@ -145,3 +145,4 @@ A patch release is required when a critical bug is found. Critical bugs are defi
TODO [#2850](https://github.com/fleetdm/fleet/issues/2850): Improve docs/tooling for this.
+
diff --git a/docs/Contributing/Run-Locally-Built-Orbit.md b/docs/Contributing/Run-Locally-Built-Orbit.md
index bdb7264d4f..5f4695ee41 100644
--- a/docs/Contributing/Run-Locally-Built-Orbit.md
+++ b/docs/Contributing/Run-Locally-Built-Orbit.md
@@ -60,3 +60,4 @@ Double-Click this pkg file and install the local Orbit.
+
diff --git a/docs/Contributing/Seeding-Data.md b/docs/Contributing/Seeding-Data.md
index fd90868917..6d744cb068 100644
--- a/docs/Contributing/Seeding-Data.md
+++ b/docs/Contributing/Seeding-Data.md
@@ -68,7 +68,6 @@ The `fleet/create_figma` script will generate an environment to reflect the mock
Each user generated by the script has its password set to `password123#`.
-
## Related actions
@@ -88,4 +87,7 @@ Fleet supports [SSO users](https://fleetdm.com/docs/deploying/configuration#conf
### Create test hosts
-To create a handful of test hosts, you can run containerized `osqueryd` [Docker test hosts](https://github.com/fleetdm/fleet/tree/main/tools/osquery). As these Docker test hosts are RAM intensive, alternatively, you can use `osquery-perf` to create thousands of [simulated test hosts](https://github.com/fleetdm/fleet/tree/main/cmd/osquery-perf).
\ No newline at end of file
+To create a handful of test hosts, you can run containerized `osqueryd` [Docker test hosts](https://github.com/fleetdm/fleet/tree/main/tools/osquery). As these Docker test hosts are RAM intensive, alternatively, you can use `osquery-perf` to create thousands of [simulated test hosts](https://github.com/fleetdm/fleet/tree/main/cmd/osquery-perf).
+
+
+
diff --git a/docs/Contributing/Simulate-slow-network.md b/docs/Contributing/Simulate-slow-network.md
index bb912c00aa..3b342a0f3a 100644
--- a/docs/Contributing/Simulate-slow-network.md
+++ b/docs/Contributing/Simulate-slow-network.md
@@ -43,4 +43,5 @@ curl -s -XPOST -d '{"type" : "latency", "attributes" : {"latency" : 1000, "jitte
{"attributes":{"latency":5000,"jitter":0},"name":"latency_downstream","type":"latency","stream":"downstream","toxicity":1}%
```
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Contributing/Testing-and-local-development.md b/docs/Contributing/Testing-and-local-development.md
index 50b2e34c0b..9b5489e381 100644
--- a/docs/Contributing/Testing-and-local-development.md
+++ b/docs/Contributing/Testing-and-local-development.md
@@ -673,3 +673,4 @@ The `pkg` file needs to be a signed "distribution package", you can find a dummy
The dummy package linked above adds a Fleet logo in `/Library/FleetDM/fleet-logo.png`. To verify if the package was installed, you can open that folder and verify that the logo is there.
+
diff --git a/docs/Deploying/Configuration.md b/docs/Deploying/Configuration.md
index 2dcc7f4c51..5e31b047f2 100644
--- a/docs/Deploying/Configuration.md
+++ b/docs/Deploying/Configuration.md
@@ -2517,7 +2517,6 @@ If set, then `Fleet serve` will capture errors and panics and push them to Sentr
dsn: "https://somedsnprovidedby.sentry.com/"
```
-
#### Prometheus
@@ -3221,3 +3220,7 @@ The HTTP request headers are checked in the following order:
4. If none of the above headers are present in the HTTP request then Fleet will attempt to use the remote address of the TCP connection (note that on deployments with ingress proxies the remote address seen by Fleet is the IP of the ingress proxy).
If the IP retrieved using the above heuristic belongs to a private range, then Fleet will ignore it and will not set the "Public IP address" field for the device.
+
+
+
+
\ No newline at end of file
diff --git a/docs/Deploying/Debugging.md b/docs/Deploying/Debugging.md
index 178e855e16..be5a2b0afa 100644
--- a/docs/Deploying/Debugging.md
+++ b/docs/Deploying/Debugging.md
@@ -173,3 +173,4 @@ Make sure as well that your cloud provider is not having issues of their own. Fo
[AWS](https://health.aws.amazon.com/health/status) for status.
+
diff --git a/docs/Deploying/FAQ.md b/docs/Deploying/FAQ.md
index 87b1e29f44..b79c0f3797 100644
--- a/docs/Deploying/FAQ.md
+++ b/docs/Deploying/FAQ.md
@@ -218,3 +218,6 @@ Fleet is tested with Redis 5.0.14 and 6.2.7. Any version Redis after version 5 w
## Will my older version of Fleet work with Redis 6?
Most likely, yes! While we'd definitely recommend keeping Fleet up to date in order to take advantage of new features and bug patches, most legacy versions should work with Redis 6. Just keep in mind that we likely haven't tested your particular combination so that you may run into some unforeseen hiccups.
+
+
+
+
diff --git a/docs/Deploying/Load-testing.md b/docs/Deploying/Load-testing.md
index 3f1e7e49e9..4aff6e487d 100644
--- a/docs/Deploying/Load-testing.md
+++ b/docs/Deploying/Load-testing.md
@@ -74,3 +74,4 @@ They are sized to be the smallest that Fargate allows, so it is still cost effec
The [osquery-perf](https://github.com/fleetdm/fleet/tree/main/cmd/osquery-perf) tool doesn't simulate all data that's included when a real device communicates to a Fleet instance. For example, system users and software inventory data are not yet simulated by osquery-perf.
+
diff --git a/docs/Deploying/README.md b/docs/Deploying/README.md
index 69ebf55aa5..40c63cac04 100644
--- a/docs/Deploying/README.md
+++ b/docs/Deploying/README.md
@@ -23,3 +23,5 @@ Information to gather as part of debugging an issue with a deployment.
### [FAQ](./FAQ.md)
Includes commonly asked questions and answers about deployment from the Fleet community.
+
+
diff --git a/docs/Deploying/Reference-Architectures.md b/docs/Deploying/Reference-Architectures.md
index 398ee0887a..1c4613cb75 100644
--- a/docs/Deploying/Reference-Architectures.md
+++ b/docs/Deploying/Reference-Architectures.md
@@ -351,3 +351,4 @@ services:
+
diff --git a/docs/Deploying/Server-Installation.md b/docs/Deploying/Server-Installation.md
index c6e356321f..8be3a6e778 100644
--- a/docs/Deploying/Server-Installation.md
+++ b/docs/Deploying/Server-Installation.md
@@ -34,7 +34,9 @@ In this guide, we're going to install Fleet and all of its application dependenc
### Setting up a host
-Acquiring a CentOS host to use for this guide is largely an exercise for the reader. If you don't have a CentOS host readily available, feel free to use [Vagrant](https://www.vagrantup.com/). In a clean, temporary directory, you can run the following to create a vagrant box, start it, and log into it:
+If you don't have a CentOS host readily available, Fleet recommends using [Vagrant](https://www.vagrantup.com/) for this guide. You can find installation instructions on Vagrant's [downloads page](https://developer.hashicorp.com/vagrant/downloads).
+
+Once you have installed Vagrant, run the following to create a Vagrant box, start it, and log into it:
```
echo 'Vagrant.configure("2") do |config|
@@ -519,3 +521,4 @@ Below are some projects created by Fleet community members. These projects provi
- [CptOfEvilMinions/FleetDM-Automation](https://github.com/CptOfEvilMinions/FleetDM-Automation) - Ansible and Docker code to set up Fleet
+
diff --git a/docs/Deploying/Upgrading-Fleet.md b/docs/Deploying/Upgrading-Fleet.md
index 89cc83b796..863a68f80d 100644
--- a/docs/Deploying/Upgrading-Fleet.md
+++ b/docs/Deploying/Upgrading-Fleet.md
@@ -57,4 +57,5 @@ Once Fleet has been replaced with the newest version and the database migrations
fleet serve
```
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Deploying/cloudgov.md b/docs/Deploying/cloudgov.md
index 516339a499..d5a3b7d2c6 100644
--- a/docs/Deploying/cloudgov.md
+++ b/docs/Deploying/cloudgov.md
@@ -112,3 +112,4 @@ variables](https://fleetdm.com/docs/deploying/configuration#using-only-environme
+
diff --git a/docs/Deploying/fleetctl-agent-updates.md b/docs/Deploying/fleetctl-agent-updates.md
index 8f52335279..3c9ab7bab9 100644
--- a/docs/Deploying/fleetctl-agent-updates.md
+++ b/docs/Deploying/fleetctl-agent-updates.md
@@ -161,3 +161,4 @@ fleetctl updates rotate targets
After the key(s) have been rotated, publish the repository in the same fashion as any other update.
+
diff --git a/docs/README.md b/docs/README.md
index a4510f80df..681d2624a7 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,6 +1,6 @@
# Fleet documentation
-Welcome to the documentation for Fleet, the lightweight telemetry platform for servers and workstations.
+Welcome to the documentation for Fleet, the lightweight management platform for laptops and servers.
> You can also read the Fleet docs over at https://fleetdm.com/docs.
diff --git a/docs/Using-Fleet/Adding-hosts.md b/docs/Using-Fleet/Adding-hosts.md
index 7e5744cf77..9d12dc93f0 100644
--- a/docs/Using-Fleet/Adding-hosts.md
+++ b/docs/Using-Fleet/Adding-hosts.md
@@ -17,6 +17,7 @@
- [Migrating from plain osquery to osquery installer](#migrating-from-plain-osquery-to-osquery-installer)
- [Generate installer](#generate-installer)
- [Migrate](#migrate)
+ - [Add Chromebooks with the fleetd Chrome extension](#add-chromebooks-with-the-fleetd-chrome-extension)
- [Grant full disk access to osquery on macOS](#grant-full-disk-access-to-osquery-on-macos)
- [Creating the configuration profile](#creating-the-configuration-profile)
- [Obtaining identifiers](#obtaining-identifiers)
@@ -29,7 +30,7 @@ Fleet gathers information from an [osquery](https://github.com/osquery/osquery)
You can also install plain osquery on your hosts and connect to Fleet using osquery's `TLS API` plugins.
-> For ChromeOS hosts, the fleetd Chrome extension is installed instead of osquery. This Chrome browser extension is only supported on ChromeOS operating systems that are managed using [Google Admin](https://admin.google.com).
+> For ChromeOS hosts, the [fleetd Chrome extension](#add-chromebooks-with-the-fleetd-chrome-extension) is installed instead of osquery.
## Add hosts with Orbit
@@ -279,7 +280,9 @@ installation should appear as the same host in the Fleet UI. If other settings a
entries will appear in the Fleet UI. The older entries can be automatically cleaned up with the host
expiration setting. To configure this setting, in the Fleet UI, head to **Settings > Organization settings > Advanced options**.
-## Add Chromebooks with the Fleetd Chrome extension
+## Add Chromebooks with the fleetd Chrome extension
+
+> The fleetd Chrome browser extension is supported on ChromeOS operating systems that are managed using [Google Admin](https://admin.google.com). It is not intended for non-ChromeOS hosts with the Chrome browser installed.
Visit the Google Admin console. In the navigation menu, visit Devices > Chrome > Apps & Extensions > Users & browsers.
@@ -363,3 +366,4 @@ See the last hour of logs related to TCC permissions with this command:
You can then look for `orbit` or `osquery` to narrow down results.
+
diff --git a/docs/Using-Fleet/Application-security.md b/docs/Using-Fleet/Application-security.md
index d9dbe8e9b9..359f314e53 100644
--- a/docs/Using-Fleet/Application-security.md
+++ b/docs/Using-Fleet/Application-security.md
@@ -67,3 +67,4 @@ libraries and other vulnerabilities is available in our
+
diff --git a/docs/Using-Fleet/Audit-Activities.md b/docs/Using-Fleet/Audit-Activities.md
index 395f7dc61a..0af5c79dfa 100644
--- a/docs/Using-Fleet/Audit-Activities.md
+++ b/docs/Using-Fleet/Audit-Activities.md
@@ -1,5 +1,5 @@
-# Audit Activities
+# Audit activities
Fleet logs the following information for administrative actions (in JSON):
@@ -553,6 +553,7 @@ This activity contains the following fields:
- "host_serial": Serial number of the host.
- "host_display_name": Display name of the host.
- "installed_from_dep": Whether the host was enrolled via DEP.
+- "mdm_platform": Used to distinguish between Apple and Microsoft enrollments. Can be "apple", "microsoft" or not present. If missing, this value is treated as "apple" for backwards compatibility.
#### Example
@@ -560,7 +561,8 @@ This activity contains the following fields:
{
"host_serial": "C08VQ2AXHT96",
"host_display_name": "MacBookPro16,1 (C08VQ2AXHT96)",
- "installed_from_dep": true
+ "installed_from_dep": true,
+ "mdm_platform": "apple"
}
```
@@ -826,16 +828,17 @@ This activity contains the following fields:
### Type `enabled_windows_mdm`
-Generated when a user turns on MDM features for all Windows hosts (servers excluded).
+Windows MDM features are not ready for production and are currently in development. These features are disabled by default. Generated when a user turns on MDM features for all Windows hosts (servers excluded).
This activity does not contain any detail fields.
### Type `disabled_windows_mdm`
-Generated when a user turns off MDM features for all Windows hosts.
+Windows MDM features are not ready for production and are currently in development. These features are disabled by default. Generated when a user turns off MDM features for all Windows hosts.
This activity does not contain any detail fields.
-
\ No newline at end of file
+
+
diff --git a/docs/Using-Fleet/Automations.md b/docs/Using-Fleet/Automations.md
index c7d2db9fb8..27191afa2e 100644
--- a/docs/Using-Fleet/Automations.md
+++ b/docs/Using-Fleet/Automations.md
@@ -161,3 +161,4 @@ To enable and configure host status automations, navigate to **Settings > Organi
status webhook** in the Fleet UI.
+
diff --git a/docs/Using-Fleet/CIS-Benchmarks.md b/docs/Using-Fleet/CIS-Benchmarks.md
index 65b69cc106..712eb6c862 100644
--- a/docs/Using-Fleet/CIS-Benchmarks.md
+++ b/docs/Using-Fleet/CIS-Benchmarks.md
@@ -1,32 +1,34 @@
# CIS Benchmarks
+> Available in Fleet Premium
+
## Overview
CIS Benchmarks represent the consensus-based effort of cybersecurity experts globally to help you protect your systems against threats more confidently.
For more information about CIS Benchmarks check out [Center for Internet Security](https://www.cisecurity.org/cis-benchmarks)'s website.
-Fleet has implemented native support for CIS benchmarks for the following platforms:
+Fleet has implemented native support for CIS Benchmarks for the following platforms:
- macOS 13.0 Ventura (96 checks)
- Windows 10 Enterprise (496 checks)
-[Where possible](#limitations), each CIS benchmark is implemented with a [policy query](./REST-API.md#policies) in Fleet.
+[Where possible](#limitations), each CIS Benchmark is implemented with a [policy query](./REST-API.md#policies) in Fleet.
## Requirements
Following are the requirements to use the CIS Benchmarks in Fleet:
-- Fleet must be Premium or Ultimate licensed.
-- Devices must be running [Fleetd](https://fleetdm.com/docs/using-fleet/orbit), the osquery manager from Fleet.
-- Devices must be enrolled to an MDM solution.
+- To use these policies, Fleet must have an up-to-date paid license (≥Fleet Premium).
+- Devices must be running [`fleetd`](https://fleetdm.com/docs/using-fleet/orbit), the lightweight agent that bundles the latest osqueryd.
+- Some CIS Benchmarks explicitly involve verifying MDM-based controls, so devices must be enrolled to an MDM solution. (Any MDM solution works, it doesn't have to be Fleet.)
- On macOS, the orbit executable in Fleetd must have "Full Disk Access", see [Grant Full Disk Access to Osquery on macOS](./Adding-hosts.md#grant-full-disk-access-to-osquery-on-macos).
### MDM required
Some of the policies created by Fleet use the [managed_policies](https://www.fleetdm.com/tables/managed_policies) table. This checks whether an MDM solution has turned on the setting to enforce the policy.
-Using MDM is the recommended way to manage and enforce CIS benchmarks. To learn how to set up MDM in Fleet, visit [here](/docs/using-fleet/mdm-setup).
+Using MDM is the recommended way to manage and enforce CIS Benchmarks. To learn how to set up MDM in Fleet, visit [here](/docs/using-fleet/mdm-setup).
### Fleetd required
-Fleet's CIS benchmarks require our [osquery manager, Fleetd](https://fleetdm.com/docs/using-fleet/adding-hosts#osquery-installer). This is because Fleetd includes tables which are not part of vanilla osquery in order to accomplish auditing the benchmarks.
+Fleet's CIS Benchmarks require our [osquery manager, Fleetd](https://fleetdm.com/docs/using-fleet/adding-hosts#osquery-installer). This is because Fleetd includes tables which are not part of vanilla osquery in order to accomplish auditing the benchmarks.
-## How to add CIS benchmarks
+## How to add CIS Benchmarks
All CIS policies are stored under our restricted licensed folder `ee/cis/`.
@@ -258,3 +260,4 @@ Requires this GPO in place: 'Computer Configuration\Policies\Administrative Temp
+
diff --git a/docs/Using-Fleet/ChromeOS.md b/docs/Using-Fleet/ChromeOS.md
index c8011d67c6..e2db8d5d46 100644
--- a/docs/Using-Fleet/ChromeOS.md
+++ b/docs/Using-Fleet/ChromeOS.md
@@ -1,12 +1,12 @@
# ChromeOS
+For visibility on ChromeOS hosts, Fleet provides the fleetd Chrome extension which provides similar functionality as osquery on other operating systems.
## Adding ChromeOS hosts to Fleet
-Fleet provides a Chrome extension which you can install via Google Admin.
-
-> For ChromeOS hosts, the fleetd Chrome extension is installed instead of osquery. This Chrome browser extension is only supported on ChromeOS operating systems that are managed using [Google Admin](https://admin.google.com).
To learn how to add ChromeOS hosts to Fleet, visit [here](https://fleetdm.com/docs/using-fleet/adding-hosts#add-chromebooks-with-the-fleetd-chrome-extension).
+> The fleetd Chrome browser extension is supported on ChromeOS operating systems that are managed using [Google Admin](https://admin.google.com). It is not intended for non-ChromeOS hosts with the Chrome browser installed.
+
## Available tables
To see the available tables for ChromeOS, visit [here](https://fleetdm.com/tables/chrome_extensions?platformFilter=chrome).
@@ -16,7 +16,10 @@ By default, the hostname for a Chromebook host will be blank. The hostname can b
## Current Limitations in ChromeOS
- Scheduled queries are currently not available in ChromeOS
- The Fleetd Chrome extension must be force-installed by enterprise policy in order to have full access to the host's data.
-- More tables will be added in https://github.com/fleetdm/fleet/issues/11037
+- More tables that could be added:
+ - `disk_events`: https://github.com/fleetdm/fleet/issues/12405
+ - `client_certificates`: https://github.com/fleetdm/fleet/issues/12465
+ - `usb_devices`: https://github.com/fleetdm/fleet/issues/12780
## Debugging ChromeOS
To learn how to debug the Fleetd Chrome extension, visit [here](https://fleetdm.com/docs/contributing/testing-and-local-development#fleetd-chrome-extension).
diff --git a/docs/Using-Fleet/Fleet-UI.md b/docs/Using-Fleet/Fleet-UI.md
index 872798cd2a..fe3af2d7ff 100644
--- a/docs/Using-Fleet/Fleet-UI.md
+++ b/docs/Using-Fleet/Fleet-UI.md
@@ -98,5 +98,6 @@ To see all agent options, head to the [agent options documentation](https://flee
The agents may take several seconds to update because Fleet has to wait for the hosts to check in. Additionally, hosts enrolled with removed enroll secrets must properly rotate their secret to have the new changes take effect.
-
+
+
diff --git a/docs/Using-Fleet/Fleet-desktop.md b/docs/Using-Fleet/Fleet-desktop.md
index a2c1efa71d..283031ea00 100644
--- a/docs/Using-Fleet/Fleet-desktop.md
+++ b/docs/Using-Fleet/Fleet-desktop.md
@@ -59,3 +59,4 @@ This change is imperceptible to users, as clicking on the "My Device" tray item
+
diff --git a/docs/Using-Fleet/Learn-how-to-use-Fleet.md b/docs/Using-Fleet/Learn-how-to-use-Fleet.md
index b258d8c260..730646d2c0 100644
--- a/docs/Using-Fleet/Learn-how-to-use-Fleet.md
+++ b/docs/Using-Fleet/Learn-how-to-use-Fleet.md
@@ -54,3 +54,4 @@ When the query has finished, you should see several columns in the "Results" tab
- The "version" column answers: "What version of the installed operating system is on my device?"
+
diff --git a/docs/Using-Fleet/Log-destinations.md b/docs/Using-Fleet/Log-destinations.md
index b11c752a12..9114dcd737 100644
--- a/docs/Using-Fleet/Log-destinations.md
+++ b/docs/Using-Fleet/Log-destinations.md
@@ -142,4 +142,5 @@ See the [osquery logging documentation](https://osquery.readthedocs.io/en/stable
If `--logger_plugin=tls` is used with osquery clients, the following configuration can be applied on the Fleet server for handling the incoming logs.
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Using-Fleet/MDM-commands.md b/docs/Using-Fleet/MDM-commands.md
index 1792851186..ec0a2880bb 100644
--- a/docs/Using-Fleet/MDM-commands.md
+++ b/docs/Using-Fleet/MDM-commands.md
@@ -118,3 +118,4 @@ The command ID can be used to view command results as documented in [step 4 of t
+
diff --git a/docs/Using-Fleet/MDM-custom-macOS-settings.md b/docs/Using-Fleet/MDM-custom-macOS-settings.md
index 3b73fbbf1f..62289de880 100644
--- a/docs/Using-Fleet/MDM-custom-macOS-settings.md
+++ b/docs/Using-Fleet/MDM-custom-macOS-settings.md
@@ -86,16 +86,19 @@ Learn more about configuration options for hosts that aren't assigned to a team
1. In the Fleet UI, head to the **Controls > macOS settings** tab.
-2. In the top box, with "Latest," "Pending," and "Failing" statuses, click each status to view a list hosts:
+2. In the top box, with "Verified," "Verifying," "Pending," and "Failed" statuses, click each status to view a list of hosts:
-* Latest: hosts that applied the latest settings.
+* Verified: hosts that installed all configuration profiles. Fleet has verified with osquery.
-* Pending: hosts that will apply the latest settings when the hosts come online.
+* Latest: hosts that have acknowledged all MDM commands to install configuration profiles. Fleet is verifying the profiles are installed with osquery.
-* Failing: hosts that are failing to apply the latest settings.
+* Verifying: hosts that will receive MDM commands to install configuration profiles when the hosts come online.
+
+* Failed: hosts that failed to install configuration profiles.
3. In the list of hosts, click on an individual host and click the **macOS settings** item to see the status for a specific setting.
+
diff --git a/docs/Using-Fleet/MDM-disk-encryption.md b/docs/Using-Fleet/MDM-disk-encryption.md
index 89d5ab2ecc..4d0253eecb 100644
--- a/docs/Using-Fleet/MDM-disk-encryption.md
+++ b/docs/Using-Fleet/MDM-disk-encryption.md
@@ -116,3 +116,4 @@ How to reset a macOS host's password using the disk encryption key:
+
diff --git a/docs/Using-Fleet/MDM-macOS-setup.md b/docs/Using-Fleet/MDM-macOS-setup.md
index c038106d1f..222089270b 100644
--- a/docs/Using-Fleet/MDM-macOS-setup.md
+++ b/docs/Using-Fleet/MDM-macOS-setup.md
@@ -4,9 +4,9 @@ _Available in Fleet Premium_
In Fleet, you can customize the out-of-the-box macOS setup experience for your end users:
-* Require end users to authenticate with your identity provider (IdP) and agree to an end user license agreement (EULA) before they can use their new Mac
+* Require end users to authenticate with your identity provider (IdP) and agree to an end user license agreement (EULA) before they can use their new Mac.
-* Customize the macOS Setup Assistant by choosing to show or hide specific panes
+* Customize the macOS Setup Assistant by choosing to show or hide specific panes.
* Install a bootstrap package to gain full control over the setup experience by installing tools like Puppet, Munki, DEP notify, custom scrips, and more.
@@ -150,7 +150,84 @@ You should see the URL for your bootstrap package as the value for `mdm.macos_se
## macOS Setup Assistant
-> This feature is currently in development.
+When an end user unboxes their new Mac, or starts up a freshly wiped Mac, they're presented with the macOS Setup Assistant. Here they see panes that allow them to configure accessibility, appearance, and more.
+
+In Fleet, you can customize the macOS Setup Assistant by using an automatic enrollment profile.
+
+To customize the macOS Setup Assistant, we will do the following steps:
+
+1. Create an automatic enrollment profile
+2. Upload the profile to Fleet
+3. Test the custom macOS Setup Assistant
+
+### Step 1: create an automatic enrollment profile
+
+1. Download Fleet's example automatic enrollment profile by navigating to the example [here on GitHub](https://github.com/fleetdm/fleet/blob/main/mdm_profiles/setup_assistant.json) and clicking the download icon.
+
+2. Open the automatic enrollment profile and replace the `profile_name` key with your organization's name.
+
+3. View the the list of macOS Setup Assistant properties (panes) [here in Apple's Device Management documentation](https://developer.apple.com/documentation/devicemanagement/skipkeys) and choose which panes to hide from your end users.
+
+4. In your automatic enrollment profile, edit the `skip_setup_items` array so that it includes the panes you want to hide.
+
+> You can modify properties other than `skip_setup_items`. These are documented by Apple [here](https://developer.apple.com/documentation/devicemanagement/profile).
+
+### Step 2: upload the profile to Fleet
+
+1. Choose which team you want to add the automatic enrollment profile to.
+
+In this example, let's assume you have a "Workstations" team as your [default team](./MDM-setup.md#step-6-optional-set-the-default-team-for-hosts-enrolled-via-abm) in Fleet and you want to test your profile before it's used in production.
+
+To do this, we'll create a new "Workstations (canary)" team and add the automatic enrollment profile to it. Only hosts that automatically enroll to this team will see the custom macOS Setup Assistant.
+
+2. Create a `workstations-canary-config.yaml` file:
+
+```yaml
+apiVersion: v1
+kind: team
+spec:
+ team:
+ name: Workstations (canary)
+ mdm:
+ macos_setup:
+ macos_setup_assistant: ./path/to/automatic_enrollment_profile.json
+ ...
+```
+
+Learn more about team configurations options [here](./configuration-files/README.md#teams).
+
+If you want to customize the macOS Setup Assistant for hosts that automatically enroll to "No team," we'll need to create a `fleet-config.yaml` file:
+
+```yaml
+apiVersion: v1
+kind: config
+spec:
+ mdm:
+ macos_setup:
+ macos_setup_assistant: ./path/to/automatic_enrollment_profile.json
+ ...
+```
+
+Learn more about configuration options for hosts that aren't assigned to a team [here](./configuration-files/README.md#organization-settings).
+
+3. Add an `mdm.macos_setup.macos_setup_assistant` key to your YAML document. This key accepts a path to your automatic enrollment profile.
+
+4. Run the `fleetctl apply -f workstations-canary-config.yml` command to upload the automatic enrollment profile to Fleet.
+
+### Step 3: test the custom macOS Setup Assistant
+
+Testing requires a test Mac that is present in your Apple Business Manager (ABM) account. We will wipe this Mac and use it to test the custom macOS Setup Assistant.
+
+1. Wipe the test Mac by selecting the Apple icon in top left corner of the screen, selecting **System Settings** or **System Preference**, and searching for "Erase all content and settings." Select **Erase All Content and Settings**.
+
+2. In Fleet, navigate to the Hosts page and find your Mac. Make sure that the host's **MDM status** is set to "Pending."
+
+> New Macs purchased through Apple Business Manager appear in Fleet with MDM status set to "Pending." Learn more about these hosts [here](./MDM-setup.md#pending-hosts).
+
+3. Transfer this host to the "Workstations (canary)" team by selecting the checkbox to the left of the host and selecting **Transfer** at the top of the table. In the modal, choose the Workstations (canary) team and select **Transfer**.
+
+4. Boot up your test Mac and complete the custom out-of-the-box setup experience.
+
diff --git a/docs/Using-Fleet/MDM-macOS-updates.md b/docs/Using-Fleet/MDM-macOS-updates.md
index a3ef6b7eaf..21e132ac7a 100644
--- a/docs/Using-Fleet/MDM-macOS-updates.md
+++ b/docs/Using-Fleet/MDM-macOS-updates.md
@@ -45,7 +45,15 @@ On Intel Macs, Fleet triggers step 1 (downloading the macOS update) programmatic
Step 2 (installing the update) always requires end user action.
-### Known issue
+### Known issues
+
+#### Apple Rapid Security Responses (RSRs)
+
+Currently, end user macOS update reminders via Nudge don't support RSR versions (ex. "13.4.1 (a)").
+
+You can use custom MDM commands in Fleet to trigger built-in macOS update reminders for RSRs. Learn how [here](#end-user-macos-update-via-built-in-macos-notifications).
+
+#### Mac is up to date
Sometimes after the end user clicks "update" on the Nudge window, the end user's Mac will say that macOS is up to date when it isn't. This known issue can create a frustrating experience for the end user. Ask the end user to follow the steps below to troubleshoot:
@@ -63,7 +71,94 @@ Sometimes after the end user clicks "update" on the Nudge window, the end user's
## End user macOS update via built-in macOS notifications
-Built-in macOS update reminders are available for all Fleet instances. To trigger these reminders, run the ["Schedule an OS update" MDM command](https://developer.apple.com/documentation/devicemanagement/schedule_an_os_update).
+Built-in macOS update reminders are available in Fleet Free and Fleet Premium.
+
+To trigger these reminders, we will do the following steps:
+
+1. Force a macOS update scan
+
+2. List available macOS updates
+
+3. Trigger macOS update reminder
+
+### Step 1: force a macOS update scan
+
+Use the request payload below when running a custom MDM command with Fleet. Documentation on how to run a custom command is [here](./MDM-commands#custom-commands).
+
+Request payload:
+
+```xml
+
+
+
+
+ Command
+
+ ForceUpdateScan
+
+ RequestType
+ ScheduleOSUpdateScan
+
+
+
+```
+
+### Step 2: list available macOS updates
+
+1. Run another custom MDM command using the request payload below.
+
+Request payload:
+
+```xml
+
+
+
+
+ Command
+
+ RequestType
+ AvailableOSUpdates
+
+
+
+```
+
+2. Copy the `ProductKey` from the command's results. Documentation on how to view a command's results is [here](./MDM-commands#step-4-view-the-commands-results).
+
+Example product key: `MSU_UPDATE_22F770820d_patch_13.4.1_rsr`
+
+### Step 3: trigger macOS update reminder
+
+Run another custom MDM command using the request payload below. Replace the product key with your product key.
+
+> This payload will trigger the "Install ASAP" behavior which displays a macOS notification with a 60 seconds timer before the Mac automatically restarts. The end user can dismiss the timer. To trigger different behavior, update the `InstallAction`. Options are documented by Apple [here](https://developer.apple.com/documentation/devicemanagement/scheduleosupdatecommand/command/updatesitem).
+
+Request payload:
+
+```xml
+
+
+
+
+ Command
+
+ RequestType
+ ScheduleOSUpdate
+ Updates
+
+
+ InstallAction
+ InstallASAP
+ ProductKey
+ MSU_UPDATE_22F770820d_patch_13.4.1_rsr
+
+
+
+
+
+```
+
+
diff --git a/docs/Using-Fleet/MDM-migration-guide.md b/docs/Using-Fleet/MDM-migration-guide.md
index 9489830e79..a8757262e7 100644
--- a/docs/Using-Fleet/MDM-migration-guide.md
+++ b/docs/Using-Fleet/MDM-migration-guide.md
@@ -117,3 +117,4 @@ Want to know what your organization can see? Read about [transparency](https://f
+
diff --git a/docs/Using-Fleet/MDM-setup.md b/docs/Using-Fleet/MDM-setup.md
index 332d101cad..eb68a3484f 100644
--- a/docs/Using-Fleet/MDM-setup.md
+++ b/docs/Using-Fleet/MDM-setup.md
@@ -282,3 +282,4 @@ To renew the token:
+
diff --git a/docs/Using-Fleet/Monitoring-Fleet.md b/docs/Using-Fleet/Monitoring-Fleet.md
index de9d80ffc0..7b6f575118 100644
--- a/docs/Using-Fleet/Monitoring-Fleet.md
+++ b/docs/Using-Fleet/Monitoring-Fleet.md
@@ -102,3 +102,4 @@ fleetctl debug archive --context server-a
The `fleetctl debug archive` command retrieves information generated by Go's [`net/http/pprof`](https://golang.org/pkg/net/http/pprof/) package. In most scenarios this should not include sensitive information, however it does include command line arguments to the Fleet server. If the Fleet server receives sensitive credentials via CLI argument (not environment variables or config file), this information should be scrubbed from the archive in the `cmdline` file.
+
diff --git a/docs/Using-Fleet/Osquery-process.md b/docs/Using-Fleet/Osquery-process.md
index 2f1cfeba5d..76aa4e3f47 100644
--- a/docs/Using-Fleet/Osquery-process.md
+++ b/docs/Using-Fleet/Osquery-process.md
@@ -25,4 +25,5 @@ If the managed extension is `Non-existent` (either because it was `Non-existent`
Lastly, we check the state of the watcher process itself. If it is deemed unhealthy because of resource contention, then the osquery process is shut down.
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Using-Fleet/Permissions.md b/docs/Using-Fleet/Permissions.md
index 8a6d2d723c..5aa124d52a 100644
--- a/docs/Using-Fleet/Permissions.md
+++ b/docs/Using-Fleet/Permissions.md
@@ -155,3 +155,4 @@ Users that are members of multiple teams can be assigned different roles for eac
\** Team observers can view all queries but the UI and fleetctl only list the ones they can run (**observer can run**).
+
diff --git a/docs/Using-Fleet/Process-File-Events.md b/docs/Using-Fleet/Process-File-Events.md
index 086c6d2aa4..dbc3a18c6f 100644
--- a/docs/Using-Fleet/Process-File-Events.md
+++ b/docs/Using-Fleet/Process-File-Events.md
@@ -176,4 +176,5 @@ auditdnetlink.cpp:354 The Audit publisher has throttled reading records from Net
Some events might get lost due to system load or low CPU/memory resources.
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Using-Fleet/REST-API.md b/docs/Using-Fleet/REST-API.md
index 018fb8e40b..8dd5b74628 100644
--- a/docs/Using-Fleet/REST-API.md
+++ b/docs/Using-Fleet/REST-API.md
@@ -3122,6 +3122,46 @@ Retrieves the disk encryption key for a host.
}
```
+### Get configuration profiles assigned to a host
+
+Requires Fleet's MDM properly [enabled and configured](./Mobile-device-management.md).
+
+Retrieves a list of the configuration profiles assigned to a host.
+
+`GET /api/v1/fleet/mdm/hosts/:id/profiles`
+
+#### Parameters
+
+| Name | Type | In | Description |
+| ---- | ------- | ---- | -------------------------------- |
+| id | integer | path | **Required**. The ID of the host |
+
+
+#### Example
+
+`GET /api/v1/fleet/mdm/hosts/8/profiles`
+
+##### Default response
+
+`Status: 200`
+
+```json
+{
+ "host_id": 8,
+ "profiles": [
+ {
+ "profile_id": 1337,
+ "team_id": 0,
+ "name": "Example profile",
+ "identifier": "com.example.profile",
+ "created_at": "2023-03-31T00:00:00Z",
+ "updated_at": "2023-03-31T00:00:00Z",
+ "checksum": "dGVzdAo="
+ }
+ ]
+}
+```
+
---
@@ -3701,12 +3741,13 @@ List all configuration profiles for macOS hosts enrolled to Fleet's MDM that are
{
"profiles": [
{
- "profile_id": 1337,
- "team_id": 0,
- "name": "Example profile",
- "identifier": "com.example.profile",
- "created_at": "2023-03-31T00:00:00Z",
- "updated_at": "2023-03-31T00:00:00Z"
+ "profile_id": 1337,
+ "team_id": 0,
+ "name": "Example profile",
+ "identifier": "com.example.profile",
+ "created_at": "2023-03-31T00:00:00Z",
+ "updated_at": "2023-03-31T00:00:00Z",
+ "checksum": "dGVzdAo="
}
]
}
@@ -7572,3 +7613,4 @@ Response:
---
+
\ No newline at end of file
diff --git a/docs/Using-Fleet/Security-audits.md b/docs/Using-Fleet/Security-audits.md
index 397508a391..b105c74608 100644
--- a/docs/Using-Fleet/Security-audits.md
+++ b/docs/Using-Fleet/Security-audits.md
@@ -224,3 +224,5 @@ Our goal with this audit was to ensure that our auto-updater mechanism, built wi
improvements to make it more robust and resilient to compromise.
+
+
diff --git a/docs/Using-Fleet/Supported-browsers.md b/docs/Using-Fleet/Supported-browsers.md
index 252669831a..3f941f9c8b 100644
--- a/docs/Using-Fleet/Supported-browsers.md
+++ b/docs/Using-Fleet/Supported-browsers.md
@@ -24,3 +24,4 @@ We test each browser on Windows whenever possible, because our engineering team
> - The Fleet user interface [may not be fully supported](https://github.com/fleetdm/fleet/issues/969) in Google Chrome when the browser is running on ChromeOS
+
diff --git a/docs/Using-Fleet/Supported-host-operating-systems.md b/docs/Using-Fleet/Supported-host-operating-systems.md
index af6babe2fb..44c3b409d1 100644
--- a/docs/Using-Fleet/Supported-host-operating-systems.md
+++ b/docs/Using-Fleet/Supported-host-operating-systems.md
@@ -27,3 +27,4 @@ If you aren't sure what version of `glibc` your distribution is using, [DistroWa
+
diff --git a/docs/Using-Fleet/Teams.md b/docs/Using-Fleet/Teams.md
index 275e3005ce..9006277bac 100644
--- a/docs/Using-Fleet/Teams.md
+++ b/docs/Using-Fleet/Teams.md
@@ -130,4 +130,5 @@ To delete a team:
3. On the right side, select "Delete team" and confirm the action.
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Using-Fleet/Troubleshooting-live-queries.md b/docs/Using-Fleet/Troubleshooting-live-queries.md
index d2737662ea..ab180cb56d 100644
--- a/docs/Using-Fleet/Troubleshooting-live-queries.md
+++ b/docs/Using-Fleet/Troubleshooting-live-queries.md
@@ -137,4 +137,5 @@ fleetctl query \
If this works and the browser is not working then it might be a rendering issue on the browser.
You should also try running the live query on different browsers.
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/docs/Using-Fleet/Usage-statistics.md b/docs/Using-Fleet/Usage-statistics.md
index ceddde34d3..87469f29ed 100644
--- a/docs/Using-Fleet/Usage-statistics.md
+++ b/docs/Using-Fleet/Usage-statistics.md
@@ -127,3 +127,4 @@ To disable usage statistics:
3. Uncheck the "Enable usage statistics" checkbox and then select "Update settings."
+
diff --git a/docs/Using-Fleet/Vulnerability-Processing.md b/docs/Using-Fleet/Vulnerability-Processing.md
index a1e8bed259..178dfc690e 100644
--- a/docs/Using-Fleet/Vulnerability-Processing.md
+++ b/docs/Using-Fleet/Vulnerability-Processing.md
@@ -409,3 +409,4 @@ The CPE translation. Used to match CPEs in the CPE database. Fields are are AND'
Once we have a good CPE, we can match it against the CVE database. We download the data streams locally and match each CPE to the whole list. The matching is done using the [nvdtools implementation](https://github.com/facebookincubator/nvdtools).
+
diff --git a/docs/Using-Fleet/configuration-files/README.md b/docs/Using-Fleet/configuration-files/README.md
index 4fe3cbf074..d98a650c72 100644
--- a/docs/Using-Fleet/configuration-files/README.md
+++ b/docs/Using-Fleet/configuration-files/README.md
@@ -290,12 +290,10 @@ integrations
webhook_settings
```
-You can bypass these errors by removing the key from your YAML or adding the `--force` flag. This flag will force application of the changes without validation. Proceed with caution.
+You can bypass these errors by removing the key from your YAML or adding the `--force` flag. This flag will apply the changes without validation and should be used with caution.
### Mobile device management (MDM) settings for teams
-> MDM features are not ready for production and are currently in development. These features are disabled by default.
-
The `mdm` section of this configuration YAML lets you control MDM settings for each team in Fleet.
To specify Team MDM configuration, as opposed to [Organization-wide MDM configuration](#mobile-device-management-mdm-settings), follow the below YAML format. Note the `kind: team` field, as well as the `name` and `mdm` fields under `team`.
@@ -1360,8 +1358,6 @@ agent_options:
#### Mobile device management (MDM) settings
-> MDM features are not ready for production and are currently in development. These features are disabled by default.
-
The `mdm` section of the configuration YAML lets you control MDM settings in Fleet.
##### mdm.apple_bm_default_team
@@ -1379,6 +1375,8 @@ Set name of default team to use with Apple Business Manager.
##### mdm.windows_enabled_and_configured
+> Windows MDM features are not ready for production and are currently in development. These features are disabled by default.
+
Enables or disables Windows MDM support.
- Default value: false
@@ -1467,3 +1465,5 @@ If you're using Fleet Premium, this enforces disk encryption on all hosts assign
#### Advanced configuration
> **Note:** More settings are included in the [contributor documentation](https://fleetdm.com/docs/contributing/configuration-for-contributors). It's possible, although not recommended, to configure these settings in the YAML configuration file.
+
+
diff --git a/docs/Using-Fleet/fleetctl-CLI.md b/docs/Using-Fleet/fleetctl-CLI.md
index 7214499bcb..d833f8dba1 100644
--- a/docs/Using-Fleet/fleetctl-CLI.md
+++ b/docs/Using-Fleet/fleetctl-CLI.md
@@ -432,3 +432,4 @@ This will generate a `tar.gz` file with:
- Files containing database-specific information.
+
diff --git a/ee/server/service/devices.go b/ee/server/service/devices.go
index b2b5370792..f8dab0f3cc 100644
--- a/ee/server/service/devices.go
+++ b/ee/server/service/devices.go
@@ -110,6 +110,7 @@ func (svc *Service) GetFleetDesktopSummary(ctx context.Context) (fleet.DesktopSu
// organization information
sum.Config.OrgInfo.OrgName = appCfg.OrgInfo.OrgName
sum.Config.OrgInfo.OrgLogoURL = appCfg.OrgInfo.OrgLogoURL
+ sum.Config.OrgInfo.OrgLogoURLLightBackground = appCfg.OrgInfo.OrgLogoURLLightBackground
sum.Config.OrgInfo.ContactURL = appCfg.OrgInfo.ContactURL
// mdm information
diff --git a/ee/server/service/mdm.go b/ee/server/service/mdm.go
index 0c1484801c..89a9729b25 100644
--- a/ee/server/service/mdm.go
+++ b/ee/server/service/mdm.go
@@ -4,16 +4,15 @@ import (
"bytes"
"context"
"crypto/sha256"
+ "database/sql"
"encoding/base64"
"encoding/json"
"errors"
- "fmt"
"io"
"net/http"
"net/url"
"sort"
"strings"
- "time"
"github.com/fleetdm/fleet/v4/pkg/file"
"github.com/fleetdm/fleet/v4/server/authz"
@@ -147,6 +146,30 @@ func (svc *Service) MDMAppleEraseDevice(ctx context.Context, hostID uint) error
return nil
}
+func (svc *Service) MDMListHostConfigurationProfiles(ctx context.Context, hostID uint) ([]*fleet.MDMAppleConfigProfile, error) {
+ if err := svc.authz.Authorize(ctx, &fleet.Host{}, fleet.ActionList); err != nil {
+ return nil, err
+ }
+
+ host, err := svc.ds.HostLite(ctx, hostID)
+ if err != nil {
+ return nil, ctxerr.Wrap(ctx, err, "find host to list profiles")
+ }
+
+ var tmID uint
+ if host.TeamID != nil {
+ tmID = *host.TeamID
+ }
+
+ // NOTE: the service method also does all the right authorization checks
+ sums, err := svc.ListMDMAppleConfigProfiles(ctx, tmID)
+ if err != nil {
+ return nil, ctxerr.Wrap(ctx, err, "list config profiles")
+ }
+
+ return sums, nil
+}
+
func (svc *Service) MDMAppleEnableFileVaultAndEscrow(ctx context.Context, teamID *uint) error {
cert, _, _, err := svc.config.MDM.AppleSCEP()
if err != nil {
@@ -786,46 +809,35 @@ func (svc *Service) MDMAppleMatchPreassignment(ctx context.Context, externalHost
return err
}
- // Collect the profiles' hashes and look for a team with exactly that set.
- // Also collect the profiles' groups in case we need to create a new team,
+ // Collect the profiles' groups in case we need to create a new team,
// and the list of raw profiles bytes.
- hashes, groups, rawProfiles := make([]string, 0, len(profs.Profiles)),
- make([]string, 0, len(profs.Profiles)),
+ groups, rawProfiles := make([]string, 0, len(profs.Profiles)),
make([][]byte, 0, len(profs.Profiles))
for _, prof := range profs.Profiles {
- hashes = append(hashes, prof.HexMD5Hash)
- rawProfiles = append(rawProfiles, prof.Profile)
if prof.Group != "" {
groups = append(groups, prof.Group)
}
- }
- // find a team with exactly that set of profiles
- teamIDs, err := svc.ds.MatchMDMAppleConfigProfiles(ctx, hashes)
- if err != nil {
- return err
+ if !prof.Exclude {
+ rawProfiles = append(rawProfiles, prof.Profile)
+ }
}
+
+ teamName := teamNameFromPreassignGroups(groups)
+ team, err := svc.ds.TeamByName(ctx, teamName)
- var targetTeamID uint
- if len(teamIDs) > 0 {
- // if the host is already in one of those valid teams, nothing to do.
- if host.TeamID != nil {
- for _, tmID := range teamIDs {
- if *host.TeamID == tmID {
- return nil
- }
- }
+ if err != nil {
+ // TODO: update to use fleet.IsNotFound once
+ // https://github.com/fleetdm/fleet/pull/12620 is merged
+ if !errors.Is(err, sql.ErrNoRows) {
+ return err
}
- // else assign the host to the first valid team
- targetTeamID = teamIDs[0]
- } else {
// Create a new team with this set of profiles. Creating via the service
// call so that it properly assigns the agent options and creates audit
// activities, etc.
- teamName := teamNameFromPreassignGroups(groups)
payload := fleet.TeamPayload{Name: &teamName}
- tm, err := svc.NewTeam(ctx, payload)
+ team, err = svc.NewTeam(ctx, payload)
if err != nil {
return err
}
@@ -842,27 +854,24 @@ func (svc *Service) MDMAppleMatchPreassignment(ctx context.Context, externalHost
// TODO: seems like we don't support enabling disk encryption
// on team creation?
// see https://github.com/fleetdm/fleet/issues/12220
- tm, err = svc.ModifyTeam(ctx, tm.ID, payload)
+ team, err = svc.ModifyTeam(ctx, team.ID, payload)
if err != nil {
return err
}
+ }
- // create profiles for that team via the service call, so that uniqueness
- // of profile identifier/name is verified, activity created, etc.
- // NOTE: this will use the read replica to load the team, which was just
- // created above, could lead to not found issues with slow replication.
- if err := svc.BatchSetMDMAppleProfiles(ctx, &tm.ID, nil, rawProfiles, false); err != nil {
- return err
- }
-
- targetTeamID = tm.ID
+ // create profiles for that team via the service call, so that uniqueness
+ // of profile identifier/name is verified, activity created, etc.
+ if err := svc.BatchSetMDMAppleProfiles(ctx, &team.ID, nil, rawProfiles, false); err != nil {
+ return err
}
// assign host to that team via the service call, which will trigger
// deployment of the profiles.
- if err := svc.AddHostsToTeam(ctx, &targetTeamID, []uint{host.ID}); err != nil {
+ if err := svc.AddHostsToTeam(ctx, &team.ID, []uint{host.ID}); err != nil {
return err
}
+
return nil
}
@@ -870,8 +879,7 @@ func (svc *Service) MDMAppleMatchPreassignment(ctx context.Context, externalHost
// created to match the set of profiles preassigned to a host. The team name is
// derived from the "group" field provided with each request to pre-assign a
// profile to a host (in fleet.MDMApplePreassignProfilePayload). That field is
-// optional, and empty groups are ignored. The current timestamp is appended to
-// the team's name to help avoid duplicates.
+// optional, and empty groups are ignored.
func teamNameFromPreassignGroups(groups []string) string {
const defaultName = "default"
@@ -891,5 +899,5 @@ func teamNameFromPreassignGroups(groups []string) string {
groups = []string{defaultName}
}
- return fmt.Sprintf("%s (%s)", strings.Join(groups, " - "), time.Now().UTC().Format("2006-01-02:15:04:05.000"))
+ return strings.Join(groups, " - ")
}
diff --git a/ee/server/service/mdm_profiles.go b/ee/server/service/mdm_profiles.go
index 6c7782fe29..fba921ba0f 100644
--- a/ee/server/service/mdm_profiles.go
+++ b/ee/server/service/mdm_profiles.go
@@ -30,6 +30,8 @@ var fileVaultProfileTemplate = template.Must(template.New("").Option("missingkey
1ShowRecoveryKey
+ DeferForceAtUserLoginMaxBypassAttempts
+ 1EncryptCertPayloadUUID
@@ -64,17 +66,17 @@ var fileVaultProfileTemplate = template.Must(template.New("").Option("missingkey
1
- dontAllowFDEDisable
-
- PayloadIdentifier
- com.apple.MCX.62024f29-105E-497A-A724-1D5BA4D9E854
- PayloadType
- com.apple.MCX
- PayloadUUID
- 62024f29-105E-497A-A724-1D5BA4D9E854
- PayloadVersion
- 1
-
+ dontAllowFDEDisable
+
+ PayloadIdentifier
+ com.apple.MCX.62024f29-105E-497A-A724-1D5BA4D9E854
+ PayloadType
+ com.apple.MCX
+ PayloadUUID
+ 62024f29-105E-497A-A724-1D5BA4D9E854
+ PayloadVersion
+ 1
+
PayloadDisplayNameDisk encryption
diff --git a/ee/server/service/teams.go b/ee/server/service/teams.go
index 524c7eb3ef..4d0119ccca 100644
--- a/ee/server/service/teams.go
+++ b/ee/server/service/teams.go
@@ -3,9 +3,7 @@ package service
import (
"bytes"
"context"
- "database/sql"
"encoding/json"
- "errors"
"fmt"
"net/http"
@@ -605,14 +603,6 @@ func (svc *Service) teamByIDOrName(ctx context.Context, id *uint, name *string)
} else if name != nil {
tm, err = svc.ds.TeamByName(ctx, *name)
if err != nil {
- if errors.Is(err, sql.ErrNoRows) {
- // this should really be handled in TeamByName so that it returns a
- // notFound error as is usually the case for this scenario, but
- // changing it causes a number of test failures that indicates this
- // might be tricky and even maybe a breaking change in some places. For
- // now, handling it here.
- return nil, notFoundError{}
- }
return nil, err
}
}
@@ -635,7 +625,7 @@ func (svc *Service) checkAuthorizationForTeams(ctx context.Context, specs []*fle
for _, spec := range specs {
team, err := svc.ds.TeamByName(ctx, spec.Name)
if err != nil {
- if err := ctxerr.Cause(err); err == sql.ErrNoRows {
+ if fleet.IsNotFound(err) {
// Can the user create a new team?
if err := svc.authz.Authorize(ctx, &fleet.Team{}, fleet.ActionWrite); err != nil {
return err
@@ -688,7 +678,7 @@ func (svc *Service) ApplyTeamSpecs(ctx context.Context, specs []*fleet.TeamSpec,
switch {
case err == nil:
// OK
- case ctxerr.Cause(err) == sql.ErrNoRows:
+ case fleet.IsNotFound(err):
if spec.Name == "" {
return nil, fleet.NewInvalidArgumentError("name", "name may not be empty")
}
diff --git a/ee/tools/puppet/fleetdm/README.md b/ee/tools/puppet/fleetdm/README.md
index 126b17a852..069a220bba 100644
--- a/ee/tools/puppet/fleetdm/README.md
+++ b/ee/tools/puppet/fleetdm/README.md
@@ -60,15 +60,50 @@ node default {
}
```
+The `group` parameter is used to create/match profiles with teams in
+Fleet. In the example above, all devices will be assigned to a team named
+`workstations`.
+
+You can use this feature along with the `ensure` param to create teams that
+**don't** contain specific profiles, for example given the following manifest:
+
+```pp
+node default {
+ fleetdm::profile { 'com.apple.universalaccess':
+ template => template('fleetdm/profile-template.mobileconfig.erb'),
+ group => 'workstations',
+ }
+
+ if $facts['architecture'] == 'x86_64' {
+ fleetdm::profile { 'my.arm.only.profile':
+ ensure => absent,
+ template => template('fleetdm/my-arm-only-profile.mobileconfig.erb'),
+ group => 'amd64',
+ }
+ } else {
+ fleetdm::profile { 'my.arm.only.profile':
+ template => template('fleetdm/my-arm-only-profile.mobileconfig.erb'),
+ group => 'workstations',
+ }
+ }
+}
+```
+
+Assuming you have devices with both architectures checking in, you'll end up
+with the following two teams in Fleet:
+
+- `workstations`: with two profiles, `com.apple.universalaccess` and `my.arm.only.profile`
+- `workstations - amd64`: with only one profile, `com.apple.universalaccess`
+
### Sending a custom MDM Command
You can use the `fleetdm::command_xml` function to send any custom MDM command to the device:
-```
- $host_uuid = $facts['system_profiler']['hardware_uuid']
- $command_uuid = generate('/usr/bin/uuidgen').strip
+```pp
+$host_uuid = $facts['system_profiler']['hardware_uuid']
+$command_uuid = generate('/usr/bin/uuidgen').strip
- $xml_data = "
+$xml_data = "
@@ -82,12 +117,12 @@ You can use the `fleetdm::command_xml` function to send any custom MDM command t
"
- $response = fleetdm::command_xml($host_uuid, $xml_data)
- $err = $response['error']
+$response = fleetdm::command_xml($host_uuid, $xml_data)
+$err = $response['error']
- if $err != '' {
- notify { "Error sending MDM command: ${err}": }
- }
+if $err != '' {
+ notify { "Error sending MDM command: ${err}": }
+}
```
### Releasing a device from await configuration
diff --git a/ee/tools/puppet/fleetdm/examples/multiple-teams.pp b/ee/tools/puppet/fleetdm/examples/multiple-teams.pp
index bfeb583ded..699e19eb35 100644
--- a/ee/tools/puppet/fleetdm/examples/multiple-teams.pp
+++ b/ee/tools/puppet/fleetdm/examples/multiple-teams.pp
@@ -1,10 +1,10 @@
node default {
- fleetdm::profile { 'cis.macOSBenchmark.section2.BluetoothSharing':
+ fleetdm::profile { 'com.apple.SoftwareUpdate':
template => template('fleetdm/automatic_updates.mobileconfig.erb'),
group => 'base',
}
- fleetdm::profile { 'com.apple.SoftwareUpdate':
+ fleetdm::profile { 'cis.macOSBenchmark.section2.BluetoothSharing':
template => template('fleetdm/disable_bluetooth_file_sharing.mobileconfig.erb'),
group => 'workstations',
}
diff --git a/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/preassign_profile.rb b/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/preassign_profile.rb
index 0e5b0837c6..1c33e1626f 100644
--- a/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/preassign_profile.rb
+++ b/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/preassign_profile.rb
@@ -8,19 +8,29 @@ Puppet::Functions.create_function(:"fleetdm::preassign_profile") do
param 'String', :host_uuid
param 'String', :template
optional_param 'String', :group
+ optional_param 'Enum[absent, present]', :ensure
end
- def preassign_profile(profile_identifier, host_uuid, template, group = 'default')
- host = call_function('lookup', 'fleetdm::host')
- token = call_function('lookup', 'fleetdm::token')
- client = Puppet::Util::FleetClient.new(host, token)
+ def preassign_profile(profile_identifier, host_uuid, template, group = 'default', ensure_profile = 'present')
+ client = Puppet::Util::FleetClient.instance
run_identifier = "#{closure_scope.catalog.catalog_uuid}-#{Puppet[:node_name_value]}"
- response = client.preassign_profile(run_identifier, host_uuid, template, group)
+ response = client.preassign_profile(run_identifier, host_uuid, template, group, ensure_profile)
if response['error'].empty?
- Puppet.info("successfully pre-assigned profile #{profile_identifier}")
+ base64_checksum = Digest::MD5.base64digest(template)
+ host = client.get_host_by_identifier(host_uuid)
+ host_profiles = client.get_host_profiles(host['body']['host']['id'])
+
+ if host_profiles['error'].empty?
+ Puppet.info("successfully pre-set profile #{profile_identifier} as #{ensure_profile}")
+
+ has_profile = host_profiles['body']['profiles'].any? { |p| p['checksum'] == base64_checksum }
+ if (has_profile && ensure_profile == 'absent') || (!has_profile && ensure_profile == 'present')
+ response['resource_changed'] = true
+ end
+ end
else
- Puppet.err("error pre-assigning profile #{profile_identifier}: #{response['error']} \n\n #{template}")
+ Puppet.err("error pre-setting profile #{profile_identifier} (ensure #{ensure_profile}): #{response['error']} \n\n #{template}")
end
response
diff --git a/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/release_device.rb b/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/release_device.rb
index 7cc7da580f..7c88936038 100644
--- a/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/release_device.rb
+++ b/ee/tools/puppet/fleetdm/lib/puppet/functions/fleetdm/release_device.rb
@@ -29,9 +29,7 @@ Puppet::Functions.create_function(:"fleetdm::release_device") do
COMMAND_TEMPLATE
- host = call_function('lookup', 'fleetdm::host')
- token = call_function('lookup', 'fleetdm::token')
- client = Puppet::Util::FleetClient.new(host, token)
+ client = Puppet::Util::FleetClient.instance
response = client.send_mdm_command(uuid, command_xml)
if response['error'].empty?
diff --git a/ee/tools/puppet/fleetdm/lib/puppet/reports/fleetdm.rb b/ee/tools/puppet/fleetdm/lib/puppet/reports/fleetdm.rb
index 2de2d7698f..06d353bb4b 100644
--- a/ee/tools/puppet/fleetdm/lib/puppet/reports/fleetdm.rb
+++ b/ee/tools/puppet/fleetdm/lib/puppet/reports/fleetdm.rb
@@ -8,15 +8,8 @@ Puppet::Reports.register_report(:fleetdm) do
def process
return if noop
+ client = Puppet::Util::FleetClient.instance
node_name = Puppet[:node_name_value]
- node = Puppet::Node.new(node_name)
- compiler = Puppet::Parser::Compiler.new(node)
- scope = Puppet::Parser::Scope.new(compiler)
- lookup_invocation = Puppet::Pops::Lookup::Invocation.new(scope, {}, {}, nil)
- host = Puppet::Pops::Lookup.lookup('fleetdm::host', nil, '', false, nil, lookup_invocation)
- token = Puppet::Pops::Lookup.lookup('fleetdm::token', nil, '', false, nil, lookup_invocation)
-
- client = Puppet::Util::FleetClient.new(host, token)
run_identifier = "#{catalog_uuid}-#{node_name}"
response = client.match_profiles(run_identifier)
diff --git a/ee/tools/puppet/fleetdm/lib/puppet/util/fleet_client.rb b/ee/tools/puppet/fleetdm/lib/puppet/util/fleet_client.rb
index d39fd81a7b..603b0ae19c 100644
--- a/ee/tools/puppet/fleetdm/lib/puppet/util/fleet_client.rb
+++ b/ee/tools/puppet/fleetdm/lib/puppet/util/fleet_client.rb
@@ -7,9 +7,33 @@ require 'hiera_puppet'
module Puppet::Util
# FleetClient provides an interface for making HTTP requests to a Fleet server.
class FleetClient
- def initialize(host, token)
- @host = host
- @token = token
+ include Singleton
+
+ # NOTE: the Puppet server supports [multithread mode][1], but it's a beta
+ # feature subject to change. Still adding a mutex to control instances and
+ # the cache just in case.
+ #
+ # [1]: https://www.puppet.com/docs/puppet/8/server/config_file_puppetserver.html
+ @instance_mutex = Mutex.new
+
+ def self.instance
+ return @instance if @instance
+ @instance_mutex.synchronize do
+ @instance ||= new
+ end
+ @instance
+ end
+
+ def initialize
+ node_name = Puppet[:node_name_value]
+ node = Puppet::Node.new(node_name)
+ compiler = Puppet::Parser::Compiler.new(node)
+ scope = Puppet::Parser::Scope.new(compiler)
+ lookup_invocation = Puppet::Pops::Lookup::Invocation.new(scope, {}, {}, nil)
+ @host = Puppet::Pops::Lookup.lookup('fleetdm::host', nil, '', false, nil, lookup_invocation)
+ @token = Puppet::Pops::Lookup.lookup('fleetdm::token', nil, '', false, nil, lookup_invocation)
+ @cache = {}
+ @cache_mutex = Mutex.new
end
# Pre-assigns a profile to a host. Note that the profile assignment is not
@@ -20,14 +44,16 @@ module Puppet::Util
# @param profile_xml [String] Raw XML with the configuration profile.
# @param group [String] Used to construct a team name.
# @return [Hash] The response status code, headers, and body.
- def preassign_profile(run_identifier, uuid, profile_xml, group)
- post(
- '/api/latest/fleet/mdm/apple/profiles/preassign',
- {
+ def preassign_profile(run_identifier, uuid, profile_xml, group, ensure_profile)
+ req(
+ method: :post,
+ path: '/api/latest/fleet/mdm/apple/profiles/preassign',
+ body: {
'external_host_identifier' => run_identifier,
'host_uuid' => uuid,
'profile' => Base64.strict_encode64(profile_xml),
'group' => group,
+ 'exclude' => ensure_profile == 'absent',
},
)
end
@@ -42,10 +68,11 @@ module Puppet::Util
# pre-assigned profiles.
# @return [Hash] The response status code, headers, and body.
def match_profiles(run_identifier)
- post('/api/latest/fleet/mdm/apple/profiles/match',
- {
- 'external_host_identifier' => run_identifier,
- })
+ req(
+ method: :post,
+ path: '/api/latest/fleet/mdm/apple/profiles/match',
+ body: { 'external_host_identifier' => run_identifier },
+ )
end
# Sends an MDM command to the host with the specified UUID.
@@ -54,8 +81,8 @@ module Puppet::Util
# @param command_xml [String] Raw XML with the MDM command.
# @return [Hash] The response status code, headers, and body.
def send_mdm_command(uuid, command_xml)
- post('/api/latest/fleet/mdm/apple/enqueue',
- {
+ req(method: :post, path: '/api/latest/fleet/mdm/apple/enqueue',
+ body: {
# For some reason, the enqueue function expects the command to be
# base64 encoded using _raw encoding_ (without padding, as defined in RFC
# 4648 section 3.2)
@@ -67,20 +94,50 @@ module Puppet::Util
})
end
- # Sends an HTTP POST request to the specified path.
+ # Get profiles assigned to the host.
#
- # @param path [String] The path of the resource to post to.
- # @param body [Object] (optional) The request body to send.
- # @param headers [Hash] (optional) Additional headers to include in the request.
+ # @param host_id [Number] Fleet's internal host id.
# @return [Hash] The response status code, headers, and body.
- def post(path, body = nil, headers = {})
+ def get_host_profiles(host_id)
+ req(method: :get, path: "/api/latest/fleet/mdm/hosts/#{host_id}/profiles", cached: false)
+ end
+
+ # Gets host details by host identifier.
+ #
+ # @param identifier [String] The host identifier, can be
+ # osquery_host_identifier, node_key, UUID, or hostname.
+ # @return [Hash] The response status code, headers, and body.
+ def get_host_by_identifier(identifier)
+ req(method: :get, path: "/api/latest/fleet/hosts/identifier/#{identifier}", cached: true)
+ end
+
+ private
+
+ def req(method: :get, path: '', body: nil, headers: {}, cached: false)
+ if cached
+ @cache_mutex.synchronize do
+ unless @cache[path].nil?
+ return @cache[path]
+ end
+ end
+ end
+
out = { 'error' => '' }
uri = URI.parse("#{@host}#{path}")
+ uri.path.squeeze! '/'
+ uri.path.chomp! '/'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == 'https'
- request = Net::HTTP::Post.new(uri.request_uri)
+ case method
+ when :get
+ request = Net::HTTP::Get.new(uri.request_uri)
+ when :post
+ request = Net::HTTP::Post.new(uri.request_uri)
+ else
+ throw "HTTP method #{method} not implemented"
+ end
headers['Authorization'] = "Bearer #{@token}"
headers.each { |key, value| request[key] = value }
@@ -89,6 +146,12 @@ module Puppet::Util
begin
response = http.request(request)
out = parse_response(response)
+
+ if cached && out['error'].empty?
+ @cache_mutex.synchronize do
+ @cache[path] = out
+ end
+ end
rescue => e
out['error'] = e
end
@@ -96,14 +159,17 @@ module Puppet::Util
out
end
- private
-
def parse_response(response)
out = {
'status' => response.code.to_i,
- 'error' => ''
+ 'error' => '',
+ 'body' => {}
}
+ if response.body
+ out['body'] = JSON.parse(response.body)
+ end
+
if (400...600).cover?(response.code.to_i)
message = 'server returned a non-ok status code without an error'
@@ -113,7 +179,7 @@ module Puppet::Util
unless body['errors'].nil?
error_messages = body['errors'].map { |e| "#{e['name']} #{e['reason']}" }
- message = [message, *error_messages].join(': ')
+ message = [message, *error_messages].join(' : ').delete_prefix(' : ')
end
end
diff --git a/ee/tools/puppet/fleetdm/manifests/profile.pp b/ee/tools/puppet/fleetdm/manifests/profile.pp
index bc51c86b8d..5cd7265fca 100644
--- a/ee/tools/puppet/fleetdm/manifests/profile.pp
+++ b/ee/tools/puppet/fleetdm/manifests/profile.pp
@@ -17,12 +17,18 @@
# Fleet keeps track of each time this resource is
# declared with a group name, the final team name
# will be a concatenation of all unique group names.
+# @param ensure
+# Whether the profile should be present or not.
+# Set to `absent` along with a distinct `group`
+# name to create a new team that doesn't have the
+# configuration profile.
#
# @example
# fleetdm::profile { 'identifier': }
define fleetdm::profile (
String $template,
String $group = 'default',
+ Enum['absent', 'present'] $ensure = 'present',
) {
if $facts["clientnoop"] {
notice('noop mode: skipping profile definition in the Fleet server')
@@ -36,15 +42,18 @@ define fleetdm::profile (
}
$host_uuid = $facts['system_profiler']['hardware_uuid']
- $response = fleetdm::preassign_profile($name, $host_uuid, $template, $group)
+ $response = fleetdm::preassign_profile($name, $host_uuid, $template, $group, $ensure)
$err = $response['error']
+ $changed = $response['resource_changed']
if $err != '' {
- notify { "error pre-assigning profile ${$name}: ${$err}":
+ notify { "error pre-setting profile ${name} as ${ensure}: ${err}":
loglevel => 'err',
}
- } else {
- notify { "successfully pre-assigned profile ${$name}": }
+ } elsif $changed {
+ # NOTE: sending a notification also marks the
+ # 'fleetdm::profile' as changed in the reports.
+ notify { "successfully pre-set profile ${name} as ${ensure}": }
}
}
}
diff --git a/ee/tools/puppet/fleetdm/metadata.json b/ee/tools/puppet/fleetdm/metadata.json
index 3935a2d21b..17e0d1f44e 100644
--- a/ee/tools/puppet/fleetdm/metadata.json
+++ b/ee/tools/puppet/fleetdm/metadata.json
@@ -1,6 +1,6 @@
{
"name": "fleetdm-fleetdm",
- "version": "0.1.2",
+ "version": "0.2.1",
"author": "Fleet Device Management Inc",
"summary": "MDM management and profile assignment using FleetDM",
"license": "proprietary",
diff --git a/ee/tools/puppet/fleetdm/spec/defines/profile_spec.rb b/ee/tools/puppet/fleetdm/spec/defines/profile_spec.rb
index cd528a7da8..beb940683f 100644
--- a/ee/tools/puppet/fleetdm/spec/defines/profile_spec.rb
+++ b/ee/tools/puppet/fleetdm/spec/defines/profile_spec.rb
@@ -10,6 +10,7 @@ describe 'fleetdm::profile' do
let(:node_name) { Puppet[:node_name_value] }
let(:catalog_uuid) { '827a74c8-cf98-44da-9ff7-18c5e4bee41e' }
let(:run_identifier) { "#{catalog_uuid}-#{node_name}" }
+ let(:host_response) { { 'host' => { 'id' => 1 } } }
let(:params) do
{ 'template' => template, 'group' => group }
end
@@ -17,7 +18,7 @@ describe 'fleetdm::profile' do
before(:each) do
fleet_client_class = class_spy('Puppet::Util::FleetClient')
stub_const('Puppet::Util::FleetClient', fleet_client_class)
- allow(fleet_client_class).to receive(:new).with('https://example.com', 'test_token') { fleet_client_mock }
+ allow(fleet_client_class).to receive(:instance) { fleet_client_mock }
allow(SecureRandom).to receive(:uuid).and_return(catalog_uuid)
end
@@ -27,7 +28,18 @@ describe 'fleetdm::profile' do
it 'compiles' do
uuid = os_facts[:system_profiler]['hardware_uuid']
- expect(fleet_client_mock).to receive(:preassign_profile).with(run_identifier, uuid, template, group).and_return({ 'error' => '' })
+ expect(fleet_client_mock)
+ .to receive(:get_host_by_identifier)
+ .with(uuid)
+ .and_return({ 'error' => '', 'body' => host_response })
+ expect(fleet_client_mock)
+ .to receive(:get_host_profiles)
+ .with(host_response['host']['id'])
+ .and_return({ 'error' => '', 'body' => { 'profiles' => [] } })
+ expect(fleet_client_mock)
+ .to receive(:preassign_profile)
+ .with(run_identifier, uuid, template, group, 'present')
+ .and_return({ 'error' => '' })
is_expected.to compile
end
@@ -55,6 +67,14 @@ describe 'fleetdm::profile' do
it { is_expected.to compile.and_raise_error(%r{invalid group}) }
end
+ context 'invalid ensure' do
+ let(:params) do
+ { 'template' => template, 'ensure' => 'nothing' }
+ end
+
+ it { is_expected.to compile.and_raise_error(%r{'ensure' expects a match for Enum\['absent', 'present'\]}) }
+ end
+
context 'without group' do
let(:params) do
{ 'template' => template }
@@ -62,7 +82,41 @@ describe 'fleetdm::profile' do
it 'compiles' do
uuid = os_facts[:system_profiler]['hardware_uuid']
- expect(fleet_client_mock).to receive(:preassign_profile).with(run_identifier, uuid, template, 'default').and_return({ 'error' => '' })
+ expect(fleet_client_mock)
+ .to receive(:get_host_by_identifier)
+ .with(uuid)
+ .and_return({ 'error' => '', 'body' => host_response })
+ expect(fleet_client_mock)
+ .to receive(:get_host_profiles)
+ .with(host_response['host']['id'])
+ .and_return({ 'error' => '', 'body' => { 'profiles' => [] } })
+ expect(fleet_client_mock)
+ .to receive(:preassign_profile)
+ .with(run_identifier, uuid, template, 'default', 'present')
+ .and_return({ 'error' => '' })
+ is_expected.to compile
+ end
+ end
+
+ context 'ensure => absent' do
+ let(:params) do
+ { 'template' => template, 'ensure' => 'absent' }
+ end
+
+ it 'compiles' do
+ uuid = os_facts[:system_profiler]['hardware_uuid']
+ expect(fleet_client_mock)
+ .to receive(:get_host_by_identifier)
+ .with(uuid)
+ .and_return({ 'error' => '', 'body' => host_response })
+ expect(fleet_client_mock)
+ .to receive(:get_host_profiles)
+ .with(host_response['host']['id'])
+ .and_return({ 'error' => '', 'body' => { 'profiles' => [] } })
+ expect(fleet_client_mock)
+ .to receive(:preassign_profile)
+ .with(run_identifier, uuid, template, 'default', 'absent')
+ .and_return({ 'error' => '' })
is_expected.to compile
end
end
diff --git a/ee/tools/puppet/fleetdm/spec/functions/fleet_client_spec.rb b/ee/tools/puppet/fleetdm/spec/functions/fleet_client_spec.rb
index b67d52d644..b5cd9ed51c 100644
--- a/ee/tools/puppet/fleetdm/spec/functions/fleet_client_spec.rb
+++ b/ee/tools/puppet/fleetdm/spec/functions/fleet_client_spec.rb
@@ -3,13 +3,96 @@
require 'spec_helper'
describe 'Puppet::Util::FleetClient' do
- let(:client) { Puppet::Util::FleetClient.new('https://example.com', 'token') }
+ let(:client) { Puppet::Util::FleetClient.instance }
+ let(:host) { 'https://test.example.com' }
+ let(:token) { 'supersecret' }
+ let(:identifier) { 'test_ident' }
- it 'handles POST with 204 responses' do
- response = Net::HTTPSuccess.new(1.0, '204', 'OK')
- expect_any_instance_of(Net::HTTP).to receive(:request) { response } # rubocop:disable RSpec/AnyInstance
+ before(:each) do
+ stub_const(
+ 'Puppet::Parser::Compiler',
+ class_spy('Puppet::Parser::Compiler'),
+ )
- result = client.post('/example')
- expect(result[:body]).to be(nil)
+ stub_const(
+ 'Puppet::Parser::Scope',
+ class_spy('Puppet::Parser::Scope'),
+ )
+
+ lookup = class_spy('Puppet::Pops::Lookup')
+ stub_const('Puppet::Pops::Lookup', lookup)
+ allow(lookup)
+ .to receive(:lookup)
+ .with('fleetdm::host', anything, anything, anything, anything, anything) { host }
+
+ allow(lookup)
+ .to receive(:lookup)
+ .with('fleetdm::token', anything, anything, anything, anything, anything) { token }
+
+ stub_const(
+ 'Puppet::Pops::Lookup::Invocation',
+ class_spy('Puppet::Pops::Lookup::Invocation'),
+ )
+ end
+
+ def mock_http_post(uri: '', request_body: {}, response: nil)
+ mock_net_http = instance_double('Net:HTTP')
+ mock_net_http_post = instance_double('Net::HTTP::POST')
+ allow(Net::HTTP).to receive(:new).and_return(mock_net_http)
+ allow(mock_net_http).to receive(:use_ssl=).with(true)
+ allow(Net::HTTP::Post).to receive(:new).with(uri).and_return(mock_net_http_post)
+ allow(mock_net_http_post).to receive(:[]=).with('Authorization', "Bearer #{token}")
+ allow(mock_net_http_post).to receive(:body=).with(request_body.to_json)
+ allow(mock_net_http).to receive(:request).with(mock_net_http_post) { response }
+ end
+
+ def mock_http_get(uri: '', response: instance_double(Net::HTTPSuccess, code: 204, body: nil))
+ mock_net_http = instance_double('Net:HTTP')
+ mock_net_http_get = instance_double('Net::HTTP::POST')
+ allow(Net::HTTP).to receive(:new).and_return(mock_net_http)
+ allow(mock_net_http).to receive(:use_ssl=).with(true)
+ allow(Net::HTTP::Get).to receive(:new).with(uri).and_return(mock_net_http_get)
+ allow(mock_net_http_get).to receive(:[]=).with('Authorization', "Bearer #{token}")
+ allow(mock_net_http).to receive(:request).with(mock_net_http_get) { response }
+ end
+
+ describe '#match_profiles' do
+ describe 'successful response' do
+ subject :result do
+ mock_http_post(
+ uri: '/api/latest/fleet/mdm/apple/profiles/match',
+ request_body: { 'external_host_identifier' => identifier },
+ response: instance_double(Net::HTTPSuccess, code: 204, body: nil),
+ )
+ client.match_profiles(identifier)
+ end
+
+ it { expect(result['body']).to eq({}) }
+ it { expect(result['error']).to eq('') }
+ it { expect(result['status']).to eq(204) }
+ end
+
+ describe 'response with errors' do
+ subject :result do
+ mock_http_post(
+ uri: '/api/latest/fleet/mdm/apple/profiles/match',
+ request_body: { 'external_host_identifier' => identifier },
+ response: instance_double(
+ Net::HTTPServerError,
+ code: 500,
+ body: body.to_json,
+ ),
+ )
+ client.match_profiles(identifier)
+ end
+
+ let(:body) do
+ { 'errors' => [{ 'name' => 'server error', 'reason' => 'unknown' }] }
+ end
+
+ it { expect(result['body']).to eq(body) }
+ it { expect(result['error']).to eq('server error unknown') }
+ it { expect(result['status']).to eq(500) }
+ end
end
end
diff --git a/ee/tools/puppet/fleetdm/spec/functions/preassign_profile_spec.rb b/ee/tools/puppet/fleetdm/spec/functions/preassign_profile_spec.rb
index 0ae5d424fb..b4b374134e 100644
--- a/ee/tools/puppet/fleetdm/spec/functions/preassign_profile_spec.rb
+++ b/ee/tools/puppet/fleetdm/spec/functions/preassign_profile_spec.rb
@@ -7,27 +7,51 @@ describe 'fleetdm::preassign_profile' do
let(:device_uuid) { 'device-uuid' }
let(:template) { 'template' }
let(:group) { 'group' }
+ let(:ensure_profile) { 'absent' }
let(:node_name) { Puppet[:node_name_value] }
let(:catalog_uuid) { '827a74c8-cf98-44da-9ff7-18c5e4bee41e' }
let(:run_identifier) { "#{catalog_uuid}-#{node_name}" }
let(:profile_identifier) { 'test.example.com' }
+ let(:host_response) { { 'host' => { 'id' => 1 } } }
before(:each) do
fleet_client_class = class_spy('Puppet::Util::FleetClient')
stub_const('Puppet::Util::FleetClient', fleet_client_class)
- allow(fleet_client_class).to receive(:new).with('https://example.com', 'test_token') { fleet_client_mock }
+ allow(fleet_client_class).to receive(:instance) { fleet_client_mock }
allow(SecureRandom).to receive(:uuid).and_return(catalog_uuid)
end
it { is_expected.to run.with_params(nil).and_raise_error(StandardError) }
it 'performs an API call to Fleet with the right parameters' do
- expect(fleet_client_mock).to receive(:preassign_profile).with(run_identifier, device_uuid, template, group).and_return({ 'error' => '' })
- is_expected.to run.with_params(profile_identifier, device_uuid, template, group)
+ expect(fleet_client_mock)
+ .to receive(:get_host_by_identifier)
+ .with(device_uuid)
+ .and_return({ 'error' => '', 'body' => host_response })
+ expect(fleet_client_mock)
+ .to receive(:get_host_profiles)
+ .with(host_response['host']['id'])
+ .and_return({ 'error' => '', 'body' => { 'profiles' => [] } })
+ expect(fleet_client_mock)
+ .to receive(:preassign_profile)
+ .with(run_identifier, device_uuid, template, group, ensure_profile)
+ .and_return({ 'error' => '' })
+ is_expected.to run.with_params(profile_identifier, device_uuid, template, group, ensure_profile)
end
- it 'has a default value if group is not provided' do
- expect(fleet_client_mock).to receive(:preassign_profile).with(run_identifier, device_uuid, template, 'default').and_return({ 'error' => '' })
+ it 'has default values for `group` and `ensure`' do
+ expect(fleet_client_mock)
+ .to receive(:get_host_by_identifier)
+ .with(device_uuid)
+ .and_return({ 'error' => '', 'body' => host_response })
+ expect(fleet_client_mock)
+ .to receive(:get_host_profiles)
+ .with(host_response['host']['id'])
+ .and_return({ 'error' => '', 'body' => { 'profiles' => [] } })
+ expect(fleet_client_mock)
+ .to receive(:preassign_profile)
+ .with(run_identifier, device_uuid, template, 'default', 'present')
+ .and_return({ 'error' => '' })
is_expected.to run.with_params(profile_identifier, device_uuid, template)
end
end
diff --git a/ee/tools/puppet/fleetdm/spec/functions/release_device_spec.rb b/ee/tools/puppet/fleetdm/spec/functions/release_device_spec.rb
index 727dfb9018..3cbe7db5c3 100644
--- a/ee/tools/puppet/fleetdm/spec/functions/release_device_spec.rb
+++ b/ee/tools/puppet/fleetdm/spec/functions/release_device_spec.rb
@@ -10,7 +10,7 @@ describe 'fleetdm::release_device' do
before(:each) do
fleet_client_class = class_spy('Puppet::Util::FleetClient')
stub_const('Puppet::Util::FleetClient', fleet_client_class)
- allow(fleet_client_class).to receive(:new).with('https://example.com', 'test_token') { fleet_client_mock }
+ allow(fleet_client_class).to receive(:instance) { fleet_client_mock }
end
it { is_expected.to run.with_params(nil).and_raise_error(StandardError) }
diff --git a/frontend/__mocks__/appleMdm.ts b/frontend/__mocks__/appleMdm.ts
new file mode 100644
index 0000000000..1ed7964056
--- /dev/null
+++ b/frontend/__mocks__/appleMdm.ts
@@ -0,0 +1,16 @@
+import { IMdmApple } from "interfaces/mdm";
+
+const DEFAULT_MDM_APPLE_MOCK: IMdmApple = {
+ common_name: "APSP:12345",
+ serial_number: "12345",
+ issuer: "Test Certification Authority",
+ renew_date: "2023-03-24T22:13:59Z",
+};
+
+export const createMockMdmApple = (
+ overrides?: Partial
+): IMdmApple => {
+ return { ...DEFAULT_MDM_APPLE_MOCK, ...overrides };
+};
+
+export default createMockMdmApple;
diff --git a/frontend/__mocks__/axiosError.ts b/frontend/__mocks__/axiosError.ts
new file mode 100644
index 0000000000..7e11bd2c7b
--- /dev/null
+++ b/frontend/__mocks__/axiosError.ts
@@ -0,0 +1,14 @@
+import { AxiosError } from "axios";
+
+const DEFAULT_AXIOS_ERROR_MOCK: AxiosError = {
+ isAxiosError: true,
+ toJSON: () => ({}),
+ name: "Error",
+ message: "error message",
+};
+
+const createMockAxiosError = (overrides?: Partial): AxiosError => {
+ return { ...DEFAULT_AXIOS_ERROR_MOCK, ...overrides };
+};
+
+export default createMockAxiosError;
diff --git a/frontend/__mocks__/configMock.ts b/frontend/__mocks__/configMock.ts
index 5feb718f0c..c51d2895d5 100644
--- a/frontend/__mocks__/configMock.ts
+++ b/frontend/__mocks__/configMock.ts
@@ -4,6 +4,7 @@ const DEFAULT_CONFIG_MOCK: IConfig = {
org_info: {
org_name: "fleet",
org_logo_url: "",
+ org_logo_url_light_background: "",
contact_url: "https://fleetdm.com/company/contact",
},
server_settings: {
diff --git a/frontend/components/TableContainer/DataTable/TruncatedTextCell/_styles.scss b/frontend/components/TableContainer/DataTable/TruncatedTextCell/_styles.scss
index a33061b394..1aa73266d8 100644
--- a/frontend/components/TableContainer/DataTable/TruncatedTextCell/_styles.scss
+++ b/frontend/components/TableContainer/DataTable/TruncatedTextCell/_styles.scss
@@ -26,7 +26,7 @@
// allows for the tooltip text to break on a word instead of a character
&.tooltip-break-on-word {
.truncated-tooltip {
- word-break: normal
+ word-break: normal;
}
}
@@ -43,13 +43,13 @@
}
}
- @media (min-width: $break-990) {
+ @media (min-width: $break-md) {
.truncated-tooltip {
max-width: 400px;
}
}
- @media (min-width: $break-1400) {
+ @media (min-width: $break-lg) {
.truncated-tooltip {
max-width: 800px;
}
diff --git a/frontend/components/TableContainer/_styles.scss b/frontend/components/TableContainer/_styles.scss
index fc3c656a4c..1cb21065f6 100644
--- a/frontend/components/TableContainer/_styles.scss
+++ b/frontend/components/TableContainer/_styles.scss
@@ -15,12 +15,12 @@
flex-direction: column-reverse;
align-items: start;
- @media (min-width: $break-768) {
+ @media (min-width: $break-xs) {
flex-direction: row;
align-items: end;
justify-content: space-between;
}
- @media (min-width: $break-990) {
+ @media (min-width: $break-md) {
align-items: center;
}
}
@@ -36,7 +36,7 @@
flex-direction: column-reverse;
align-items: start;
- @media (min-width: $break-990) {
+ @media (min-width: $break-md) {
flex-direction: row;
justify-content: space-between;
align-items: center;
@@ -66,7 +66,7 @@
&.stack-table-controls {
padding-top: $pad-large;
- @media (min-width: $break-990) {
+ @media (min-width: $break-md) {
padding-top: 0;
}
}
@@ -87,10 +87,10 @@
.search-field__input-wrapper {
width: 250px;
margin-bottom: 0;
- @media (min-width: $break-768) {
+ @media (min-width: $break-xs) {
width: 300px;
}
- @media (min-width: $break-990) {
+ @media (min-width: $break-md) {
width: 344px;
}
}
@@ -99,23 +99,12 @@
padding-bottom: $pad-large;
margin-left: 0;
- @media (min-width: $break-768) {
+ @media (min-width: $break-xs) {
margin-left: $pad-medium;
padding-bottom: 0;
}
}
- &::before {
- display: inline-block;
- position: absolute;
- padding: 5px 0 0 0; // centers spin
- content: url(../assets/images/icon-search-fleet-black-16x16@2x.png);
- transform: scale(0.5);
- height: 20px;
- top: 3px;
- left: 8px;
- }
-
.input-field {
padding-left: 42px;
width: 100%;
diff --git a/frontend/components/buttons/ActionButtons/_styles.scss b/frontend/components/buttons/ActionButtons/_styles.scss
index 0fa87ee5af..4ef7cfc0a7 100644
--- a/frontend/components/buttons/ActionButtons/_styles.scss
+++ b/frontend/components/buttons/ActionButtons/_styles.scss
@@ -7,7 +7,7 @@
&__secondary-buttons {
display: none;
- @media (min-width: 990px) {
+ @media (min-width: $break-md) {
display: flex;
}
}
@@ -35,7 +35,7 @@
}
}
}
- @media (min-width: 990px) {
+ @media (min-width: $break-md) {
display: none;
}
}
diff --git a/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx b/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx
index 653fb10ef9..57dde25c35 100644
--- a/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx
+++ b/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx
@@ -32,6 +32,8 @@ class ConfirmInviteForm extends Component {
diff --git a/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx b/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx
index 39f4b2ac2a..83a20af976 100644
--- a/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx
+++ b/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx
@@ -4,12 +4,11 @@ import PropTypes from "prop-types";
import Button from "components/buttons/Button";
import Form from "components/forms/Form";
import formFieldInterface from "interfaces/form_field";
-import helpers from "components/forms/ForgotPasswordForm/helpers";
import InputFieldWithIcon from "components/forms/fields/InputFieldWithIcon";
+import validate from "./validate";
const baseClass = "forgot-password-form";
const fieldNames = ["email"];
-const { validate } = helpers;
class ForgotPasswordForm extends Component {
static propTypes = {
@@ -26,7 +25,12 @@ class ForgotPasswordForm extends Component {
return (