From 33b481fdc864b7bbf0981a381d24eeb23bc6be1c Mon Sep 17 00:00:00 2001 From: Rachael Shaw Date: Tue, 4 Feb 2025 12:38:54 -0600 Subject: [PATCH] Docs v4.63.0 (#26019) Documentation changes for 4.63.0 --------- Co-authored-by: Marko Lisica <83164494+marko-lisica@users.noreply.github.com> Co-authored-by: Eugene Co-authored-by: Ian Littman Co-authored-by: Scott Gress Co-authored-by: Victor Lyuboslavsky Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> --- .../automatic-software-install-in-fleet.md | 56 +++++------ articles/cdn-signed-urls.md | 55 +++++++++++ articles/deploy-software-packages.md | 2 +- articles/fleet-4.63.0.md | 89 ++++++++++++++++++ .../install-vpp-apps-on-macos-using-fleet.md | 8 +- .../fleet-server-configuration.md | 40 ++++++++ docs/Configuration/yaml-files.md | 20 ++-- docs/Contributing/API-for-contributors.md | 23 ++++- docs/Contributing/Audit-logs.md | 61 ++++++++++-- docs/REST API/rest-api.md | 13 ++- .../articles/fleet-4.63.0-1600x900@2x.png | Bin 0 -> 53884 bytes 11 files changed, 311 insertions(+), 56 deletions(-) create mode 100644 articles/cdn-signed-urls.md create mode 100644 articles/fleet-4.63.0.md create mode 100644 website/assets/images/articles/fleet-4.63.0-1600x900@2x.png diff --git a/articles/automatic-software-install-in-fleet.md b/articles/automatic-software-install-in-fleet.md index 907a0a92d5d0..ded919161171 100644 --- a/articles/automatic-software-install-in-fleet.md +++ b/articles/automatic-software-install-in-fleet.md @@ -1,74 +1,64 @@ # Automatically install software -Fleet [v4.57.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0) introduces the ability to automatically and remotely install software on hosts based on predefined policy failures. This guide will walk you through the process of configuring Fleet for automatic installation of software on hosts using uploaded custom packages or Fleet-maintained apps and based on programmed policies. You'll learn how to configure and use this feature, as well as understand how the underlying mechanism works. - -Fleet allows its users to upload trusted software installation files to be installed and used on hosts. This installation could be conditioned on a failure of a specific Fleet Policy. - -> Currently, Fleet-maintained apps can be automatically installed on macOS hosts and custom packages can be automatically installed on macOS, Windows, and Linux hosts. (macOS App Store apps [coming soon](https://github.com/fleetdm/fleet/issues/23115)) - -## Prerequisites - -* Fleet premium with Admin permissions. -* Fleet [v4.57.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.57.0) or greater. +In Fleet, you can automatically and remotely install software on hosts. This guide will walk you through the process of configuring Fleet to install software on your hosts. ## Step-by-step instructions -1. **Adding software**: Add any software to be available for installation. Follow the [deploying software](https://fleetdm.com/guides/deploy-security-agents) document with instructions how to do it. Note that all installation steps (pre-install query, install script, and post-install script) will be executed as configured, regardless of the policy that triggers the installation. - - -![Add software](../website/assets/images/articles/automatic-software-install-add-software.png) +1. **Adding software**: Follow the [deploying software](https://fleetdm.com/guides/deploy-security-agents) guide to make a software title available for installation. Note that for Fleet maintained Apps and custom packages all installation steps (pre-install query, install script, and post-install script) will be executed as configured, regardless of the policy that triggers the installation. Current supported software deployment formats: -- macOS: .pkg +- macOS: .pkg and App Store (VPP) app - Windows: .msi, .exe - Linux: .deb, .rpm -Coming soon: -- VPP for iOS and iPadOS +> As of v4.62.0, Fleet can create an automatic install policy for you when you upload a custom package or add a Fleet Maintained App. If you use this "Automatic" installation mode, you do not have to create your own policy, so you can skip the remaining steps of this process. -> Note: starting with v4.62.0, you can have Fleet create an automatic install policy for you when you upload a package. If you use this "Automatic" installation mode, you do not have to create your own policy. See our [deploying software](https://fleetdm.com/guides/deploy-security-agents) guide for more details. - -2. **Add a policy**: In Fleet, add a policy that failure to pass will trigger the required installation. Go to Policies tab --> Press the "Add policy" button --> Click "create your own policy" --> Enter your policy SQL --> Save --> Fill in details in the Save modal and Save. +2. **Add a policy**: In Fleet, add a policy that failure to pass will trigger the required installation. Go the **Policies** tab, select a team, then press the **Add policy** button. Next, click **Create your own policy**, enter your policy SQL, click **Save**, fill in remaining details in the Save modal, then and click **Save** again. ```sql SELECT 1 FROM apps WHERE name = 'Adobe Acrobat Reader.app' AND version_compare(bundle_short_version, '23.001.20687') >= 0; ``` -Note: In order to know the exact application name to put in the query (e.g. "Adobe Acrobat Reader.app" in the query above) you can manually install it on a canary/test host and then query SELECT * from apps; - +> In order to know the exact application name to put in the query (e.g. "Adobe Acrobat Reader.app" in the query above) you can manually install it on a canary/test host and then query `SELECT * from apps;` -3. **Manage automation**: Open Manage Automations: Policies Tab --> top right "Manage automations" --> "Install software". +3. **Open the software install automation modal**: In the **Policies** tab, click the **Manage automations** button on the top-right, then select **Install software** from the context menu that pops up. ![Manage policies](../website/assets/images/articles/automatic-software-install-policies-manage.png) -4. **Select policy**: Select (click the check box of) your newly created policy. To the right of it select from the +4. **Select policy**: Click the checkbox next to your newly created policy's name. To the right of it select from the drop-down list the software you would like to be installed upon failure of this policy. ![Install software modal](../website/assets/images/articles/automatic-software-install-install-software.png) Upon failure of the selected policy, the selected software installation will be triggered. -> Adding software to a policy will reset the policy's host counts. +> Adding a software automation to a policy, or changing the automated software title, will reset the policy's host counts. ## How does it work? * After configuring Fleet to auto-install a specific software the rest will be done automatically. -* The policy check mechanism runs on a typical 1 hour cadence on all online hosts. -* Fleet will send install requests to the hosts on the first policy failure (first "No" result for the host) or if a policy goes from "Yes" to "No". On this iteration it will not send an install request if a policy is already failing and continues to fail ("No" -> "No"). See the following flowchart for details. +* The policy check mechanism runs on a typical one-hour cadence on all online hosts. +* Fleet will send install requests to the hosts on the first policy failure (first "No" result for the host) or if a policy goes from "Yes" to "No". Currently, Fleet will not send an install request if a policy is already failing and continues to fail ("No" -> "No"). See the following flowchart for details. ![Flowchart](../website/assets/images/articles/automatic-software-install-workflow.png) *Detailed flowchart* +App Store (VPP) apps won't be installed if a host has MDM turned off or if you run out of licenses (purchased in Apple Business Manager). Currently, these errors aren't surfaced in Fleet. After turning MDM on for a host or purchasing more licenses, you can retry installing the app on the host's **Host details** page (learn how [here](https://fleetdm.com/guides/deploy-software-packages#install-the-package)). To retry on multiple hosts at once, head to **Policies > Manage Automations** in Fleet and turn the app's policy automation off and back on. + +Currently, App Store apps (VPP) are not installed as [Managed Apps](https://support.apple.com/guide/deployment/distribute-managed-apps-dep575bfed86/web). Uninstalling VPP apps is coming soon. + ## Templates for policy queries Use the following policy templates to see if the software is already installed. Fleet uses these templates to automatically install software. -### macOS (pkg) +### macOS (pkg and VPP) ```sql SELECT 1 FROM apps WHERE name = '' AND version_compare(bundle_short_version, '') >= 0; ``` +> `SOFTWARE_TITLE_NAME` includes the `.app` extension. You can also use `bundle_identifier` for a more precise match that works if an end user renames the app on their machine. + ### Windows (msi and exe) ```sql @@ -109,13 +99,13 @@ SELECT 1 WHERE EXISTS ( ); ``` -## Using the REST API for self-service software packages +## Via the API -Fleet provides a REST API for managing software packages, including self-service software packages. Learn more about Fleet's [REST API](https://fleetdm.com/docs/rest-api/rest-api#add-team-policy). +Fleet provides a REST API for managing policies, including software install automations. Learn more about Fleet's [REST API](https://fleetdm.com/docs/rest-api/rest-api#add-team-policy). -## Managing self-service software packages with GitOps +## Via GitOps -To manage self-service software packages using Fleet's best practice GitOps, check out the `software` key in the [GitOps reference documentation](https://fleetdm.com/docs/configuration/yaml-files#policies). +To manage software automations using Fleet's best practice GitOps, check out the `install_software` key in the [policies section of the GitOps reference documentation](https://fleetdm.com/docs/configuration/yaml-files#policies). ## Conclusion @@ -129,5 +119,5 @@ By automating software deployment, you can gain greater control over what's inst - + diff --git a/articles/cdn-signed-urls.md b/articles/cdn-signed-urls.md new file mode 100644 index 000000000000..f6323444f0df --- /dev/null +++ b/articles/cdn-signed-urls.md @@ -0,0 +1,55 @@ +# How to use CloudFront signed URLs with Fleet + +Fleet [v4.63.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.63.0) allows you to use CloudFront signed URLs for downloading MDM bootstrap packages and software installation packages to your hosts. This speeds up onboarding for organizations that onboard new employees at different headquarters across the world. + +CloudFront signed URLs grant access to a specific CloudFront distribution resource and are valid for a specified duration. + +## Prerequisites + +- Fleet v4.63.0 +- Orbit v1.39.0 agent installed on hosts (for software installation packages) +- S3 bucket with CloudFront distribution and a signing key pair + +To add a CloudFront distribution with a signer to your S3 bucket, follow the instructions in the [AWS documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html) or the [How to securely serve private CDN content using CloudFront](https://victoronsoftware.com/posts/cloudfront-signed-urls/) guide written by one of our engineers. + +## Configure Fleet server for S3 and CloudFront + +To configure S3 and CloudFront in Fleet, use the [S3 server configuration options](https://fleetdm.com/docs/configuration/fleet-server-configuration#s-3). Set these options via the command line, environment variables, or a configuration file. + +To enable CloudFront signed URLs, set the following options in your Fleet server configuration: + +- `s3_software_installers_cloudfront_url`: The base URL of your CloudFront distribution, such as `https://d1234567890.cloudfront.net`. +- `s3_software_installers_cloudfront_key_pair_id`: The CloudFront signer's key pair ID, such as `K1HFGXOMBB6TFF`. +- `s3_software_installers_cloudfront_private_key`: The CloudFront signer's private key, such as `-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAz...`. + +The `FLEET_S3_SOFTWARE_INSTALLERS_CLOUDFRONT_URL_SIGNING_PRIVATE_KEY` environment variable can be set from a file. On macOS, it requires [gnu-sed](https://formulae.brew.sh/formula/gnu-sed) (`gsed`) to replace newlines with `\n` characters. + +```bash +export FLEET_S3_SOFTWARE_INSTALLERS_CLOUDFRONT_URL_SIGNING_PRIVATE_KEY=$(cat ./private_key.pem | gsed -z 's/\n/\\n/g') +``` + +Non-signed CDN URLs are not secure and are not supported. + +## Use CloudFront signed URLs in Fleet + +Once configured, Fleet will automatically use CloudFront signed URLs to install MDM bootstrap packages and software packages on your hosts. The signed URLs are generated on the fly and are valid for six hours. + +If the Fleet server encounters an error while generating a signed URL for the bootstrap package, it will fall back to using the Fleet server's URL. + +If the Orbit agent encounters an error while downloading a software package using a signed URL, it will retry the download using the Fleet server's URL. + +To make sure that the signed URLs are working correctly, you can check the CloudFront logs (if enabled) as well as [APM](https://aws.amazon.com/what-is/application-performance-monitoring/) or Fleet server debug logs. In APM or Fleet server logs, you should NOT see devices downloading packages from the Fleet server's non-CDN API paths, such as: + +- `GET /api/v1/fleet/bootstrap` +- `POST /api/fleet/orbit/software_install/package` + +## Conclusion + +Using CloudFront signed URLs with Fleet can help speed up downloads and reduce the load on your Fleet server. If you have any questions or need help configuring CloudFront signed URLs, please contact our [support team](https://fleetdm.com/contact). + + + + + + + diff --git a/articles/deploy-software-packages.md b/articles/deploy-software-packages.md index 8028adc6d455..c90e068b7afd 100644 --- a/articles/deploy-software-packages.md +++ b/articles/deploy-software-packages.md @@ -8,7 +8,7 @@ In Fleet you can deploy [Fleet-maintained apps](https://fleetdm.com/guides/insta This guide will walk you through steps to manually install custom packages on your hosts. -Learn more about automatically installing software in a separate guide [here](https://fleetdm.com/guides/automatic-software-install-in-fleet). +Learn more about automatically installing software [the Automatically install software guide](https://fleetdm.com/guides/automatic-software-install-in-fleet). ## Prerequisites diff --git a/articles/fleet-4.63.0.md b/articles/fleet-4.63.0.md new file mode 100644 index 000000000000..7a9153552f65 --- /dev/null +++ b/articles/fleet-4.63.0.md @@ -0,0 +1,89 @@ +# Fleet 4.63.0 | Automatically install software, fleetctl for Linux ARM, faster employee onboarding + +
+ +
+ +Fleet 4.63.0 is live. Check out the full [changelog](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.63.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 + +- Automatically install software +- Fleetctl on Linux ARM +- Faster employee onboarding + +### Automatically install software + +Fleet can now automatically install App Store (VPP) apps when a macOS host fails a policy. This removes the need for third-party automation tools, making large-scale app deployment easier and more reliable. Learn more about installing software [here](https://fleetdm.com/guides/automatic-software-install-in-fleet). + +### Fleetctl for Linux ARM + +Fleet users with Linux ARM workstations can now use the fleetctl command-line interface (CLI) to run scripts, queries, and more. This expands Fleet’s CLI capabilities, allowing users to manage hosts on their preferred operating system (OS). Learn more about fleetctl [here](https://fleetdm.com/guides/fleetctl). + +### Faster employee onboarding + +During new employee onboarding, Macs can now optionally download bootstrap packages and software from the nearest CloudFront region. This speeds up onboarding for organizations that onboard new employees at different headquarters across the world. Learn more [here](https://fleetdm.com/guides/cdn-signed-urls). + +## Changes + +## Device management (MDM) +- Allowed the delivery of bootstrap packages and software installers using signed URLs from CloudFront CDN. To enable, configured the following server settings: + - `s3_software_installers_cloudfront_url` + - `s3_software_installers_cloudfront_url_signing_public_key_id` + - `s3_software_installers_cloudfront_url_signing_private_key` +- Downgraded the expected or common "BootstrapPackage not found" server error to a debug message. This occurred when the UI or API checked if a bootstrap package existed. +- Removed the arrow icon from the MDM solution table on the dashboard page. + +## Orchestration +- Added the ability to install VPP apps on policy failure. +- Implemented user-level settings and used them to persist a user's selection of which columns to display on the hosts table. +- Included a host's team-level queries when the user selected a query to target a specific host via the host details page. +- Included osquery pre-releases in the daily UI constant update GitHub Actions job. +- Displayed the correct path for agent options when a key was placed in the wrong object. +- When running a live query from the edit query form, considered the results of the run in calculating an existing query's performance impact if the user did not change the query from the stored version. +- Improved the validation workflow on the SMTP settings page. +- Clarified the expected behavior of policy host counts, dashboard controls software count, and controls OS updates versions count. +- Rendered the default empty value when a host had no UUID. +- Used an email logo compatible with dark modes. +- Improved readability of the success message on email update by never including the sender address. + +## Software +- Added the ability to install VPP apps on policy failure. +- Allowed filtering of titles by "any of these platforms" in `GET /api/v1/fleet/software/titles`. +- Added VPP apps to the automatic installation dropdown for failed policies and included auto-install information on the VPP app details page. +- Updated Fleet-maintained app install scripts for non-PKG-based installers to allow the apps to be installed over an existing installation. +- Clarified that editing VPP teams would remove App Store apps available to the team, not uninstall apps from hosts. +- Pushed the correct paths to the URL on the "My device" page when self-service was not enabled for the host. +- Displayed command line installation instructions when a package was generated. +- Added a fallback for extracting the app name from `.pkg` installers that had default or incorrect title attributes in their distribution file. +- Stopped VPP apps from being removed from teams whenever the VPP token team assignment was updated. +- Improved software installation for failed policies by adding platform-specific filtering in the software dropdown so that only compatible software was displayed based on each policy's targeted platforms. +- Added a timestamp for the software, OS, and vulnerability detail pages for the host count last update time. + +## Bug fixes and improvements +- Fixed an issue where the vulnerabilities cron failed in large environments due to large SQL queries. +- Fixed two broken links in the setup experience. +- Fixed a UI bug on the "My device" page where the "Software" tab included filter elements that did not match the expected design. +- Fixed a UI bug on the "Controls" page where incorrect timestamp information was displayed while the "Current versions" table was loading. +- Fixed an issue for batch upload of Apple DDM profiles with `fleetctl gitops` where the activity feed showed a change even when profiles did not actually change. +- Fixed a software name overflow in various modals. +- Fixed form validation behavior on the SSO settings form. +- Fixed MSI parsing for packages that included long interned strings (e.g., licenses for the OpenVPN Connect installer). +- Fixed a software actions dropdown styling bug. +- Fixed an issue where identical MDM commands were sent twice to the same device when the replica database was being used. +- Fixed a redirect when clicking on any column in the Fleet Maintained Apps table. +- Fixed an issue where deleted Apple config profiles were installed on devices because the devices were offline when the profile was added. +- Fixed a CVE-2024-10327 false positive on Fleet-supported platforms (the vulnerability was iOS-only and iOS vulnerability checking was not supported). +- Fixed missing capabilities in the UI for team admins when creating or editing a user by exposing more information from the API for team admins. + +## 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.63.0. + + + + + + + diff --git a/articles/install-vpp-apps-on-macos-using-fleet.md b/articles/install-vpp-apps-on-macos-using-fleet.md index 8627050c4049..ce9c559f9ec5 100644 --- a/articles/install-vpp-apps-on-macos-using-fleet.md +++ b/articles/install-vpp-apps-on-macos-using-fleet.md @@ -6,6 +6,8 @@ _Available in Fleet Premium_ In Fleet, you can install Apple App Store apps using the [Volume Purchasing Program (VPP)](https://support.apple.com/guide/app-store/volume-purchasing-app-store-mac-firc1767ec54/mac) on your macOS, iOS, and iPadOS hosts. This guide will walk you through using this feature to add apps from your Apple Business Manager account to Fleet and install those apps on your hosts. +Once a VPP app has been added to a team, it can be [automatically installed on hosts via policy automations](https://fleetdm.com/guides/automatic-software-install-in-fleet) as of Fleet [v4.63.0](https://github.com/fleetdm/fleet/releases/tag/fleet-v4.63.0). + ## Prerequisites * **MDM features**: to use the VPP integration, you must first enable MDM features in Fleet. See the [MDM setup guide](https://fleetdm.com/docs/using-fleet/mdm-setup) for instructions on enabling MDM features. @@ -59,7 +61,7 @@ To add apps to Fleet, you must first purchase them through Apple Business Manage the **Details** -> **Activity** -> **Upcoming** tab of this page. After the app is installed and the host details are refetched, the app will show up as **Installed** in the **Software** tab. ->**Note:** VPP managed apps currently can't be uninstalled from devices. Please see: [Uninstall App Store apps #20729](https://github.com/fleetdm/fleet/issues/20729). +> Currently, VPP apps are installed as unmanaged, and can't be uninstalled from devices via Fleet. Please see: [Uninstall App Store apps #20729](https://github.com/fleetdm/fleet/issues/20729). ## Install an app via self-service @@ -92,12 +94,12 @@ Fleet also provides a REST API for managing apps programmatically. You can add, ## Manage apps with GitOps -To manage App Store apps using Fleet's best practice GitOps, check out the `software` key in the GitOps reference documentation [here](https://fleetdm.com/docs/using-fleet/gitops#software). +To manage App Store apps using Fleet's best practice GitOps, check out the `software` key in [the GitOps reference documentation](https://fleetdm.com/docs/using-fleet/gitops#software). - + diff --git a/docs/Configuration/fleet-server-configuration.md b/docs/Configuration/fleet-server-configuration.md index 9bf8363bc050..e37cebc2fe43 100644 --- a/docs/Configuration/fleet-server-configuration.md +++ b/docs/Configuration/fleet-server-configuration.md @@ -2094,6 +2094,46 @@ Minio users must set this to any nonempty value (eg. `minio`), as Minio does not software_installers_region: us-east-1 ``` +### s3_software_installers_cloudfront_url + +CloudFront URL. Leave blank if you don't use CloudFront distribution. + +- Default value: none +- Environment variable: `FLEET_S3_SOFTWARE_INSTALLERS_CLOUDFRONT_URL` +- Config file format: + ```yaml + s3: + software_installers_cloudfront_url: https://jkl8dxv87sdh.cloudfront.net + ``` + +### s3_software_installers_cloudfront_url_signing_public_key_id + +Public key ID for URL signing. If `s3_software_installers_cloudfront_url` is set, this is required. + +- Default value: none +- Environment variable: `FLEET_S3_SOFTWARE_INSTALLERS_CLOUDFRONT_URL_SIGNING_PUBLIC_KEY_ID` +- Config file format: + ```yaml + s3: + software_installers_cloudfront_url_signing_public_key_id: K1HFGXOMBB6TFF + ``` + +### s3_software_installers_cloudfront_url_signing_private_key + +Private key for URL signing. If `s3_software_installers_cloudfront_url` is set, this is required. + +- Default value: none +- Environment variable: `FLEET_S3_SOFTWARE_INSTALLERS_CLOUDFRONT_URL_SIGNING_PRIVATE_KEY` +- Config file format: + ```yaml + s3: + software_installers_cloudfront_url_signing_private_key: | + ------BEGIN BEGIN RSA PRIVATE KEY----- + 3126756bd0c54fbc90c9928ef59e7037af8983afd10048929ae5 + 7473e62c7aed... + ``` + + ### s3_carves_bucket Name of the S3 bucket for file carves. diff --git a/docs/Configuration/yaml-files.md b/docs/Configuration/yaml-files.md index 60026f22c8ce..cb397f57f02e 100644 --- a/docs/Configuration/yaml-files.md +++ b/docs/Configuration/yaml-files.md @@ -63,13 +63,21 @@ policies: calendar_event_enabled: false run_script: path: "./disable-guest-account.sh" -- name: Firefox on Linux installed and up to date - platform: linux - description: "This policy checks that Firefox is installed and up to date." - resolution: "Install Firefox version 129.0.2 or higher." - query: "SELECT 1 FROM deb_packages WHERE name = 'firefox' AND version_compare(version, '129.0.2') >= 0;" +- name: Install Firefox on macOS + platform: darwin + description: "This policy checks that Firefox is installed." + resolution: "Install Firefox app if not installed." + query: "SELECT 1 FROM apps WHERE name = 'Firefox.app'" + install_software: + package_path: "./firefox.package.yml" +- name: [Install software] Logic Pro + platform: darwin + description: "This policy checks that Logic Pro is installed" + resolution: "Install Logic Pro App Store app if not installed" + query: "SELECT 1 FROM apps WHERE name = 'Logic Pro'" install_software: - package_path: "./linux-firefox.deb.package.yml" + package_path: ./linux-firefox.deb.package.yml + # app_store_id: "1487937127" (for App Store apps) ``` `default.yml` (for policies that neither install software nor run scripts), `teams/team-name.yml`, or `teams/no-team.yml` diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md index 3246068dca94..3fc4cd258a3d 100644 --- a/docs/Contributing/API-for-contributors.md +++ b/docs/Contributing/API-for-contributors.md @@ -1806,6 +1806,11 @@ If the `name` is not already associated with an existing team, this API route cr | mdm.windows_settings.custom_settings | array | body | The list of objects consists of a `path` to XML files and `labels_include_all`, `labels_include_any`, or `labels_exclude_any` list of label names. | | scripts | array | body | A list of script files to add to this team so they can be executed at a later time. | | software | object | body | The team's software that will be available for install. | +| software.app_store_apps | array | body | An array of objects with values below. | +| software.app_store_apps.app_store_id | string | body | ID of the App Store app. | +| software.app_store_apps.self_service | boolean | body | Specifies whether or not end users can install self-service. | +| software.app_store_apps.labels_include_any | array | body | Specifies whether the app will only be available for install on hosts that **have any** of these labels. Only one of either `labels_include_any` or `labels_exclude_any` can be specified. | +| software.app_store_apps.labels_exclude_any | array | body | Specifies whether the app will only be available for install on hosts that **don't have any** of these labels. Only one of either `labels_include_any` or `labels_exclude_any` can be specified. | | software.packages | array | body | An array of objects with values below. | | software.packages.url | string | body | URL to the software package (PKG, MSI, EXE or DEB). | | software.packages.install_script | string | body | Command that Fleet runs to install software. | @@ -1815,9 +1820,6 @@ If the `name` is not already associated with an existing team, this API route cr | software.packages.self_service | boolean | body | If `true` lists software in the self-service. | | software.packages.labels_include_any | array | body | Target hosts that have any label in the array. Only one of `labels_include_any` or `labels_exclude_any` can be included. If neither are included, all hosts are targeted. | | software.packages.labels_exclude_any | array | body | Target hosts that don't have any label in the array. Only one of `labels_include_any` or `labels_exclude_any` can be included. If neither are included, all hosts are targeted. | -| software.app_store_apps | array | body | An array of objects with values below. | -| software.app_store_apps.app_store_id | string | body | ID of the App Store app. | -| software.app_store_apps.self_service | boolean | body | Specifies whether or not end users can install self-service. | | mdm.macos_settings.enable_disk_encryption | bool | body | Whether disk encryption should be enabled for hosts that belong to this team. | | force | bool | query | Force apply the spec even if there are (ignorable) validation errors. Those are unknown keys and agent options-related validations. | | dry_run | bool | query | Validate the provided JSON for unknown keys and invalid value types and return any validation errors, but do not apply the changes. | @@ -3775,6 +3777,8 @@ Body: `POST /api/fleet/orbit/software_install/details` +> Note: The `installer_url` in the response will only be populated if AWS S3 and CloudFront URL signing are configured. + ##### Parameters | Name | Type | In | Description | @@ -3808,6 +3812,10 @@ Body: "uninstall_script": "sudo run-uninstaller", "post_install_script": "echo done", "self_service": true, + "installer_url": { + "url": "https://d1nsa5964r3p4i.cloudfront.net/software-installers/98330e7e6db3507b444d576dc437a9ac4d82333a88a6bb6ef36a91fe3d85fa92?Expires=1736178766&Signature=HpcpyniNSBkS695mZhkZRjXo6UQ5JtXQ2sk0poLEMDMeF063IjsBj2O56rruzk3lomYFjqoxc3BdnFqEjrEXQSieSALiCufZ2LjTfWffs7f7qnNVZwlkg-upZd5KBfrCHSIyzMYSPhgWFPOpNRVqOc4NFXx8fxRLagK7NBKFAEfCAwo0~KMCSJiof0zWOdY0a8p0NNAbBn0uLqK7vZLwSttVpoK6ytWRaJlnemofWNvLaa~Et3p5wJJRfYGv73AK-pe4FMb8dc9vqGNSZaDAqw2SOdXrLhrpvSMjNmMO3OvTcGS9hVHMtJvBmgqvCMAWmHBK6v5C9BobSh4TCNLIuA__&Key-Pair-Id=K1HFGXOMBB6TFF", + "filename": "my-installer.pkg" + } } ``` @@ -4170,8 +4178,11 @@ _Available in Fleet Premium._ | team_name | string | query | The name of the team to add the software package to. Ommitting this parameter will add software to "No team". | | dry_run | bool | query | If `true`, will validate the provided VPP apps and return any validation errors, but will not apply the changes. | | app_store_apps | list | body | An array of objects. Each object contains `app_store_id` and `self_service`. | +| app_store_apps | list | body | An array of objects with . Each object contains `app_store_id` and `self_service`. | | app_store_apps.app_store_id | string | body | ID of the App Store app. | | app_store_apps.self_service | boolean | body | Whether the VPP app is "Self-service" or not. | +| app_store_apps.labels_include_any | array | body | App will only be available for install on hosts that **have any** of these labels. Only one of either `labels_include_any` or `labels_exclude_any` can be included in the request. | +| app_store_apps.labels_exclude_any | array | body | App will only be available for install on hosts that **don't have any** of these labels. Only one of either `labels_include_any` or `labels_exclude_any` can be included in the request. | #### Example @@ -4182,7 +4193,11 @@ _Available in Fleet Premium._ "app_store_apps": [ { "app_store_id": "597799333", - "self_service": false + "self_service": false, + "labels_include_any": [ + "Engineering", + "Customer Support" + ] }, { "app_store_id": "497799835", diff --git a/docs/Contributing/Audit-logs.md b/docs/Contributing/Audit-logs.md index e91981dbe863..9cfef253491d 100644 --- a/docs/Contributing/Audit-logs.md +++ b/docs/Contributing/Audit-logs.md @@ -952,6 +952,25 @@ This activity contains the following fields: } ``` +## modified_script + +Generated when a script is modified on a team (or no team). + +This activity contains the following fields: +- "script_name": Name of the script. +- "team_id": The ID of the team that the script applies to, `null` if it applies to devices that are not in a team. +- "team_name": The name of the team that the script applies to, `null` if it applies to devices that are not in a team. + +#### Example + +```json +{ + "script_name": "set-timezones.sh", + "team_id": 123, + "team_name": "Workstations" +} +``` + ## deleted_script Generated when a script is deleted from a team (or no team). @@ -1409,6 +1428,40 @@ This activity contains the following fields: } ``` +## edited_app_store_app + +Generated when an App Store app is updated in Fleet. + +This activity contains the following fields: +- "software_title": Name of the App Store app. +- "app_store_id": ID of the app on the Apple App Store. +- "platform": Platform of the app (`darwin`, `ios`, or `ipados`). +- "self_service": App installation can be initiated by device owner. +- "team_name": Name of the team to which this App Store app was added, or `null` if it was added to no team. +- "team_id": ID of the team to which this App Store app was added, or `null`if it was added to no team. +- "labels_include_any": Target hosts that have any label in the array. +- "labels_exclude_any": Target hosts that don't have any label in the array. + + +#### Example + +```json +{ + "software_title": "Logic Pro", + "app_store_id": "1234567", + "platform": "darwin", + "self_service": false, + "team_name": "Workstations", + "team_id": 1, + "labels_exclude_any": [ + { + "name": "Engineering", + "id": 12 + } + ] +} +``` + ## deleted_app_store_app Generated when an App Store app is deleted from Fleet. @@ -1420,7 +1473,7 @@ This activity contains the following fields: - "team_name": Name of the team from which this App Store app was deleted, or `null` if it was deleted from no team. - "team_id": ID of the team from which this App Store app was deleted, or `null`if it was deleted from no team. - "labels_include_any": Target hosts that have any label in the array. -- "labels_exclude_any": Target hosts that don't have any label in the array +- "labels_exclude_any": Target hosts that don't have any label in the array. #### Example @@ -1431,14 +1484,10 @@ This activity contains the following fields: "platform": "darwin", "team_name": "Workstations", "team_id": 1, - "labels_include_any": [ + "labels_exclude_any": [ { "name": "Engineering", "id": 12 - }, - { - "name": "Product", - "id": 17 } ] } diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md index 8807ce42c2b4..ac3661f31809 100644 --- a/docs/REST API/rest-api.md +++ b/docs/REST API/rest-api.md @@ -8719,11 +8719,11 @@ Get a list of all software. | min_cvss_score | integer | query | _Available in Fleet Premium_. Filters to include only software with vulnerabilities that have a CVSS version 3.x base score higher than the specified value. | | max_cvss_score | integer | query | _Available in Fleet Premium_. Filters to only include software with vulnerabilities that have a CVSS version 3.x base score lower than what's specified. | | exploit | boolean | query | _Available in Fleet Premium_. If `true`, filters to only include software with vulnerabilities that have been actively exploited in the wild (`cisa_known_exploit: true`). Default is `false`. | -| platform | string | query | Filter software by platform. Supported values are `darwin`, `windows`, and `linux`. | +| platform | string | query | Filter software titles by platforms. Options are: `"macos"` (alias of `"darwin"`), `"darwin"` `"windows"`, `"linux"`, `"chrome"`, `"ios"`, `"ipados"`. To show titles from multiple platforms, separate the platforms with commas (e.g. `?platform=darwin,windows`). | #### Example -`GET /api/v1/fleet/software/titles?team_id=3` +`GET /api/v1/fleet/software/titles?team_id=3&platform=darwin,windows` ##### Default response @@ -9090,6 +9090,12 @@ Returns information about the specified software. By default, `versions` are sor "latest_version": "2.04", "icon_url": "https://is1-ssl.mzstatic.com/image/thumb/Purple211/v4/f1/65/1e/a4844ccd-486d-455f-bb31-67336fe46b14/AppIcon-1x_U007emarketing-0-7-0-85-220-0.png/512x512bb.jpg", "self_service": true, + "automatic_install_policies": [ + { + "id": 345, + "name": "[Install software] Logic Pro", + } + ], "status": { "installed": 3, "pending": 1, @@ -9554,7 +9560,8 @@ Returns information about the specified Fleet-maintained app. "fleet_maintained_app": { "id": 1, "name": "1Password", - "version": "8.10.40", + "filename": "1Password-8.10.50-aarch64.zip", + "version": "8.10.50", "platform": "darwin", "install_script": "#!/bin/sh\ninstaller -pkg \"$INSTALLER_PATH\" -target /", "uninstall_script": "#!/bin/sh\npkg_ids=$PACKAGE_ID\nfor pkg_id in '${pkg_ids[@]}'...", diff --git a/website/assets/images/articles/fleet-4.63.0-1600x900@2x.png b/website/assets/images/articles/fleet-4.63.0-1600x900@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..cc7e2021919fe6f73e6a1bad8800e588ae0e19c9 GIT binary patch literal 53884 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

%P9AgtJe(9Npjb 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 Dahnb> literal 0 HcmV?d00001