Skip to content
Connect2id

How to enable and manage native SSO

This guide explains how to configure the Connect2id server to enable single sign-on across groups native mobile or desktop apps using the OpenID Connect extension for native SSO. It also covers client registration, DPoP protection, shared logout and the management of native client group (NCG) sessions.

1. Configuration

  1. Enable native client group SSO in the Connect2id server.

    op.sso.nativeClientGroup.enable=true
    

    The server advertises this capability through the native_sso_supported parameter in its OpenID provider metadata.

  2. Choose suitable time settings for the native client group sessions, or keep the
    defaults.

    Example settings (all values are in minutes):

    # Limit the lifetime of sessions to 90 days
    op.sso.nativeClientGroup.sessionMaxLifetime=129600
    # Don't ask users to periodically re-authenticate 
    op.sso.nativeClientGroup.sessionAuthLifetime=0
    # End sessions after 10 days of inactivity (no token requests)
    op.sso.nativeClientGroup.sessionMaxIdleTime=14400
    
  3. Enable the default device SSO handler to authorise back-channel SSO requests.

    op.deviceSSOHandler.enable=true
    

    The default handler supports optional settings. For example, a setting for the scope values that require the user to re-authenticate or provide explicit consent at the authorisation endpoint.

    op.deviceSSOHandler.enable=true
    op.deviceSSOHandler.scopeRequiringInteraction=email profile
    

2. Native app registration

A mobile or desktop app is eligible to use native SSO when it is registered with a scope metadata parameter that includes both openid and device_sso.

Example registration request for a public native client:

POST /clients HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json

{
  "application_type"           : "native",
  "redirect_uris"              : [ "https://app.example.com/cb" ],
  "token_endpoint_auth_method" : "none",
  "code_challenge_method"      : "S256",
  "scope"                      : "openid device_sso email profile"
}

To require DPoP-bound tokens and device_secrets, set dpop_bound_access_tokens to true. The client must then include a DPoP proof header in every token request.

All apps that use the same DPoP-bound device_secret must use the same DPoP key. They must be able to generate proofs with its private key for the lifetime of the NCG session.

Example registration request with DPoP required:

POST /clients HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json

{
  "application_type"           : "native",
  "redirect_uris"              : [ "https://app.example.com/cb" ],
  "token_endpoint_auth_method" : "none",
  "code_challenge_method"      : "S256",
  "dpop_bound_access_tokens"   : true,
  "scope"                      : "openid device_sso email profile",
}

For additional guidance, see registering native apps as public OAuth 2.0 clients..

3. Refresh tokens

Refresh tokens issued with the device_sso scope are linked to the NCG session identified by the device_secret. This applies to refresh tokens issued:

  • At the end of an authorisation code flow with the openid device_sso scopes.
  • Through a successful native SSO token exchange using the ID token and device_secret.

Their validity depends on the NCG session, independently of the original web session. When a client uses one of these refresh tokens, the Connect2id server checks that the NCG session still exists and is valid. If the session has been ended or expired, the token request fails with an invalid_grant error.

4. DPoP-bound device secrets and tokens

DPoP binds access and refresh tokens to a public key. The Connect2id server extends this protection to the native SSO device_secret. Stolen credentials cannot be used without proofs signed with the corresponding private key. For access tokens, resource servers must validate these proofs and enforce the key binding.

The device_secret and the access and refresh tokens issued for the NCG session are bound to the same DPoP key. This requires coordination across the participating apps:

  • Key access and storage. Use a key specific to the app group on the device. Protect it with the operating system’s secure key storage, restrict signing access to the group’s apps and, where supported, keep it non-exportable.

  • Key lifecycle. Retain the key while the NCG session or any bound tokens are needed. Individual apps must not delete or replace it while others still depend on it, including during removal or reinstallation.

  • Key loss or rotation. A new key cannot be used with existing bound credentials. Establish a new NCG session and obtain new credentials bound to the replacement key.

  • Key compromise. Signing access through one app can expose the whole group if the attacker also obtains its credentials. End the affected NCG session and account for outstanding access tokens until they expire or their revocation is enforced.

To require DPoP, use the client registration setting above.

5. Device secret revocation for shared logout

