Jamf Setup Components

Implementing Single Login

Single Login is built entirely on Microsoft's identity stack: the Microsoft Authentication Library (MSAL) and Shared Device Mode, brokered by the Microsoft Enterprise SSO plug-in for Apple devices.

📘

Microsoft is the source of truth

Every requirement on this page is defined and maintained by Microsoft. The links throughout point to the exact Microsoft articles you should follow; treat them as authoritative. If Microsoft's guidance and this page ever differ, follow Microsoft. Jamf's role is covered separately in Jamf Setup & Single Login orchestration.

Your app has two jobs: sign in silently when a session starts (login), and clear the session when it ends (logout). Both are standard Shared Device Mode behaviors. Microsoft's Shared device mode overview describes the same admin/developer split this page follows.

Prerequisites (configured in Microsoft Entra)

These are Microsoft requirements you complete before writing app code. You cannot initialize MSAL without them.

  1. Register your application in Microsoft Entra ID. This produces the Application (client) ID your app authenticates as. Follow Microsoft's Register an application. For an ISV serving many customers, register a multitenant app (see Supported account types in that article).
  2. Add an iOS/macOS platform redirect URI. Follow Add a redirect URI and the iOS steps in Configure a mobile app that calls web APIs. The format is msauth.<BUNDLE_ID>://auth.
  3. Enable public client flows on the app registration. See the same Microsoft article.
  4. Add MSAL and configure Xcode (keychain access group, URL schemes). Follow Microsoft's Prepare your iOS (Swift) app for authentication and Enable keychain access groups.

Use MSAL for iOS and macOS version 1.1.0 or later, configured as a single-account public client application. Your client ID and authority live in your own MSAL configuration; the globally signed-in account carries the tenant.

Detect Shared Device Mode

Per Microsoft's Detect shared device mode, use getDeviceInformation and adapt your UX (for example, hide "Sign up").

application.getDeviceInformation(with: nil, completionBlock: { (deviceInformation, error) in
    guard let deviceInfo = deviceInformation else { return }
    let isSharedDevice = deviceInfo.deviceMode == .shared
    // Adjust your app UX if needed
})

Login: sign in silently

When a session has started, the account is already on the device. Call acquireTokenSilent to get a token with no prompt. This is what makes your app open already authenticated. Fall back to interactive acquireToken only when there is no account or the token is invalid. See Microsoft's Globally sign in a user.

application.acquireTokenSilent(with: silentParameters) { (result, error) in
    if let result = result {
        // Signed in — use result.accessToken
    } else {
        // No valid account/token — fall back to interactive acquireToken
    }
}

Logout: clear the session

In Shared Device Mode, sign-out is global — every supported app must end its session. Your app is notified through a Microsoft Entra account-change broadcast (a Darwin notification); confirm the change with getCurrentAccount and clear the previous user's data. Follow Microsoft's Get the signed-in user and determine if a user has changed and Receive a broadcast to detect global sign out.

MSAL clears the cached tokens. Clearing your app's own session state and any cached or displayed user data is your responsibility — Microsoft makes this explicit.

// Register a listener for the account-change broadcast (Darwin notification),
// then on each callback:
application.getCurrentAccount(with: msalParameters) { (currentAccount, previousAccount, error) in
    if currentAccount == nil {
        // User signed out — clear session, cached data, and anything on screen
    } else if currentAccount?.identifier != previousAccount?.identifier {
        // A different user — clear the previous user's data before continuing
    }
}

Your app can also initiate a global sign-out itself with signout (optionally signoutFromBrowser) — see Microsoft's Globally sign out a user.

MSAL methods used in Single Login

MethodRoleMicrosoft reference
getDeviceInformationDetect Shared Device ModeDetect shared device mode
acquireTokenSilentLogin — silently sign in the account on the deviceGlobally sign in a user
acquireTokenInteractive fallback when no valid account/token existsGlobally sign in a user
getCurrentAccountOn broadcast, confirm the account changed or clearedGet the signed-in user
signoutOptionally initiate a global sign-out from your appGlobally sign out a user

Validate your integration

  • Login — when a session starts on the device, your app opens already signed in, with no prompt.
  • Logout — when the session ends, your app signs out and removes the previous user's data, with nothing left on screen.
❗️

Test on a real device. Xcode Simulator is not a full iOS framework, can't enroll in MDM, and won't reflect the shared-device workflow.

Setting up a device to drive these events (Jamf Setup, Jamf Reset, Jamf Pro configuration) is administrator setup, not app code — see Jamf Setup & Single Login orchestration.

Microsoft references


Did this page help you?