# Setup experience
_Available in Fleet Premium_
In Fleet, you can customize the out-of-the-box macOS, Windows, Linux, iOS, iPadOS, and Android setup.
This guide covers macOS, iOS, iPadOS, and Android. Learn more about Windows and Linux in a [separate guide](https://fleetdm.com/guides/windows-linux-setup-experience).
macOS setup features require [connecting Fleet to Apple Business (AB)](https://fleetdm.com/guides/macos-mdm-setup#apple-business-manager-abm).
> For macOS, Fleet only installs setup experience software and run scripts on newly enrolling, or re-enrolling, Macs (not during migration).
Below is the end user experience for macOS. Check out the separate videos for [iOS](https://www.youtube.com/watch?v=bPtr3Qgp1JY), [iPadOS](https://www.youtube.com/watch?v=sK3ZR2iItJY), and [Android](https://www.youtube.com/watch?v=-zB1zgtGAMs).
## End user authentication
You can require IdP authentication during automatic enrollment (ADE) for Apple (macOS, iOS, iPadOS) hosts and manual enrollment for personal (BYOD) iOS, iPadOS, and Android hosts. IdP authentication is also supported on [Windows and Linux](https://fleetdm.com/guides/windows-linux-setup-experience). End users can use passkeys, such as YubiKeys, with macOS hosts during the authentication process.
1. Create a new SAML app in your IdP. In your new app, use `https:///api/v1/fleet/mdm/sso/callback` for the SSO URL. If this URL is set incorrectly, end users won't be able to enroll. On iOS hosts, they'll see a "This screen size is not supported yet" error message.
2. In your new SAML app, set **Name ID** to email (required). Fleet will trim this email and use it
to populate the macOS local account **Account Name**. For example, a
"johndoe@example.com" email will turn into a "johndoe" account name.
> If the host is restarted during automatic enrollment (DEP), the macOS local account fields won't be populated with the user's IDP email and username.
3. Make sure your end users' full names are set to one of the following attributes (depends on IdP): `name`, `displayname`, `cn`, `urn:oid:2.5.4.3`, or `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name`. Fleet will automatically populate the macOS local account **Full Name** with any of these.
4. In Fleet, configure your IdP by heading to **Settings > Integrations > Authentication (SSO) > End users**. Then, enable IdP authentication by heading to **Controls > Setup experience > Require IdP authentication**. Alternatively, you can use [Fleet's GitOps workflow](https://fleetdm.com/docs/configuration/yaml-files) to configure your IdP integration and enable IdP authentication.
> If you've already configured [single sign-on
> (SSO)](https://fleetdm.com/docs/deploy/single-sign-on-sso) in Fleet, you still want to create a
> new SAML app for IdP authentication. This way, only Fleet users can log in to Fleet.
## End user account type
During setup, the end user's local account is created as either an **admin** or **standard** account. The account type determines what the end user can do on their device.
### Standard vs. admin accounts
| Capability | Admin | Standard |
| --- | --- | --- |
| Install system-wide software | ✅ | |
| Change system settings (e.g. network, firewall, date/time) | ✅ | |
| Create, modify, or delete other user accounts | ✅ | |
| Access and modify all files on the device | ✅ | |
| Run applications from their own user space | ✅ | ✅ |
| Use peripherals and personal settings | ✅ | ✅ |
These capabilities apply across macOS, Windows, and Linux. On all three platforms, standard accounts are restricted from making system-level changes, while admin accounts have full control over the device.
### OS default account types
Each operating system assigns a default account type when a user account is created during initial device setup:
| Platform | Default account type |
| --- | --- |
| macOS | Admin |
| Windows | Admin |
| Linux | Standard |
> Many organizations prefer standard accounts for end users to reduce the attack surface and prevent accidental system-level changes. Fleet lets you override the OS defaults to enforce this.
### Controlling account type with Fleet
Fleet's `end_user_local_account_type` setting lets you enforce either `admin`, `standard`, or `none` as the account type for the end user's local account on macOS hosts that automatically enroll via Apple Business (AB).
To configure via the Fleet UI:
1. Head to **Controls > Setup experience**.
2. Under the managed local account options, choose **Admin**, **Standard**, or **Skip (no account)** for the end user account type.
To configure via GitOps, set the `end_user_local_account_type` field under `mdm.macos_setup` in your YAML configuration:
```yaml
mdm:
macos_setup:
end_user_local_account_type: "standard"
```
Valid values are `"admin"`, `"standard"`, and `"none"`. When set to `"standard"`, Fleet creates the end user's local account as a standard (non-admin) account during macOS setup, regardless of the OS default. When set to `"none"`, Fleet skips creating the end user's local account during macOS setup, leaving the device with only the managed local admin account provisioned by Fleet.
> This setting applies to macOS hosts that automatically enroll via Apple Business (AB). For Windows and Linux, account type is controlled by the operating system during setup.
> System-scoped profiles apply device-wide, including to any Fleet-managed local admin account. Admins are responsible for ensuring profile scope (`PayloadScope`) aligns with their intended targets.
## Managed local account
Fleet can create a hidden admin account (`_fleetadmin`) with a unique password on each eligible host during setup. IT admins can use this account as a break-glass login for troubleshooting.
This feature is available for macOS hosts that automatically enroll via Apple Business (AB) and Windows hosts that automatically enroll via Azure AD. Manually enrolled hosts are not supported.
To enable managed local accounts:
1. In Fleet, head to **Controls > Setup experience > Users** and select the platform (macOS or Windows), then choose **Managed > Create hidden admin**. Alternatively, you can enable this using [Fleet's REST API](https://fleetdm.com/docs/rest-api/rest-api#update-setup-experience) or [GitOps workflow](https://fleetdm.com/docs/configuration/yaml-files).
2. Wipe and re-enroll any existing hosts that should receive the account. Hosts enrolled before the feature is turned on won't receive a managed account until they go through the setup experience again.
To view the password for a host's managed account, head to **Host details > Actions > Show managed account**. The password is unique per host and stored securely in Fleet.
### macOS
> The managed account is hidden from the macOS login window. To log in as `_fleetadmin`, click **Other** on the login window (or press the username field) and type the username and password manually.
> The managed account does not have a Secure Token. To access a FileVault-encrypted disk, first unlock it using the [escrowed recovery key](https://fleetdm.com/guides/macos-mdm-setup#disk-encryption), then log in as `_fleetadmin` at the login window.
> On macOS 15.7, if the end user account type is set to **Standard** or **Skip (no account)**, FileVault cannot be enabled locally through System Settings by the managed local account. To encrypt the disk, [enforce disk encryption via Fleet](https://fleetdm.com/guides/enforce-disk-encryption) instead. This issue does not affect macOS 26.
### Windows
> The managed account is hidden from the Windows sign-in screen. To log in as _fleetadmin, select **Other user** on the sign-in screen and enter the username and password manually.
## Platform SSO
Fleet supports configuring Platform SSO (PSSO) for macOS hosts with the option to create a local user account during enrollment. If you use Okta, see [Deploying Okta Platform SSO with Fleet](https://fleetdm.com/guides/deploying-okta-platform-sso-with-fleet) for setup instructions. PSSO can be used with or without [end user authentication](#end-user-authentication) enabled.
Fleet also supports using the Fleet Desktop app's built-in PSSO extension to achieve initial account provisioning during setup and password sync with any OAuth ROPG IdP for use cases where a native IdP PSSO integration is unavailable or is not configured. See [Deploying Apple Account Provisioning with Fleet](https://fleetdm.com/guides/deploying-apple-account-provisioning-with-fleet).
## End user license agreement (EULA)
To require a EULA, in Fleet, head to **Settings > Integrations > MDM > End user license agreement (EULA)** or use the [Fleet API](https://fleetdm.com/docs/rest-api/rest-api#upload-an-eula-file).
Currently, the EULA is only displayed for macOS hosts that automatically enroll via Apple Business (AB).
## Managed local account
Fleet can create and manage a local admin account on macOS hosts that automatically enroll via Apple Business (AB). This account gives IT admins a secure way to access a macOS host for troubleshooting without relying on shared or static credentials.
Admins can view the current password from **Host details > Show managed account** in the Fleet UI or via the API.
### Password rotation
Fleet rotates the managed local account password by sending an MDM command to the host. Rotation can be triggered manually by clicking **Rotate password** in the managed account modal, or automatically after the password is viewed.
> Shortly after a host enrolls via DEP, the host's UUID may not yet be known to Fleet. In this case, password rotation is **deferred** until Fleet receives the UUID (typically after the host completes its first check-in). Any pending rotation will proceed automatically once the UUID is available.
A manual rotation cancels any active auto-rotation timer for that host.
## Bootstrap package
Fleet supports installing a bootstrap package on macOS hosts that automatically enroll to Fleet. Apple requires that your package is a [distribution package](https://fleetdm.com/learn-more-about/macos-distribution-packages). You can install software during out-of-the-box Windows and Linux setup. Learn more in [this separate guide](https://fleetdm.com/guides/windows-linux-setup-experience).
> Fleet will always deliver the command to install a bootstrap package before delivering commands for installing profiles.
This enables installing tools like [Puppet](https://www.puppet.com/), [Munki](https://www.munki.org/munki/), or [Chef](https://www.chef.io/products/chef-infra) for configuration management and/or running custom scripts and installing tools like [DEP notify](https://gitlab.com/Mactroll/DEPNotify) to customize the setup experience for your end users.
By default, the bootstrap package is not installed during [MDM migration](https://fleetdm.com/guides/mdm-migration) or when a host is enrolled by running `sudo profiles renew -type enrollment`. To change this behavior, you can set the [`fleet_allow_bootstrap_package_during_migration`](https://fleetdm.com/docs/configuration/fleet-server-configuration#fleet-allow-bootstrap-package-during-migration) server configuration.
Fleet's agent (fleetd) is also installed during [MDM migration](https://fleetdm.com/guides/mdm-migration) and when the enrollment profile is renewed manually by running `sudo profiles renew -type enrollment`. If you [manually install fleetd](#manually-install-fleetd), fleetd won't be installed.
The following are examples of what some organizations deploy using a bootstrap package:
* Munki client to install and keep software up to date on your Macs
* Puppet agent to run custom scripts on your Macs
* Custom scripts and several packages bundled into one bootstrap package using a tool like [InstallApplications](https://github.com/macadmins/installapplications) to install a base set of applications, set the Mac's background, and install the latest macOS update for the end user.
To add a bootstrap package to Fleet, we will do the following steps:
1. Download or generate a package
2. Sign the package
3. Upload the package to Fleet
4. Confirm package is uploaded
### Step 1: Download or generate a package
Whether you have to download or generate a package depends on what you want to deploy using your bootstrap package:
* A single client or agent, like Munki or Puppet, can usually be downloaded from the tool's GitHub repository or website. For example, you can download Munki, the Munki client on their [releases page on GitHub](https://github.com/munki/munki/releases).
> Packages deployed via bootstrap need to be signed. The packages on the official Munki release page above are not signed. You will either need to sign the package yourself (see Step 2 below) or use an already signed release from [MacAdmins Open Source](https://github.com/macadmins/munki-builds/releases).
* To deploy custom scripts, you need to generate a package. The [munkipkg tool](https://github.com/munki/munki-pkg) is a popular tool for generating packages.
Verify that the package is a distribution package:
1. Run the following commands to expand your package and look at the files in the expanded folder:
```bash
$ pkgutil --expand package.pkg expanded-package
$ ls expanded-package
```
If your package is a distribution package you should see a `Distribution` file.
2. If you don't see a `Distribution` file, run the following command to convert your package into a distribution package.
```bash
$ productbuild --package package.pkg distrbution-package.pkg
```
Make sure your package is a `.pkg` file.
### Step 2: Sign the package
To sign the package we need a valid Developer ID Installer certificate:
1. Login to your [Apple Developer account](https://developer.apple.com/account).
2. Follow [Apple's instructions to create a Developer ID Installer certificate](https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates).
> During step 3 in Apple's instructions, make sure you choose "Developer ID Installer." You'll need this kind of certificate to sign the package.
Confirm that certificate is installed on your Mac by opening the **Keychain Access** application. You should see your certificate in the **Certificates** tab.
3. Run the following command in the **Terminal** application to sign your package with your Developer ID certificate:
```bash
$ productsign --sign "Developer ID Installer: Your name (Serial number)" /path/to/package.pkg /path/to/signed-package.pkg
```
You might be prompted to enter the password for your local account.
Confirm that your package is signed by running the following command:
```bash
$ pkgutil --check-signature /path/to/signed-package.pkg
```
In the output you should see that your package has a "signed" status.
### Step 3: Upload the package to Fleet
1. Head to the **Controls > Setup experience > Bootstrap package** page.
2. Choose which fleet you want to add the bootstrap package to by selecting the desired fleet in the fleets dropdown in the upper left corner.
3. Select **Upload** and choose your bootstrap package.
## Install software
You can install software during first time macOS, iOS, iPadOS, Android, and [Windows and Linux setup](https://fleetdm.com/guides/windows-linux-setup-experience).
Currently, for macOS hosts, software is only installed on hosts that automatically enroll to Fleet via Apple Business (AB).
On Windows and Linux hosts, Fleet checks policies before installing setup experience software. If the host already passes the software's associated policies, the install is skipped. Learn more in the [Windows and Linux setup experience guide](https://fleetdm.com/guides/windows-linux-setup-experience#policies-are-checked-before-install). On macOS, iOS, iPadOS, and Android, software is always installed.
Add setup experience software:
1. Click on the **Controls** tab in the main navigation bar, then **Setup experience** > **4. Install software**.
2. Click **Add software**, then select or search for the software you want installed during the setup experience.
3. Press **Save** to save your selection.
To see the end user experience on iOS/iPadOS, check out the [iOS video](https://www.youtube.com/shorts/_XXNGrQPqys) and [iPadOS video](https://www.youtube.com/shorts/IIzo4NyUolM)
### Retries
For macOS, Windows, and Linux hosts, custom packages and Fleet-maintained app installs are automatically attempted up to 3 times (1 initial attempt + 2 retries) to handle intermittent network issues or temporary failures. When Fleet retries, IT admins can see error messages for all attempts in the **Host details > Activity** card. The end user only sees an error message if the third, and final, attempt fails.
For App Store (VPP) apps, VPP app installs are automatically attempted up to 4 times (1 initial attempt + 3 retries).
#### Stop setup on failed software installs
For macOS hosts, you can configure the setup experience to stop if any software item fails to install:
1. In **Controls > Setup experience > Install software > macOS**, select **Show advanced options**.
2. Check the **Cancel setup if software install fails** checkbox.
3. Select **Save**.
When this feature is enabled, any failed software will immediately end the setup experience and instruct the end user to restart their Mac:

End users won't continue through setup experience unless they press Command (⌘) + Shift + X.
### App Store (VPP) apps in setup experience
App Store (VPP) apps are installed by Apple. Fleet sends an [InstallApplication](https://developer.apple.com/documentation/devicemanagement/install-application-command) MDM command, and the device downloads and installs the app from the App Store. As a result, VPP installs during setup depend on Apple's services and the device's connection to the App Store while it's still in Setup Assistant.
Because Apple performs the install, things outside Fleet's control, such as an App Store or Apple Business outage, `InstallApplication` throttling, an expired VPP token, or too few licenses, can cause installs to fail or hang for every host at once. Fleet retries automatically (up to 4 attempts, waiting 10 minutes each time to verify), but retries won’t help while Apple itself is unavailable, and until an install finishes, the end user waits at the Setup Assistant screen.
To reduce these risks:
- Only add apps that end users need before their first login. Deliver everything else after enrollment using [automatic install](https://fleetdm.com/guides/automatic-software-install-in-fleet), which runs in the background and doesn't hold the device in Setup Assistant.
- Keep the setup experience software list short. Each item extends setup time.
- Before a large rollout, confirm your VPP token is valid and you have enough available licenses for the apps you're installing.
- If available, choose Fleet-maintained app over App Store (VPP) app for better control
If a host gets stuck, you can send the [`DeviceConfigured`](https://developer.apple.com/documentation/devicemanagement/device-configured-command) command using Fleet's [Run MDM command](https://fleetdm.com/docs/rest-api/rest-api#run-mdm-command) API to let the end user through.
## Run script
To configure a script to run during setup experience:
1. Click on the **Controls** tab in the main navigation bar, then **Setup experience** > **5. Run script**.
2. Click **Upload** and select a script (.sh file) from the file picker modal.
To replace the Fleet logo with your organization's logo:
1. Go to **Settings** > **Organization settings** > **Organization info**.
2. Add URLs to your logos in the **Organization avatar URL (for dark backgrounds)** and **Organization avatar URL (for light backgrounds)** fields.
3. Press **Save**.
> See [configuration documentation](https://fleetdm.com/docs/configuration/yaml-files#org-info) for recommended logo sizes.
> Setup experience software installs alphabetically (by name unless custom display name is added), one at a time. The setup script runs after all software installs are complete. Software won't appear in the upcoming activity until the previous install is complete (success or fail).
> Currently, software that [automatically installs](https://fleetdm.com/guides/automatic-software-install-in-fleet) and scripts that [automatically run](https://fleetdm.com/guides/policy-automation-run-script) are also installed and run during Setup Assistant but won't appear in the window. Automatic software and scripts may run before or after the setup experience software/script. They aren't installed/run in any particular order.
### Exiting the setup experience
The Fleet setup experience for macOS will exit if any of the following occurs:
* All setup steps complete successfully.
* All setup steps complete, including failed installs or script runs, with the "Cancel setup if software install fails" option _not_ enabled (see ["Blocking setup on failed software installs"](https://fleetdm.com/guides/macos-setup-experience#install-software)).
* The user presses Command (⌘) + Shift + X at any time during the setup process.
> If the end user is stuck, you can send the [DeviceConfigured](https://developer.apple.com/documentation/devicemanagement/device-configured-command) using Fleet's [Run MDM command](https://fleetdm.com/docs/rest-api/rest-api#run-mdm-command) API to let the user through.
## Setup Assistant
When an end user unboxes their new Apple device, or starts up a freshly wiped device, they're presented with the Setup Assistant. Here they see panes that allow them to configure accessibility, appearance, and more.
In Fleet, you can customize the Setup Assistant by using an automatic enrollment profile. Fleet uses [these options](https://github.com/fleetdm/fleet/blob/cf6343cbd4d02ce92df13339aca78cba2f5b43ff/server/mdm/apple/apple_mdm.go#L96-L126) by default. See all options in the [Apple docs](https://developer.apple.com/documentation/devicemanagement/profile).
To customize the Setup Assistant, we will do the following steps:
1. Create an automatic enrollment profile.
2. Upload the profile to Fleet.
3. Test the custom Setup Assistant.
> [Automatic enrollment profile delivery can take up to ten minutes](https://github.com/fleetdm/fleet/issues/27854#issuecomment-2811275551).
### Step 1: Create an automatic enrollment profile
1. Download Fleet's example automatic enrollment profile by navigating to [the example](https://fleetdm.com/example-dep-profile) 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 list of 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`. See [Apple's profile documentation](https://developer.apple.com/documentation/devicemanagement/profile) for valid fields.
The `await_device_configured` option is always set to `true` to allow Fleet to take actions like running scripts and installing software packages during the enrollment process.
If you'd like to release devices manually, you can check the "Release device manually" option in Setup experience > Setup Assistant > Show advanced options.
### Step 2: Upload the profile to Fleet
1. Head to the **Controls > Setup experience > Setup Assistant** page.
2. Choose which fleet you want to add the profile to by selecting the desired fleet in the fleets dropdown in the upper left corner.
3. Select **Add profile** and choose your profile package.
### Step 3: Test the custom Setup Assistant
Testing requires a test Mac that is present in your Apple Business (AB) account. We will wipe this Mac and use it to test the custom 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 appear in Fleet with MDM status set to "Pending." See our [automatic enrollment guide](https://fleetdm.com/guides/macos-mdm-setup#apple-business-manager) for more information.
3. Transfer this host to a test fleet by selecting the checkbox to the left of the host and selecting **Transfer** at the top of the table. In the modal, choose the test fleet and select **Transfer**.
4. Boot up your test Mac and complete the custom out-of-the-box setup experience.
## Configuring via REST API
Fleet also provides a REST API for managing setup experience software and scripts programmatically. Learn more about Fleet's [REST API](https://fleetdm.com/docs/rest-api/rest-api).
## Configuring via GitOps
To manage setup experience software and script using Fleet's best practice GitOps, check out the `setup_experience` key in the [GitOps reference documentation](https://fleetdm.com/docs/configuration/yaml-files#setup-experience)
## Advanced
### Manually install fleetd
> **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows.
By default, Fleet's agent (fleetd) is automatically installed during automatic enrollment (ADE) on macOS hosts. To deploy a custom fleetd agent on macOS hosts that automatically enroll, you can use a bootstrap package.
How to deploy a custom fleetd:
1. Generate your fleetd package by running the command `fleetctl package`, ensuring you do **not**
use the `--use-system-configuration` flag.
2. Add fleetd to your bootstrap package. To customize fleetd further, you can also add a script to modify fleetd's [launchd template](https://github.com/fleetdm/fleet/blob/fleet-v4.66.0/orbit/pkg/packaging/macos_templates.go#L96).
3. In Fleet, head to **Controls > Setup Experience > Bootstrap package** and add your bootstrap package. Make sure to check the option **Install Fleet’s agent (fleetd) manually** and then select **Save**.
4. Once the option to manually install Fleet's agent is checked, instead of using **Install software** and **Run script** options, include your software in the bootstrap package.
If you deploy a custom fleetd, also add the software and scripts you want to install/run during out-of-the-box macOS setup to your bootstrap package. Fleet won't install the software and run the script [configured in setup experience](#software-and-script).
### swiftDialog
Fleet uses [swiftDialog](https://github.com/swiftDialog/swiftDialog) to show end users [software install](#install-software) and [script run](#run-script) status. swiftDialog is only installed on macOS hosts if there is setup experience software or a script. After setup experinece, swiftDialog stays installed.