Any client participating in an NCG session can end it by submitting its device_secret to the Connect2id server’s token revocation endpoint.

Revoking the device secret ends the shared native SSO session and invalidates all refresh tokens linked to it. The apps can no longer use that session to obtain new tokens through native SSO or refresh token requests. Apps must also clear any local login state as appropriate.

6. Native client group (NCG) sessions

An NCG session is a subject session created specifically for native SSO across a group of native clients. Its session identifier is issued to the clients as the device_secret.

NCG sessions have the following properties:

  • The Connect2id server creates a new NCG session whenever a native SSO flow results in the issuance of a new device_secret.

  • The subject (sub) and authentication details (auth_time, acr and amr) are copied from the web session in which the user authenticated.

  • The web session’s claims and data are also copied, starting with Connect2id server v20.0.

  • The creation_time records when the NCG session was created and is independent of the web session’s creation time.

  • The lifetimes (max_life, auth_life and max_idle) are taken from the native SSO configuration.

  • The rps array contains the client IDs of the apps that have joined the NCG session.

  • When a client completes an interactive authorisation code flow and presents the existing device_secret in the token request, the NCG session is updated with the web session’s current authentication details (auth_time, acr and amr), as well as its claims and data.

Example NCG session:

{
  "sub"           : "alice",
  "ctx"           : "NCG",
  "creation_time" : 1791821144,
  "auth_time"     : 1791820701,
  "max_life"      : 259200,
  "auth_life"     : 43200,
  "max_idle"      : 14400,
  "acr"           : "http://loa.c2id.com/high",
  "amr"           : [ "mfa", "pwd", "otp" ],
  "rps"           : [ "eedi8jah", "ahp9xei5", "ioj6agah" ]
}

6.1 NCG session management

Use the Connect2id server’s session store API to list a user’s active sessions. NCG sessions have a ctx value of NCG.

Example request to list the NCG sessions for user alice:

GET /session-store/rest/v2/sessions?subject=alice&ctx=NCG HTTP/1.1
Host: c2id.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

To end an NCG session via the API, use the DELETE method. This will also invalidate all refresh tokens linked to the session.

Example request to end a session:

DELETE /session-store/rest/v2/sessions HTTP/1.1
Host: c2id.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
SID: WYqFXK7Q4HFnJv0hiT3Fgw.-oVkvSXgalUuMQDfEsh1lw

6.2 Relationship to web sessions

An NCG session is created from the web session in which the user authenticated. After creation, the two sessions have independent lifecycles. Ending the web session, or allowing it to expire, does not end the NCG session.

The authentication details, claims and data copied at creation are a snapshot of the web session. They are updated when a client successfully completes another authorisation code flow and presents the NCG session’s device_secret in the token request. The web session used for that flow may differ from the one that originally created the NCG session.

7. Usage guidance

7.1 Scopes and claims requiring user interaction

The default device SSO handler limits the scopes it authorises in back-channel requests to those
registered for the client. Authorising a scope such as email or profile also authorises its associated OpenID Connect claims. The same applies to custom scopes that request OpenID Connect claims.

By default, no scopes require user interaction. To require re-authentication or explicit consent for particular scopes, list them in the following setting, separated by spaces:

op.deviceSSOHandler.scopeRequiringInteraction=email profile

A back-channel device SSO request that includes any of these scopes fails with an interaction_required error at the token endpoint. The client must then use the authorisation code flow to obtain authorisation.

7.2 OAuth 2.0-only token requests

The Connect2id server does not require an ID token to be issued in every response to a token exchange request made with a device_secret. A native app that does not need an identity assertion can omit the openid scope and request only OAuth 2.0 tokens.

7.3 ID tokens and user authentication

A client participating in an NCG session can request a new ID token through a back-channel token exchange with the openid device_sso scopes. The ID token reflects the identity and authentication details recorded in the NCG session. Its issuance does not mean that the user has authenticated again or is currently present.

To authenticate the user through the front channel, the client must use the authorisation code flow with the openid device_sso scopes. If fresh authentication is required, the request must also require re-authentication, for example with prompt=login or max_age=0.

The default device SSO handler does not issue new ID tokens in response to refresh token requests.