You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We don't want SSO to pop up during macOS setup experience.
Goal
User story
As a Fleet user,
I want to require that my end users are signed-in via SSO (IdP) before they can access Fleet Desktop on their macOS, Windows, Linux, or iOS/iPadOS host
so that I can enforce an extra layer of authentication.
Database schema migrations: None. App config is stored as a single JSON blob (app_config_json); the new fleet_desktop.sso_enabled key needs no migration.
Load testing: Not required. The SSO gate adds one session lookup per device-page API call, only when the setting is enabled; the high-volume fleetd polling endpoints (/desktop, /ping) are excluded and unchanged.
Pre-QA load test: Not required — the setting defaults to off and the change doesn't measurably modify Fleet's load profile.
Load testing/osquery-perf improvements: None.
This is a premium only feature: Yes
ℹ️ Please read this issue carefully and understand it. Pay special attention to UI wireframes, especially "dev notes".
Risk description: fleet_desktop.sso_enabled defaults to false, so every PR merges with zero behavior change until an admin enables it; enforcement is new code alongside (not replacing) existing device auth. Watch for: device-endpoint regressions with the setting off (pinned by snapshot tests in Fleet Desktop SSO: enforcement gate and exclusion list #51521), and the excluded fleetd endpoints (/desktop, /ping, /debug/errors) which must never be gated.
Test plan
Make sure to go through the list and consider all events that might be related to this story, so we catch edge cases earlier.
Core flow
Prerequisites: Fleet Premium; an IdP configured in Settings > Integrations > Authentication (SSO) > End users; at least one host enrolled with fleetd.
As a global admin, go to Settings > Organization settings > Fleet Desktop. Verify the End user authentication radio group renders per Figma with Hourly token rotation selected by default, and select Single sign-on (SSO), then Save.
Verify the enabled_sso_fleet_desktop activity appears in the activity feed (no detail fields).
On an enrolled host, verify the Fleet Desktop tray is unaffected: icon reaches "🟢 My device" (or "🔴 My device (N)" with failing policies), and Self service / About Fleet items appear as before.
Click My device in the tray. Verify the browser is redirected to the IdP sign-in page, and after signing in, lands on the My device page with full data.
Reload the My device page and navigate to Self-service / Software / Policies tabs. Verify no second IdP prompt (session persists).
Call a device API endpoint directly with only the token (e.g. curl -i https://<server>/api/latest/fleet/device/<token>, no cookies). Verify 401 whose JSON body includes "sso_required": true. Verify every excluded endpoint still behaves exactly as with the setting off: GET .../desktop and HEAD .../ping return 200, GET .../transparency redirects, POST .../debug/errors accepts a report, and POST .../sso starts the flow.
Switch the setting back to Hourly token rotation. Verify the disabled_sso_fleet_desktop activity, and that the My device page works with the token alone again.
Edge cases
With no IdP configured: verify the SSO radio is disabled with tooltip "This setting requires an IdP configured in Settings > Integrations > Authentication (SSO) > End users.", and PATCH /api/v1/fleet/config with {"fleet_desktop":{"sso_enabled":true}} returns 422 naming the missing IdP.
Configure the IdP and sso_enabled: true in the same PATCH payload — succeeds.
With SSO enabled, attempt to clear mdm.end_user_authentication (UI and API). Verify 422 telling the user to disable Fleet Desktop SSO first; after disabling SSO, clearing the IdP succeeds.
Re-asserting the same sso_enabled value (true→true, false→false) generates no activity.
Session expiry: after the device SSO session TTL elapses (or with the cookie deleted), the next My device visit re-prompts the IdP once — no redirect loop.
Cookie/host binding: use host A's browser session cookie with host B's device token — expect 401.
Invalid/expired device token with a valid SSO session — expect the existing "This URL is invalid or expired." error, not an SSO redirect.
Setup Experience with ADE end user authentication off (mdm.macos_setup.enable_end_user_authentication: false): repeat the check above. The gate exempts every host that is awaiting configuration, whether or not the end user authenticated to the IdP during enrollment, so this path needs its own pass rather than being assumed from the case above.
Setup Experience release window: watch the Setup Assistant web view at the moment setup completes and the device is released. Verify it does not flash an IdP redirect or an error before closing. The exemption is keyed on the host still awaiting configuration, and that flag clears when the device acknowledges DeviceConfigured — which can happen while the web view is still open showing its "done" state.
Setup Experience exemption boundary: while a host is awaiting configuration, curl -i https://<server>/api/latest/fleet/device/<token> with no cookies returns 200 — this carve-out is deliberate, and means a leaked device URL reaches device endpoints without SSO for the duration of setup. Re-run the same call after setup completes and verify it returns 401 with "sso_required": true.
Fleet Desktop Migrate to Fleet: with SSO enabled and no browser session, trigger the tray's migration dialog on a host pending MDM migration. Verify the migration webhook still fires — POST /device/{token}/migrate_mdm is exempt from the gate because fleetd posts it with the device token alone and has no browser in which to sign in.
alternative_browser_host set (proxy topology): verify the full SSO round-trip works when browsing through the alternative host.
iOS/iPadOS host: verify the device page SSO flow works with certificate-based device auth.
Hosts enrolled before the feature was enabled behave identically to newly enrolled hosts.
UI
Verify that all UI changes specified in the Figma wireframes are correctly implemented (radio group, labels, updated section description, disabled-state tooltip)
Verify expected UI states (loading, empty, error states if applicable), including the My device page "redirecting to sign-in" and SSO-failure states
API
Test all API endpoints added or modified in the API changes section of this issue (fleet_desktop.sso_enabled on GET/PATCH /api/v1/fleet/config; POST /api/_version_/fleet/device/{token}/sso; SSO-required 401 on gated device endpoints)
Verify any new API endpoints appear in the list when adding an API-only user. The API endpoints display name, method, and path is the same as listed in the API reference docs
Verify error handling for invalid inputs where applicable (sso_enabled non-boolean; enabling without IdP; enabling on Free)
GitOps (generate + run)
Configure the feature through the UI and run fleetctl generate-gitops
Confirm the generated .yml includes the expected fields (org_settings.fleet_desktop.sso_enabled, compare with YAML changes in the Product section)
Modify the generated .yml and run fleetctl gitops
Confirm the configuration updates correctly in Fleet (including the toggle activity)
Enable GitOps mode and verify the feature behaves correctly (End user authentication radios disabled in the UI)
Permissions
Verify role restrictions are applied correctly for global roles (admin, maintainer, observer, observer+, GitOps) — only roles that can modify org settings can change the setting; observers see it read-only per existing org-settings behavior
Verify role restrictions are applied correctly for fleet-level roles — fleet-scoped users cannot modify this global setting
Premium gating (if this is a premium-only feature)
Verify the feature is blocked on Fleet Free in the frontend (Fleet Desktop section absent from org settings nav)
Verify the feature is blocked on Fleet Free in the backend (PATCH /config with sso_enabled: true returns the license error; license downgrade resets the value to false)
Upgrade / data migration
Verify behavior on a server upgraded from a prior version (not just a fresh install) — existing fleet_desktop config is preserved and sso_enabled defaults to false
Verify existing data is migrated/handled correctly (no migration required; app config JSON gains the key on first save)
Feature in isolation (MDM / platform independence)
Verify the feature works on a fully configured server (all MDM platforms enabled)
Verify the feature works in isolation — Apple MDM off with only the End users IdP configured (the SSO callback route must not require Apple MDM); Windows-only and Linux-only hosts complete the flow
Supplemental testing
Testing notes
Confirmation
Engineer: Added comment to user story confirming successful completion of test plan (include any special setup, test data, or configuration used during development/testing if applicable).
QA: Added comment to user story confirming successful completion of test plan.
QA: Determined whether this story needs Playwright automation.
Needs automation: Yes / No
If yes, filed a follow-up issue in the :help-qa project with status "Needs automation":
@noahtalerman: Let's plan on addressing this at the same time:
We don't want SSO to pop up during macOS setup experience.
Goal
Changes
Product
Get Fleet Desktop informationfleet_desktop>sso_enabledkey in generated GitOps YAML.Engineering
Sub-tasks:
Fleet Desktop SSO: config setting, activities, and usage statistics #51519 Fleet Desktop SSO: config setting, activities, and usage statistics
Fleet Desktop SSO: device SSO endpoints and session plumbing #51520 Fleet Desktop SSO: device SSO endpoints and session plumbing
Fleet Desktop SSO: enforcement gate and exclusion list #51521 Fleet Desktop SSO: enforcement gate and exclusion list
Fleet Desktop SSO: organization settings UI and activity feed #51522 Fleet Desktop SSO: organization settings UI and activity feed
Fleet Desktop SSO: My device page SSO flow #51523 Fleet Desktop SSO: My device page SSO flow
Test plan is finalized
Contributor API changes: New
POST /api/_version_/fleet/device/{token}/ssoendpoint and the SSO-required 401 contract for gated device endpoints, documented indocs/Contributing/reference/api-for-contributors.mdas part of Fleet Desktop SSO: device SSO endpoints and session plumbing #51520 and Fleet Desktop SSO: enforcement gate and exclusion list #51521.Feature guide changes: No new guide. Doc changes ride the in-flight PRs Update rest-api.md #51155 (REST API + YAML), Update audit-logs.md #51160 (audit log), #47116 Usage statistics #51166 (usage statistics).
Database schema migrations: None. App config is stored as a single JSON blob (
app_config_json); the newfleet_desktop.sso_enabledkey needs no migration.Load testing: Not required. The SSO gate adds one session lookup per device-page API call, only when the setting is enabled; the high-volume fleetd polling endpoints (
/desktop,/ping) are excluded and unchanged.Pre-QA load test: Not required — the setting defaults to off and the change doesn't measurably modify Fleet's load profile.
Load testing/osquery-perf improvements: None.
This is a premium only feature: Yes
Risk assessment
alternative_browser_hosttopology.fleet_desktop.sso_enableddefaults to false, so every PR merges with zero behavior change until an admin enables it; enforcement is new code alongside (not replacing) existing device auth. Watch for: device-endpoint regressions with the setting off (pinned by snapshot tests in Fleet Desktop SSO: enforcement gate and exclusion list #51521), and the excluded fleetd endpoints (/desktop,/ping,/debug/errors) which must never be gated.Test plan
Core flow
Prerequisites: Fleet Premium; an IdP configured in Settings > Integrations > Authentication (SSO) > End users; at least one host enrolled with fleetd.
curl -i https://<server>/api/latest/fleet/device/<token>, no cookies). Verify 401 whose JSON body includes"sso_required": true. Verify every excluded endpoint still behaves exactly as with the setting off:GET .../desktopandHEAD .../pingreturn 200,GET .../transparencyredirects,POST .../debug/errorsaccepts a report, andPOST .../ssostarts the flow.Edge cases
PATCH /api/v1/fleet/configwith{"fleet_desktop":{"sso_enabled":true}}returns 422 naming the missing IdP.sso_enabled: truein the same PATCH payload — succeeds.sso_enabledvalue (true→true, false→false) generates no activity.mdm.macos_setup.enable_end_user_authentication: false): repeat the check above. The gate exempts every host that is awaiting configuration, whether or not the end user authenticated to the IdP during enrollment, so this path needs its own pass rather than being assumed from the case above.DeviceConfigured— which can happen while the web view is still open showing its "done" state.curl -i https://<server>/api/latest/fleet/device/<token>with no cookies returns 200 — this carve-out is deliberate, and means a leaked device URL reaches device endpoints without SSO for the duration of setup. Re-run the same call after setup completes and verify it returns 401 with"sso_required": true.POST /device/{token}/migrate_mdmis exempt from the gate because fleetd posts it with the device token alone and has no browser in which to sign in.alternative_browser_hostset (proxy topology): verify the full SSO round-trip works when browsing through the alternative host.UI
API
fleet_desktop.sso_enabledonGET/PATCH /api/v1/fleet/config;POST /api/_version_/fleet/device/{token}/sso; SSO-required 401 on gated device endpoints)sso_enablednon-boolean; enabling without IdP; enabling on Free)GitOps (generate + run)
fleetctl generate-gitops.ymlincludes the expected fields (org_settings.fleet_desktop.sso_enabled, compare with YAML changes in the Product section).ymland runfleetctl gitopsPermissions
Premium gating (if this is a premium-only feature)
PATCH /configwithsso_enabled: truereturns the license error; license downgrade resets the value to false)Upgrade / data migration
fleet_desktopconfig is preserved andsso_enableddefaults to falseFeature in isolation (MDM / platform independence)
Supplemental testing
Testing notes
Confirmation