Skip to content
Connect2id

OpenID Connect native SSO explained

Vendors with multiple native applications in their portfolio can now offer a smooth login experience to their users, keeping the good security properties of OpenID Connect intact while benefiting from a strong, device-based 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 compromises that can adversely compromise the security of the user or the vendor’s products.

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 logged 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 access, ID and refresh token.

Single logout

With a single command the user is able to logout from all apps of the vendor present on the device. The logout command can be triggered in two ways:

  • From any one of the vendor’s apps.
  • From the user’s control panel for logins and granted authorisations at the IdP.

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 device session for the user is represented by a secret token, called device secret, that is cryptographically secured. The session has a set lifetime and a maximum idle time. This enables the IdP to expire the session after a certain time or duration of inactivity.

The following operations, by any of the vendor’s apps, count as device session activity:

  • A back-channel SSO request.
  • A token refresh.
  • A front-channel OpenID authentication request.

Expiration of the device session disables all refresh tokens issued to the apps. To continue, the user must log in again.

Some of the above features are not part of the native SSO specification, but additions invented for the Connect2id server and particular to its APIs.

Distinct app authorisations

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. Prerequisites

OpenID Connect Native SSO relies on two credentials – a device session secret and an ID token, that the vendor’s apps must store in a location accessible only to them. Other apps or users on the device must not have the means to access these credentials. If they do, there is risk of impersonation and illegitimate access to protected APIs of the app vendor.

What OS facilities are available to store the native SSO credentials?

Operating system Recommended native SSO credential storage
Android EncryptedSharedPreferences
iOS, macOS Keychain services API
Windows Credentials Management API
Linux GNOME Keyring, KWallet

4. Native compared to web SSO

Native and web SSO are conceptually similar, by establishing 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=123
 &state=af0ifjsldkj
 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

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. The OAuth 2.0 password grant and the recent OAuth 2.0 first-party app flow effort that seeks to replace it are two other suitable methods.

Back-end token requests utilising the device session

An app that finds an ID token and a device_secret available in its credential store shared with the vendor’s other apps, can assume the user is already signed in and thus proceed with a direct back-channel token request to the IdP.

As usual, the client app uses the scope parameter to indicate the requested access. The openid scope value can be included to request 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 prove that it has a device_secret and a cryptographically bound ID token for the signed-in user.

  • The ID token must be passed in the subject_token parameter and the parameter content indicated in the subject_token_type.
  • The device_secret must be passed in the actor_token parameter and the parameter content indicated in the actor_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

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&subject_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUl...
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid-token
&actor_token=WYqFXK7Q4HFnJv0hiT3Fgw.-oVkvSXgalUuMQDfEsh1lw
&actor_token_type=urn%3Ax-oath%3Aparams%3Aoauth%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_required error code. If the device session is no longer active the client app must initiate a new front-channel OpenID authentication request that includes the device_sso scope, in order to create a new device session.

  • Step-up authentication or additional consent required – Also indicated by the interaction_required error 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 same scope values.

  • Invalid request or another client error – Indicated by the error codes invalid_request, invalid_grant, invalid_client or another error for an incorrectly configured client or a protocol exception. The client code or its configuration for the IdP must be fixed.

6. Further reading

The OpenID Connect Native SSO for Mobile Apps 1.0 specification is published here. It can be considered stable for implementation and we expect it to be declared final in 2025 or 2026.

The Connect2id server introduced support for device sessions in release 16.0. These can be managed just like web sessions, giving an IdP the ability to associate an ACR level with them, set an expiration time, and include special data. Client apps can close a device session by passing the device_secret to the token revocation endpoint.