OpenID Connect native SSO explained
Vendors with multiple native applications in their portfolio can offer users a smooth login experience while preserving the security properties of OpenID Connect and providing strong device session management.
1. Who is native SSO for?
If you are a vendor that offers a suite of mobile or desktop applications that require the user to be authenticated, this may be exactly what you have been looking for, so read on.
Single-app vendors are not concerned with this OpenID Connect extension for device-based single sign-on (SSO) as it relies on the sharing of an ID token and a device-bound secret between the applications participating in the SSO. This requires a level of trust between the apps that is only practical when they belong to the same vendor.
2. The benefits of native SSO
The leading benefit is the seamless login and logout experience for users, without weakening the security of users or the vendor’s applications.
Smooth SSO on the device
The user is asked to authenticate only once, into any one of the vendor’s apps enabled for SSO. At that instant the user may have installed only one of the vendor’s apps.
When the user opens another app of the vendor, which may be installed before or after the authentication, the user can be given the choice to automatically log into it. Additional interaction (beyond a simple confirmation) or the launching of the system browser (or another app) is not required. The app then obtains the necessary tokens for its operation, such as an access token, an ID token and a refresh token.
Single logout
With a single action, the user can log out of all the vendor’s apps participating in the device session. The user can initiate this logout:
- In any of the participating apps.
- In the IdP’s account management page, where the user can review and end active sessions and manage the authorisations granted to apps.
The logout automatically disables all refresh tokens issued to the vendor’s apps on the device.
Authentication step-up or additional consent
Privileged or sensitive operations can be made to trigger a step-up in the user authentication or request additional consent. The new authentication level (ACR) is automatically applied to the device session, which is shared by the participating apps.
Device session management
The Connect2id server represents the device session for the
user by a cryptographically secured secret token, the device_secret. The
session has a fixed lifetime and a maximum idle time, enabling the IdP to
expire it after a defined period or due to inactivity.
The following operations performed by any app in the vendor’s group count as device-session activity:
- Back-channel SSO requests
- Token refreshes
- Front-channel OpenID authentication request
When the device session expires, all refresh tokens issued to the apps are invalidated. To continue, the user must authenticate again.
Some of these behaviours are not part of the standard Native SSO specification, but represent useful Connect2id server extensions specific to its APIs.
Each app remains a distinct OAuth client
The native apps in the device session maintain a distinct identity in regard to
the IdP. Every app is issued with its own token(s), to the app’s client_id,
with scope and other properties that are independent from the tokens issued to
the other vendor apps. The app’s tokens can thus follow their own, separate
lifecycle and be managed independently.
3. Storage of the shared credentials
OpenID Connect Native SSO relies on two credentials – a device_secret and an
ID token bound to it. The vendor’s authorised apps must store them so the two
credentials are accessible only to them. Other apps or users on the device must
not be able to access these credentials. If they do, this may enable user
impersonation and unauthorised access to the vendor’s protected APIs.
The credential storage design must therefore:
- Restrict access to participating apps signed by the same vendor.
- Protect the credentials against extraction.
- Prevent their backup, synchronisation or transfer to another device.
The exact design is platform-specific. The following OS facilities can be used as part of it, but may require additional access controls:
| Operating system | Platform facilities |
|---|---|
| Android | Encrypted app-private storage with encryption keys protected by Android Keystore, exposed to participating apps through a component protected by a signature permission |
| iOS, macOS | Keychain services with a shared access group and device-only, non-synchronising storage |
| Windows | Device-local encryption using the Data Protection API, combined with an access-controlled mechanism for sharing the credentials between participating apps |
| Linux | GNOME Keyring or KWallet, combined with application-level encryption and access control |
4. Native compared to web SSO
Native and web SSO are conceptually similar. They establish a session after the user authentication, yet also differ significantly, in that the native variant requires a significant degree of trust between the apps.
| Characteristic | Native SSO | Web SSO |
|---|---|---|
| Session credential | device secret | browser cookie |
| Session credential storage | OS-specific API | browser cookie jar |
| Session credential storage managed by | the vendor’s apps | the browser |
| Application type | native | web, native |
| Scope | vendor’s apps | any app |
| Requires trust between the apps | yes | no |
5. The native SSO flow
A client app creates a device session
A device session is established when one of the vendor’s apps successfully
completes an authorisation code flow with the IdP that includes the openid
and device_sso values. These two values identify the request as being
conformant with the OpenID Connect native SSO 1.0
specification.
openid– This scope value requests an ID token for the user.device_sso– This scope value requests the creation of a device session.
Example OpenID authentication
request, note the
presence of the device_sso scope value:
https://c2id.com/login?
response_type=code
&scope=openid%20device_sso%20email%20profile
&client_id=app-1
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&code_challenge=K5mWL42Cly67d3EUJsIGeX_wtqDS2BsKFIFbVlR5Nfw
&code_challenge_method=S256
At the completion of the flow the client app must store the obtained ID token and device secret in a secure location accessible to the vendor’s apps only.
Example token response, the
device_secret is included for the native SSO:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token" : "aiK9aehiejohNahk8ia7luh.inohshoh6bahGeL5eife7",
"token_type" : "Bearer",
"expires_in" : 600,
"scope" : "openid email profile",
"refresh_token" : "eyJraWQiOki8jioWihahpquofiePhieg0a...",
"id_token" : "eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUl...",
"device_secret" : "WYqFXK7Q4HFnJv0hiT3Fgw.-oVkvSXgalUuMQDfEsh1lw"
}
The code flow is currently the only method specified in the native SSO extension for a client app to create a device session. Other suitable flows, which were designed for native apps, but do not involve the browser, are the OAuth 2.0 password grant and the recent OAuth 2.0 for first-party apps.
Back-end token requests utilising the device session
An app that retrieves an ID token and a device_secret from the credential
store shared by the vendor’s participating apps can make
a direct back-channel token request to the IdP.
As usual, the client app uses the scope parameter to indicate the requested
access. Including openid requests a new ID token for the signed in user. When
the scope parameter is omitted the convention stipulates that the scope
values registered in the client
metadata apply.
The token request follows a profile of the OAuth 2.0 token exchange
grant (RFC 8693) devised for
the purposes of native SSO. This enables the client app to present the
device_secret and the cryptographically bound ID token for the signed-in
user.
- The ID token must be passed in the
subject_tokenparameter and the parameter content indicated in thesubject_token_type. - The
device_secretmust be passed in theactor_tokenparameter and the parameter content indicated in theactor_token_type.
Example token request with
scope values openid, email and profile (note that the grant type is token
exchange):
POST /token HTTP/1.1
Host: c2id.com
Content-Type: application/x-www-form-urlencoded
client_id=app-2
&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&audience=https%3A%2F%2Fc2id.com
&subject_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUl...
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token
&actor_token=WYqFXK7Q4HFnJv0hiT3Fgw.-oVkvSXgalUuMQDfEsh1lw
&actor_token_type=urn%3Aopenid%3Aparams%3Atoken-type%3Adevice-secret
&scope=openid%20email%20profile
If the device session is still active the client app receives the requested token(s).
Example token response with an access, ID and refresh token:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token" : "eepeizaGhu8hhochu3Athe.e3cef9aiNgie9sIey2Kain",
"issued_token_type" : "urn:ietf:params:oauth:token-type:access_token",
"token_type" : "Bearer",
"expires_in" : 600,
"scope" : "openid email profile",
"refresh_token" : "eyJraWQiOki8jioWihahpquofiePhieg0a...",
"id_token" : "eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUl..."
}
This example showed how a client app was able to skip the user authentication by relying on device session.
When making a token request that relies on a device session client apps must be prepared to handle the following error conditions:
-
Closed or expired device session – The Connect2id server indicates this with the
interaction_requirederror code. If the device session is no longer active the client app must initiate a new front-channel OpenID authentication request that includes thedevice_ssoscope, in order to create a new device session. -
Step-up authentication or additional consent required – Also indicated by the
interaction_requirederror code. If the token request requires a higher ACR level than the current device session, or explicit user consent is required for a particular scope value, the client app must initiate a front-channel OpenID authentication request with the samescopevalues. -
Invalid request or another client error – Indicated by the error codes
invalid_request,invalid_grant,invalid_clientor another error for an incorrectly configured client or a protocol exception. The client code or its configuration for the IdP must be fixed.
6. Connect2id server support
Connect2id server introduced support for Native SSO in release 16.0.
Its features include:
-
Configurable device sessions Device sessions are managed in the same way as web sessions. The IdP can associate an ACR level with a session, set its maximum lifetime and idle timeout, and store additional data in it.
-
Single logout
Any participating client app can close the device session by submitting thedevice_secretto the token revocation endpoint. This logs the user out of all participating apps on the device. -
DPoP-bound device secrets
Connect2id server release 19.5 introduced an industry’s first implementation of DPoP binding for thedevice_secret, converting it from a bearer credential into a proof-of-possession credential. The participating clients share and collectively manage the corresponding DPoP private key. -
OAuth 2.0-only tokens requests The Connect2id server does not require an ID token to be issued in every response to a token request made with a
device_secret. A native app can therefore request OAuth 2.0 tokens without an ID token when it does not need an identity assertion.
7. Further reading
The OpenID Connect Native SSO for Mobile Apps 1.0 specification is published here. Draft 07 was approved as the Second Implementer’s Draft in October 2025. This status identifies the specification as stable for implementation, but it is not yet a Final Specification.
As of September 2026, the OpenID Connect working group has yet to decide whether
to finalise the current design or revise it further. One possible extension is
optional DPoP binding for the device_secret.