Okta supports native mobile SSO through a token-exchange flow: request the device_sso scope alongside Authorization Code with PKCE, store the returned device_secret securely on the device, and use token exchange to sign other vendor apps in without another interactive login. Getting this working means enabling Token Exchange on your authorization server, configuring the right scopes and grants, and handling the device_secret with the same care you'd give any long-lived credential.
TL;DR:
- Ensure your authorization server permits the device_sso, openid, and offline_access scopes, and allows the token exchange grant type before implementation.
- Store the device_secret securely in platform-specific storage, and revoke it on logout to prevent security breaches.
- Use the
/introspectendpoint to confirm the device_secret's validity before use, especially after periods of inactivity.- Test silent sign-in with prompt=none and verify revocation clears all app sessions to ensure proper token and device_secret handling.
- Build a clear sign-out process that revokes the device_secret across all participating apps to maintain security and session integrity.
Table of Contents
- Overview: how token-exchange native SSO works and why it's preferred
- Prerequisites and admin-side configuration in your Okta org
- Step-by-step implementation: requests, parameters and token-exchange sequences
- Platform specifics: secure storage patterns for iOS and Android
- Identity Engine SDK and custom UI considerations
- Security best practices and anti-patterns to avoid
- Troubleshooting and tests: what to check during development and QA
- Practitioner perspective: our practical tips for rollout and support
- What Okta's native SSO guide gets right, and where teams still trip up
- How we help: Discover, Design, Develop and Deploy your SSO rollout
- FAQ
- Sources
- Authoritative documentation and standards to consult
Overview: how token-exchange native SSO works and why it's preferred
When an app requests device_sso during the Authorization Code with PKCE flow, Okta's /token response includes a device_secret alongside the usual id_token, access_token and refresh_token. A second app on the same device can then present that device_secret as an actor token together with the first app's id_token as a subject token, and exchange both for its own fresh tokens, without the user seeing a login screen again.

This differs from older patterns built on shared web sessions or persistent cookies. A cookie-based session is hard to revoke cleanly across apps and ties SSO to a browser context that native apps have to work around. Token exchange gives you an explicit, revocable artefact and supports cross-device patterns that cookies never handled well. The approach follows the direction of the OIDC native SSO draft specification, and sits alongside RFC 8252, which sets out why native apps should authenticate through the system browser rather than an embedded one.
Prerequisites and admin-side configuration in your Okta org
Before writing any client code, your Okta org needs a few changes. Most of this happens on the custom authorization server and the app integration itself, and it's worth getting right the first time because a missing grant type is the most common cause of a failed token exchange later.
- Enable the
device_sso,openidandoffline_accessscopes on your custom authorization server. - Allow the Token Exchange grant type in the authorization server's access policy.
- Create native OIDC app integrations for each participating app, with correct redirect URIs and allowed grant types.
- Check whether you previously relied on the Okta Mobile companion app: it reached End of Life on 31 May 2026, so any SSO design built around it needs a migration path onto native SSO instead.
Treat this configuration as the foundation. Everything in the implementation steps that follow assumes the authorization server policy already permits token exchange.
Step-by-step implementation: requests, parameters and token-exchange sequences
The flow splits into two parts: the initial sign-in that mints the device_secret, and the subsequent exchanges that other apps use to get their own tokens.
- From the first app, build an Authorization Code with PKCE request that includes the scopes
device_sso openid offline_accessalongside whatever API scopes the app needs. - Exchange the returned authorization code at the
/tokenendpoint. The response containsid_token,access_token,refresh_tokenand, becausedevice_ssowas requested,device_secretin the additional parameters. - Store the
device_secretin platform-secure storage immediately; it assumes the lifetime and idle timeout of the refresh token it was minted alongside, according to Okta's native SSO guidance. - From a second app, call the
/tokenendpoint withgrant_type=urn:ietf:params:oauth:grant-type:token-exchange, settingactor_tokento the storeddevice_secretandsubject_tokento the first app'sid_token. - On success, the second app receives its own
id_token,access_tokenandrefresh_tokenwithout any interactive step. - When you need to confirm a
device_secretis still live, call/introspectand correlate the result against thesidclaim in the ID token to catch stale or revoked secrets during silent sign-in attempts.
Pro Tip: Log the token-exchange response status separately from the initial authorization flow; the two failure modes (bad PKCE verifier versus invalid actor token) look identical in a generic error toast but need different fixes.
Refresh tokens issued through this flow follow Okta's normal rotation rules, so plan for your refresh logic to run independently in each app rather than assuming one app's refresh keeps every app's session alive.
Platform specifics: secure storage patterns for iOS and Android
The device_secret is only as safe as the storage you put it in, and iOS and Android call for different patterns.
- On iOS, store the secret in the Keychain, and use keychain access groups when several apps from the same vendor team need to share it on one device.
- iCloud Keychain can sync the secret across a user's Apple devices, which is convenient but widens the blast radius if one device is compromised, so weigh that trade-off deliberately.
- On Android, use the Android Keystore system, typically through Jetpack Security's
EncryptedSharedPreferences, and review your backup configuration so the secret isn't swept into an unencrypted cloud backup. - Restrict access to the secret to apps signed with the same certificate or belonging to the same app group, so an unrelated app on the device can't request it.
Our guidance on protecting user data in mobile apps covers the broader storage and encryption choices that sit around this specific credential.
Identity Engine SDK and custom UI considerations
Okta's Identity Engine SDKs model sign-in as a state machine: each response from the service represents a step, such as a password challenge, an MFA factor or a remediation, and the SDK exposes that step so your app can render the right screen. This is a deliberate improvement on hard-coded login screens, because a policy change on the Okta side that adds a new authenticator doesn't require an app release to handle it.

