Skip to content

07-C9/xcreds-classlink-patch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 

Repository files navigation

XCreds ClassLink Patch

A modification to XCreds that makes ClassLink work properly as an OIDC identity provider for macOS login. Requires XCreds 5.9+ (getToken() added a required basicAuth parameter in 5.9).

XCreds ClassLink login window

Why this exists

ClassLink's OIDC implementation always redirects to a generic "Find your login page" screen at launchpad.classlink.com, no matter how you configure things. Users have to search for and select their district before they can log in.

I opened a case with ClassLink about this (Case #00606606). Their response:

"The redirect to the generic ClassLink page is intended with the OIDC/OAuth2 workflow. The reason being is this will allow for universal functionality. Unfortunately we cannot manipulate the issuer url to redirect to [your] login page. If JAMF Connect supports a SAML integration, this can be specified in the ClassLink SAML settings."

Neither Jamf Connect nor XCreds use SAML for login window auth. They use OIDC. I submitted feature requests to both ClassLink and Jamf, but as of early 2026 neither has addressed it.

What the patch does

One file is modified: WebViewController.swift. It adds two things.

Redirect interceptor

Stock XCreds handles OIDC redirects via didReceiveServerRedirectForProvisionalNavigation, which only catches HTTP 3xx server-side redirects. ClassLink uses client-side redirects, so stock XCreds never sees them and the webview ends up trying to load whatever your redirect URI points to (usually your school's website or localhost).

This patch adds an intercept in decidePolicyFor, which fires for all navigations including client-side redirects. When it sees a URL matching your configured redirectURI, it cancels the navigation before any HTTP request goes out, extracts the authorization code from the query string, and exchanges it for tokens. The user sees a "Signing in..." message during the exchange.

Tenant auto-navigation

When ClassLink loads the generic search page, JavaScript is injected that:

  • Shows a white overlay with a spinner ("Loading YourDistrict login...")
  • Searches for your tenant code in ClassLink's search bar
  • Clicks the matching result

The user never sees the generic search page. They see a brief spinner, then their district's login screen. If the script fails (ClassLink redesigns their page, network issue, etc.), a 5-second timeout removes the overlay and falls back to the generic search page.

ClassLink URL styles

ClassLink has two URL formats for district login pages. Check which one yours uses before configuring.

URL style Example Status
Launchpad (most districts) launchpad.classlink.com/yourdistrict Working
Login (districts with passkeys) login.classlink.com/my/yourdistrict Working, lightly tested

To check: visit launchpad.classlink.com/yourdistrict in a browser. If it stays on launchpad.classlink.com, you have the Launchpad style. If it redirects to login.classlink.com/my/yourdistrict, you have the Login style.

Login-style districts

As of April 2026, login.classlink.com support is working but has limited testing outside of one external district.

  • https://login.classlink.com/.well-known/openid-configuration does not serve an OIDC discovery document (returns HTML). All of ClassLink's OIDC infrastructure still lives at launchpad.classlink.com.
  • Set idpHostName to launchpad.classlink.com, not login.classlink.com.
  • shouldSetGoogleAccessTypeToOffline must be true. ClassLink's token response often omits the refresh token, and this setting tells XCreds to accept that. Without it, token validation will fail.
  • Password capture is handled differently on login.classlink.com due to the page using a different frontend framework than launchpad.classlink.com.

Configuration

Patch preference keys

Key Type Required Description
classLinkTenant String Yes Your tenant code. The slug after launchpad.classlink.com/ or login.classlink.com/my/.
classLinkTenantDisplayName String No Friendly name shown on the loading overlay. Defaults to the search term or tenant code.
classLinkSearchTerm String No Use this if your tenant code doesn't work as a ClassLink search term. Some districts can only be found by district name, not tenant code.

To check if you need classLinkSearchTerm: go to launchpad.classlink.com and type your tenant code into the search bar. If your district shows up, you don't need it. If it doesn't, try your district name instead.

Standard XCreds keys

Key Value
discoveryURL https://launchpad.classlink.com/.well-known/openid-configuration
clientID Your ClassLink OIDC Client ID (from the Developer portal)
clientSecret Your ClassLink OIDC Client Secret
redirectURI The redirect URI configured in your ClassLink app (see below)
idpHostName launchpad.classlink.com (for both Launchpad and Login style districts)
shouldSetGoogleAccessTypeToOffline true (tells XCreds to accept token responses without a refresh token)

Redirect URI

ClassLink requires your redirect URI's domain to be verified in their Developer portal. We weren't able to get localhost or 127.0.0.1 verified, so we used our school's homepage URL.

ClassLink appends the authorization code to the redirect URI (e.g. https://www.yourschool.org/?code=abc123), and the interceptor catches it before any request is made, cancels the navigation, and completes the OAuth exchange.

Make sure the redirectURI in your XCreds config matches exactly what's set in your ClassLink Developer app.

ClassLink Developer Portal setup

  1. Create an OIDC application in the ClassLink Developer portal
  2. Add your redirect URI domain as a verified domain
  3. Set the redirect URI to match your XCreds config profile
  4. Note your Client ID and Client Secret

See example-classlink.mobileconfig for a working example.

Password sync

XCreds captures the password from the ClassLink login form at each login and sets the local account password to match. There's no real-time sync while logged in, the local password updates the next time the user logs in through the login window.

XCreds also has a PasswordOverwriteSilent preference key that silently resets the keychain if the IdP password changed since the last login.

Credits

  • XCreds by Twocanoes Software (Timothy Perfitt)
  • ClassLink integration by Brad White, Peninsula School District

About

XCreds modification for ClassLink OIDC tenant support at the macOS login window

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages