Clever Single Sign-On - Best Practices & Edge Cases
Review Clever Single Sign-On best practices and edge cases, including shared devices and kiosk or lockdown-browser deployments.
Clever Complete Agreement RequiredThis feature is included with a Clever Complete subscription. Sign up here or email your Application Success Manager to learn more.
SSO-only integrations are no longer supportedClever no longer supports new standalone SSO-only integrations. To implement district-managed Clever SSO, your application needs a Clever Complete agreement and should use SSO as part of an SSO + Rostering integration.
If you need access, contact your Application Success Manager or [email protected].
Use this page to review implementation best practices for Clever Single Sign-On and handle common edge cases before certification.
Best practices
Use these practices to avoid common SSO implementation problems:
- Do not exchange the same authorization code more than once. Clever returns an error if you do.
- Support login requests that start from the Clever Portal or an Instant Login link. Do not redirect those users back to your own login page.
- Make sure your first configured redirect URI can handle logins for all districts without requiring extra parameters or district-specific subdomains.
- A common pattern is to use one centralized redirect URI, then route users to the correct domain or path after login.
- Use HTTPS on your production redirect URI. The rest of your application should also use HTTPS.
- Include a Log in with Clever button on your site.
- Override any existing session when a new Clever authentication request arrives. This is important on shared devices.
- Do not rely on district context being stored in the user’s browser. Kiosk and lockdown-browser sessions that start with a reset browser profile have no stored state, so Clever falls back to the school picker on every launch. If you know the district, include
district_idin the authorization request and test the resulting flow in the district’s kiosk or lockdown environment. - If your app runs in a kiosk or lockdown browser, complete Clever Single Sign-On before the locked session starts. See Kiosk mode and lockdown browsers.
- Show clear account indicators in your UI, such as the user’s name or username, so users can confirm they are signed in to the correct account.
- Include a logout button.
- If your app requires fields that Clever Single Sign-On does not provide, such as school information, collect them during first login.
Use the Clever User ID as your primary identifierClever does not verify user email addresses, and some users may not have an email on record. District-managed identifiers like SIS IDs are unique only within a district. To reliably identify users across Clever, always key off the Clever User ID.
Edge cases
Multi-role users
With v3.0 of the API, Clever introduced multi-role users. This supports users who have multiple roles in a district, such as someone who is both a teacher and an administrator.
In API responses from /v3.0/users, the roles object contains each role that is shared with your application. Each role includes role-specific fields such as legacy_id. This value is different from the user’s top-level id.
Example:
{
"data": {
"created": "2022-05-15T22:20:03.535Z",
"district": "62817af12d430f5d54001f99",
"email": "[email protected]",
"last_modified": "2024-07-10T16:22:11.422Z",
"name": {
"first": "PE",
"last": "Bot"
},
"roles": {
"teacher": {
"schools": [],
"legacy_id": "6298ef2e9e30ed3d9066e118"
},
"district_admin": {
"legacy_id": "62817af1d65e86e415b6f68d"
}
},
"id": "62817c88dc4dc002ea40b594"
},
"links": [
{
"rel": "self",
"uri": "/v3.0/users/62817c88dc4dc002ea40b594"
}
]
}When a multi-role user starts SSO from Clever, your application does not receive context about which role they intended to use. Plan a default behavior for that case.
For example, if a user is both a teacher and an admin, your application might send them to the admin experience by default.
State parameters
If you use an identity management system such as Okta or Auth0, your implementation may require a state parameter.
The state parameter helps prevent CSRF attacks and preserve application state between the authorization request and callback.
Clever-initiated logins do not include a state parameter by default, which can create problems for those implementations.
To handle this:
- Detect Clever-initiated logins that arrive without
state. - Do not complete authentication from that request.
- Treat that request as a trigger to restart authentication from your own site.
- Include your own
stateparameter in the new request. - Clever will pass that
statevalue through after authentication.
If you need help planning this flow, contact Clever Support through the Help Center chat. Your application is still responsible for implementing the logic.
Native iOS apps and duplicate callback handling
If your iOS app uses Universal Links, Safari may continue loading the callback URL before the OS finishes opening your native app. In some implementations, both Safari and the native app then send the same authorization code to your backend.
Because authorization codes are single-use, the first exchange succeeds and the second can fail with invalid_grant. Make your callback handler duplicate-safe: detect when a code was already processed, avoid a second token exchange, and log repeated callback requests for troubleshooting.
Supporting multiple applications with one Log in with Clever button
Some products support multiple environments or multiple Clever integration accounts, but still want to use a single login page with one Log in with Clever button.
For this use case, add the return_unshared=true parameter to the authorization URL:
https://clever.com/oauth/authorize?response_type=code&redirect_uri=&client_id=&return_unshared=true
If a user does not have access to that specific app, Clever sends an unauthorized-user error to the redirect_uri instead of showing a user-facing error.
Your application can then start a new login attempt with a different client ID and, if needed, a different redirect URI.
return_unshared=true is also useful outside multi-application routing. Without it, a user whose district has not connected your app sees a Clever-hosted error page. In a locked assessment session, that page can prevent your app from controlling the next step. With return_unshared=true, Clever redirects to your redirect_uri with error=unauthorized-user instead.
Make sure your callback handles an error-only request with no authorization code and routes the user to a page you control.
Avoid infinite loopsDo not include
return_unsharedon the final app you try. If every attempt includesreturn_unshared=trueand the user has access to none of the apps, your flow can loop forever.
Shared devices for students
If your app has strict security requirements and needs to reduce the chance of a student accessing the wrong account on a shared device, add confirmed=false to the authorization URL.
This prompts Clever to confirm the identity of the student.
Example:
https://clever.com/oauth/authorize?response_type=code&redirect_uri=&client_id=&confirmed=false
This behavior only applies to student users.
Kiosk and lockdown-browser deployments are a special case of shared devices. See Kiosk mode and lockdown browsers.
Implicit grants
Clever uses the authorization code grant flow by default.
In some cases, the implicit grant flow documented here may also be allowed.
Single logout
Clever does not support SLOUse safe session-management practices in your own application, especially for shared devices.
Single Logout (SLO) means logging a user out of multiple applications or services with a single action through a centralized authentication service.
Clever sessions can last up to 24 hours depending on the device. Clever does not recommend logging users out of their Clever session when they log out of your app, because that would interrupt the expected SSO experience across the rest of their learning tools.
If you believe you have a strong use case for logging users out of Clever, contact Clever Support through the Help Center chat.
Identifying impersonations
District admins can sometimes impersonate users and then use SSO into your application on that user’s behalf. This can affect login analytics or inflate certain login metrics.
Clever can expose a flag that indicates whether an SSO request came from impersonation.
If you want this feature, contact support at https://support.clever.com.
Once enabled, impersonated login attempts include loginas_by_admin=true in the redirect URL.
Kiosk mode and lockdown browsers
Some applications, especially assessment and testing products, run inside a kiosk app or lockdown browser. These environments can restrict navigation, block new tabs, disable copy and paste or typed URLs, and close other applications when the locked session begins.
Clever cannot detect kiosk or lockdown modeClever does not receive a signal that a login is happening inside a locked session, and the SSO flow does not adapt automatically. Your application is responsible for sequencing and containing the login flow.
Complete SSO before the session locks
Authenticate first, then start the locked session:
- Start Clever Single Sign-On in a normal browser session.
- Exchange the authorization code on your server.
- Call
/meand use the Clever user ID to identify the user. - Establish your own application session.
- Launch the kiosk or lockdown browser.
Authenticating inside the locked session causes most kiosk-related login problems. Lockdown environments can block navigation required by the authorization flow or redirects to a district identity provider such as Google or Microsoft.
Verify whether the locked browser inherits the existing browser sessionTest this before implementing the flow. If the lockdown browser starts with a clean browser profile, authentication completed beforehand does not carry into the locked session.
If the locked session does not inherit the Clever session, treat the Clever login and locked session as separate sessions. Identify the student with Clever in the unlocked browser, then give the locked session an application-controlled credential, such as a test code or session code, that your app creates after calling /me.
Do not put a Clever authorization code or access token in the kiosk launch URL. Authorization codes are short-lived and single-use.
Pass district_id explicitly
district_id explicitlyA general Log in with Clever link does not require district_id. Clever uses district context stored in the browser when it is available and otherwise shows the school picker.
In a kiosk or ephemeral browser session, district context may be removed on every launch. If your deployment already knows the district, include district_id in the authorization URL and test the resulting flow in the district’s kiosk or lockdown environment.
The school picker can move the user outside the authorization flow your application initiated. If a student abandons the picker, recovery can continue through a Clever login without the original redirect_uri. After a successful login, the user can land in the Clever Portal instead of returning to your application.
Common sources for a district ID include:
- managed kiosk configuration, such as Chrome kiosk settings deployed through Google Admin
- a district-specific start URL, such as
https://yourapp.example.com/kiosk?district=<clever_district_id> - an application-controlled session or test code that already resolves to a district
- your rostering data, if your app syncs with Clever
Use app-initiated login
Start Clever SSO from your application with Log in with Clever instead of expecting students to select your tile in the Clever Portal. Portal launches can open a new tab, which many kiosk and lockdown browsers block. App-initiated login also lets your app control the authorization parameters and destination after authentication.
Handle districts that have not shared your app
If a district has not connected and shared your app, Clever normally shows a hosted error page. In a locked assessment session, that can be a dead end or allow navigation outside the assessment flow.
Add return_unshared=true to the authorization URL:
https://clever.com/oauth/authorize?response_type=code&redirect_uri=<uri>&client_id=<id>&return_unshared=trueClever redirects to your registered redirect_uri with error=unauthorized-user and no authorization code. Your callback must detect this error-only response and route the user to an application page you control.
If you use an SSO broker or middlewareThe registered
redirect_urimay belong to the broker instead of your application. Confirm that the broker handles error-only callbacks and returns the user to your app.
Also see the infinite-loop warning in Supporting multiple applications with one Log in with Clever button. Do not set return_unshared=true on the final application you try.
Plan for session length, resume, and exit
- Session length: Make your application session last for the full assessment window. Do not require a student to reauthenticate in the middle of a locked session.
- Resume after a crash: Have students re-enter an application-controlled credential rather than starting a new Clever login.
- Exit: Define where users go when they exit the locked session. Many kiosk tools return users to your login screen rather than to Clever.
Allowlist required domains
If the district filters network access on testing devices, allow access to clever.com, your application, and the district’s identity provider domains. For example, a login that resolves through Google or Microsoft fails if only clever.com is allowed.
Use district-side containment controls
Clever’s SSO flow can include paths such as the school picker, hosted error pages, and footer links that lead a signed-in user back to the Clever Portal. The recommendations on this page help you control the parts of the flow owned by your application, but they do not replace the district’s device or network restrictions for high-stakes assessments.
Updated 4 days ago