For most teams, the default redirect model using the system browser is the right starting point: it's simpler to maintain and keeps you aligned with the security guidance in RFC 8252. A fully custom embedded UI built on the Identity Engine SDK gives you more control over branding and flow, but it means your app has to react correctly to every remediation Okta might return, including ones introduced after launch. Build your UI around the state machine's current step rather than assuming a fixed sequence of screens, and you avoid most of the maintenance burden that comes with custom authentication UIs.
Security best practices and anti-patterns to avoid
A handful of mistakes account for most of the native SSO security issues teams run into, and all of them are avoidable with a bit of discipline at design time.
- Never authenticate inside an embedded WebView; use the system browser or an official Okta SDK, as RFC 8252 recommends, to avoid exposing credentials to the host app.
- Revoke the
device_secreton logout rather than leaving it live, and keep its scope and lifetime as tight as the user experience allows. - Validate the
device_secretagainst/introspectbefore trusting it in a token exchange, particularly after any gap in app usage. - Treat decisions around iCloud Keychain sharing as an explicit risk acceptance, not a default.
Pro Tip: Build the revoke-on-logout call into your sign-out flow from day one; retrofitting it after other apps already depend on a shared secret is far harder.
Our piece on biometric authentication in mobile apps covers how to layer device biometrics on top of this flow without weakening it.
Troubleshooting and tests: what to check during development and QA
Before shipping, run through a short set of checks that catch most native SSO failures.
- Confirm the
/tokenresponse actually includesdevice_secretwhendevice_ssowas requested; its absence usually points to a missing scope or grant on the authorization server. - Test silent sign-in with
prompt=noneto confirm the second app gets tokens without a screen, then testprompt=loginto confirm forced re-authentication still works. - Revoke the
device_secretand verify every participating app signs the user out, not just the one that triggered the revocation. - Check server logs and
/introspectresults for policy misconfigurations, particularly mismatched redirect URIs or a disabled Token Exchange grant.
Practitioner perspective: our practical tips for rollout and support
We recommend piloting native SSO with a small, enterprise-leaning user group first, watching token-exchange success rates and sign-in latency before widening the rollout. Account recovery and MFA fallback deserve attention early: our guidance on mobile MFA and recovery flows is a useful companion once users start losing devices that hold a device_secret. Where the authentication surface spans several apps and teams, bringing in a specialist partner for the security review tends to save time later.
What Okta's native SSO guide gets right, and where teams still trip up
The token-exchange model is a genuine improvement over the cookie-sharing workarounds mobile teams built in the past, and the biggest thing it gets right is making revocation explicit: one call invalidates every app's session rather than relying on a shared cookie quietly expiring. Where we see teams go wrong isn't the Okta configuration itself, it's underestimating the storage and lifecycle work around the device_secret. Treating it as "just another token" rather than a long-lived credential is the most common source of later security review findings.
The conventional advice tends to stop at "enable the scope and call the endpoint", which undersells how much platform-specific storage and revocation logic has to sit around that call. If you're prioritising, get the secure storage and sign-out-everywhere behaviour right before you spend time on a bespoke sign-in UI. A plain redirect flow with solid storage and revocation will serve users better than a polished custom screen sitting on top of a device_secret nobody ever revokes. For readers who want the underlying protocol detail, this explainer on OpenID Connect is a useful companion to Okta's own docs.
— Paul
How we help: Discover, Design, Develop and Deploy your SSO rollout

Implementing native SSO well takes more than following the documentation: it takes a clear view of which apps need to share a session, how your storage and revocation flows hold up under real use, and what testing catches problems before release. Our Discover, Design, Develop and Deploy process is built around exactly that kind of scoping and build work, across the sectors we've delivered for. If you'd rather start small, a Mobile App Clinic gives you a short, focused session to scope the SSO effort and flag risks before a full build begins.
FAQ
Can Okta be used for SSO?
Yes, Okta supports single sign-on for web and native mobile apps, including a token-exchange based approach specifically designed for native apps on the same device, as described in Okta's developer documentation. It covers both browser-based SSO and the device-level native SSO flow covered in this guide.
How do I login to Okta Mobile?
Okta Mobile, the standalone companion app, reached End of Life on 31 May 2026 and is no longer available or supported. Organisations that relied on it for SSO should migrate to the native SSO token-exchange flow described in Okta's current developer guidance.
Is Okta the same as Google Authenticator?
No, they solve different problems: Okta is an identity provider that handles authentication and single sign-on across apps, while Google Authenticator is a one-time passcode generator used as one possible multi-factor authentication method. You can use an authenticator app like Google Authenticator as one factor within an Okta sign-in policy, but it isn't an alternative to Okta itself.
How to verify Okta on new phone without old phone?
This depends on which recovery and MFA fallback methods your organisation's Okta policy has enabled, such as backup codes, an admin-assisted reset or a secondary verification method. Our guidance on mobile MFA and recovery flows covers how to design these fallback paths so users aren't locked out when a device is lost.
Sources
- Configure SSO for Native apps | Okta Developer
- Overview of the mobile Identity Engine SDK | Okta Developer
- Native SSO: Desktop and Mobile Apps Single Sign-On | Okta Developer
- OAuth 2.0 for Native Apps (RFC 8252)
- Okta Mobile release notes
Authoritative documentation and standards to consult
- OAuth 2.0 for Native Apps (RFC 8252)
- Configure SSO for Native apps | Okta Developer
- Overview of the mobile Identity Engine SDK | Okta Developer
- Native SSO: Desktop and Mobile Apps Single Sign-On | Okta Developer
- Okta Mobile release notes
