Skip to main content

Session management

How to handle user sessions when integrating with CIS2 Authentication, including re-authentication and logout.

Overview

When a user signs in with CIS2 Authentication to access your application, you’ll need to create a ‘session’ that allows them to continue using the application without having to re-authenticate every time they move to a new web page.

You’ll also need to consider things like:

  • If the user is already authenticated with CIS2 Authentication, do you need them to re-authenticate to use your application?
  • If the user has been inactive for a while, do you need to sign them out?
  • If the user has authenticated with a smartcard, and they remove it, do you need to sign them out?

Session management basics

When a user signs in to a web application, the application needs some way of remembering that the user is signed in and also remembering other things about the user’s state.

It also needs to cater for signing the user out, either upon explicit request, or because the user has been inactive for a while.

We call this 'session management'.

Session cookies

A common method for managing a user's session is to create a 'session cookie'. This is a packet of information that is created by the web application and passed back to the user’s browser when the user signs in. The browser then passes the cookie to the application with every HTTP request. Usually, the application also holds session information on the server, which it can obtain by matching it to a unique ID in the cookie.

The cookie is shared across all tabs and windows within a single browser (for example Google Chrome) but is not shared across different browsers (for example Google Chrome and Microsoft Edge).

The cookie remains available until all browser tabs and windows are closed.

For security reasons, cookies used for managing sessions typically have the Secure and HttpOnly tags set.

Federated session management

When an application uses a federated identity provider (IdP) to sign the user in, such as CIS2 Authentication, the IdP creates its own session with the user's browser. So the user’s browser will have two session cookies:

  • One for the application
  • One for CIS2 Authentication

It's possible for the user to have been signed out of their application (for example due to an idle timeout) but still be signed in to CIS2 Authentication.

Likewise, it's possible for the user to have been signed out of CIS2 Authentication (for example due to a smartcard having been removed) but still be signed in to their application.

If the user is using two or more applications within the same browser that use CIS2 Authentication, it's possible for them to sign in once to access all applications. This is known as Single Sign-On (SSO). In this case, the user’s browser will have multiple session cookies:

  • One for CIS2 Authentication
  • A separate one for each application they are using

Each application is responsible for managing the user's session with that application.

CIS2 Authentication is responsible for handling the user's session with itself as an identity provider.


CIS2 Authentication session management

CIS2 Authentication establishes a session when the user first signs in. It uses a Secure HttpOnly session cookie for this.

CIS2 Authentication allows up to 10 concurrent sessions per user. This allows users to be signed in to multiple applications across multiple devices and browsers at the same time. If the user re-authenticates within the same browser, the existing session is reused and does not add to the session quota.

CIS2 Authentication will terminate a session on the server side if:

  1. The session expires. This happens 12 hours after authentication or the most recent re-authentication.
  2. The session was established using a smartcard and the 'smartcard session' is terminated (see below).
  3. The user creates more than 10 sessions across different devices or browsers and this is the oldest session.

The session will also effectively end if all instances of the browser are closed, because the session cookie will be lost.

CIS2 Authentication's session management capabilities might change over time. You are advised to frequently check this section for updates on how and when a session is terminated.

Smartcard session management

When a user authenticates using a smartcard, a component on their client device manages the smartcard session for them, separately from the CIS2 Authentication session. We have two different components for this:

  • Smartcard Connect (newer)
  • Identity Agent (older)

The session management rules are different for each one.

Smartcard Connect

With Smartcard Connect, there is no smartcard session. It does not keep track of the smartcard session duration and does not monitor smartcard removals.

Identity Agent

With Identity Agent, the smartcard session terminates if:

  1. The session expires. This happens after 12 hours.
  2. The smartcard is removed from the reader.

Identity Agent can be configured to manage its own session, the client device session and browser sessions in a number of different ways, including:

  1. Closing all browser windows when the smartcard is removed.
  2. Offering the user the option to end the Identity Agent session or lock the client device when the smartcard is removed.
  3. Offering the user the option to remove the smartcard but to continue the Identity Agent session by periodically re-entering the smartcard pin.

For more details, see NHS Identity Agent.


Your application's session management

You must implement session management for your own application.

You'll need to:

  1. Decide whether to force the user to re-authenticate with CIS2 Authentication when authenticating for your application. See Prompt parameter below.
  2. Create a session for the user. This must be a secure session binding such as a Secure HttpOnly cookie.
  3. Provide a way for users to explicitly sign out. See Explicit sign-out below.
  4. Terminate the user’s session at least every 12 hours.
  5. Terminate the user’s session following a period of inactivity. See Idle timeout below.
  6. Decide whether to react to termination of the CIS2 Authentication session. See Back-channel logout below.

Prompt parameter

When you make an authentication request to CIS2 Authentication, you can specify how to handle re-authentication.

There are three options:

not present

If you omit the prompt parameter, we'll only ask the user to sign in if they don't already have an existing session.

The ID token you receive from your subsequent token request will contain an auth_time claim containing the time that the user was last actively authenticated, whether it be just now or at some time in the past.

If you use this option, you must modify this behaviour using the max_age parameter as described below.

login

If you specify prompt=login then we'll always authenticate the user, regardless of whether they have an existing session. This is equivalent to setting max_age=0 (see below).

However, if the user is authenticating with a smartcard, and is using our older Identity Agent component (as opposed to our newer Smartcard Connect component), the behaviour depends on the Identity Agent's smartcard session state:

  • if a session still exists in the IA then no user action is required
  • if a session doesn't exist, the user is prompted to insert their smartcard and enter their pin

When using prompt=login, you should check the auth_time returned in the ID token as described below.

none

If you specify prompt=none, we don't actively authenticate the user, regardless of whether they have an existing session. If they have an existing session, authentication is successful automatically. If they don't have an existing session, we return an error response to your redirection URI. The error response will have an error value of interaction_required as in the example below:

HTTP/1.1 302 Found
  Location: https://www.nationalsupplier.nhs.net/callback?
    error=interaction_required
 
&error_description=The%20request%20requires%20some%20interaction%20that%20is%20not%20allowed.
    &state=af0ifjsldkj

Maximum age parameter

Use the max_age parameter to modify the behaviour of an authentication request when no prompt parameter is provided. It specifies the maximum allowed time in seconds since the last time the user was actively authenticated. If the elapsed time is greater than this value, we will attempt to actively re-authenticate the user. If the authentication is successful then the resulting ID token will contain an auth_time claim containing the new authentication time.

When using a max_age parameter, you should check the auth_time returned in the ID token as described below.

You may typically choose to allow a limited max_age of up to 5 minutes to reduce the authentication burden on users. For values greater than this, the confidence that the authenticating user is present decreases and should only be used in carefully considered situations. It should be avoided in scenarios where the OS session is shared between users.

Authentication time claim

We always return an auth_time claim in the ID token. This claim gives the time at which the user was last authenticated. Its value is a JSON number representing the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the date/time.

You can use this claim to make decisions about the freshness of the current CIS2 Authentication session.

When you make an authentication request with prompt=login or with a max_age parameter, you must check the auth_time claim to confirm that that the request has been honoured and has not been subject to manipulation by an attacker. Do this by checking auth_time against the current time. Allowance should be made for the time taken between receiving the auth code and obtaining the ID token and for potential clock skew. For example, within 15 seconds of the current time.

Inferring the presence of the user

A successful authentication doesn't always mean that the user is present. It depends on the value of the prompt parameter and on the authentication method.

For all authentication methods, including a smartcard using Smartcard Connect, but not a smartcard using the Identity Agent:

Prompt value Impact
Not present The user was present at the time given in the auth_time claim. It can only be inferred that the user is currently present by comparison of the auth_time with the present time and the iat time.
login The presence of the user is guaranteed.
none The user was present at the time given in the auth_time claim but it can not be guaranteed that the user is still present.

For smartcards using the Identity Agent:

Prompt value Impact
Not present The presence of the smartcard is guaranteed and the presence of the user can be inferred.
login

The presence of the smartcard is guaranteed and the presence of the user can (almost) be inferred.

That said, this does not actually guarantee the presence of the user because if a session has already been established in the Identity Agent the user is not prompted to re-enter their pin. This behaviour is a result of a design decision to maintain the existing Identity Agent behaviour.

none The presence of the smartcard is guaranteed and the presence of the user can be inferred.

The mechanism used to authenticate a user is given by the value of the amr claim in the ID token as described in Authenticator guidance for developers.


Explicit sign-out

You should provide a way for users to explicitly sign out of your application.

When they do this you should terminate their session with your application.

We do not currently provide a 'single logout' (SLO) mechanism – there's no way to terminate the user's session with CIS2 Authentication.

Therefore, if the user requests to sign back in to your application, either explicitly or implicitly by browsing to a page that requires them to sign in, and if you are allowing the user to skip re-authentication using the prompt parameter setting of 'not present', and if their CIS2 Authentication session is still active, then they will be signed in to your application without needing to re-authenticate.


Idle timeout

If the user has been inactive for a period of time, you must terminate their session. The 'idle timeout' depends on the authenticator assurance level you require for your application:

Authentication assurance level Idle timeout
AAL2 30 minutes
AAL3 15 minutes

Back-channel logout

As explained above, users have a separate session with CIS2 Authentication from their session with your application.

The user's CIS2 Authentication session can be terminated for a number of reasons, for example, the user has removed their smartcard (and is using the Identity Agent).

You can use back-channel logout to be notified when this happens. To do this you'll need to provide a 'logout' endpoint we can call when a user's CIS2 Authentication session is terminated.

Registration

To register for back-channel logout notifications, when you register to access an environment you'll need to provide us with the URI of a public internet-facing back-channel logout endpoint.

Notification

Your endpoint must be secured with HTTPS (using port 443), accessible by a public DNS domain and present a server certificate matching its FQDN. The certificate presented must include a full certificate chain to a trusted public Root CA, for example DigiCert.

There is no need to restrict access to your endpoint, but if you do, you should configure your firewall to allow requests to the endpoint from these IP addresses:

Environment IP address range(s)
Production

52.142.148.70/31
51.143.231.182/31

INT 51.104.255.212/31
DEP 51.132.152.140/31

When a user's session CIS2 Authentication is terminated for any reason, we'll send a logout token to your endpoint by HTTP POST.

The logout token is similar to an ID token in that it contains the user's subject identifier and is a JWT signed with our private key. On receipt of the logout token, you should terminate the user's session with your application.

Logout token

The logout token is a JWT (see JSON Web Token Specification) very similar to the ID token. It is signed by the same keypair and is therefore subject to the same key rotation requirements.

The logout token is sent in a logout_token parameter included in a POST body using the application/x-www-form-urlencoded encoding.

The POST body may contain other values in addition to logout_token. You must ignore any parameters you do not understand.

An example POST request and decoded payload are given below - most of the logout_token contents are omitted for brevity.

Example logout token

POST /backchannel_logout HTTP/1.1
Host: rp.example.org
Content-Type: application/x-www-form-urlencoded

logout_token=eyJhbGci ... .eyJpc3Mi ... .T3BlbklE ...

Example decoded payload

{
    "iss": "https://am.nhsint.auth-ptl.cis2.spineservices.nhs.uk:443/openam/oauth2/realms/root/realms/NHSIdentity/realms/Healthcare",

    "sub": "999999999999",
    "aud": "999999999999.apps.national",
    "iat": 1589817244, 
    "jti": "bWJq",
    "sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
    "events": {
        "http://schemas.openid.net/event/backchannel-logout": {}
    },
    "exp": 1589817544
}
Claim Description
iss The CIS2 Authentication issuer identifier as specified in the relevant configuration document.
sub A unique identifier for the user. See Scopes and claims for more details.
aud Your client identifier.
iat The time at which the JWT was issued. This is a JSON number representing the number of seconds from 1970-01-01T0:0:0Z as measured in UTC.
jti Unique identifier for the token.
sid The CIS2 Authentication session ID (this will match the sid given in the ID token as described above)
events JSON object containing the member name http://schemas.openid.net/event/backchannel-logout. This declares that the JWT is a logout token
exp The expiry time of the token in seconds since 1970-01-01T00:00:00Z as measured in UTC.

You must validate the logout token as per section 2.6 of the OIDC Back-Channel Logout Specification. Note that:

  1. The value of the iss claim must exactly match the Issuer Identifier for CIS2 Authentication as specified in the relevant configuration document.
  2. The aud Claim must contain your Client identifier.
  3. You must validate the signature of the logout token according to the JSON Web Signature Specification using the algorithm specified in the JWT alg header parameter. You must use the keys provided by the CIS2 Authentication as described in Key management.
  4. The logout token must contain an events claim whose value is JSON object containing the member name http://schemas.openid.net/event/backchannel-logout.
  5. The logout token must not contain a nonce claim.
  6. You must validate the iat and exp claims in the same way they are validated in ID tokens.

Actions

You should store the sub and sid claims from the ID token (see Sign in journey) in your own session upon successful sign in. Upon receipt of a logout token, you must check the veracity of the token as described above.

If the logout token contains both a sub and sid claim, you should find any application sessions where both the captured sub and sid values match those in the logout token and invalidate these sessions. 

If there is no sid claim present in the logout token, you should invalidate all sessions for the user identified by the sub claim.

You may choose to implement a client side polling mechanism such that when a session is invalidated on the server the user is also signed out client side. This may give a better user experience than allowing the user to attempt further actions only to be denied as the result of a server side session check.

Response

Your endpoint should respond as follows: 

  • If the logout succeeded, respond with HTTP 200 OK.
  • If the logout request was invalid or the logout failed, respond with HTTP 400 Bad Request.
  • The response may include an HTTP body consisting of a JSON object with error and error_description parameters conveying the nature of the error that occurred.

For the avoidance of confusion, "HTTP 400 Bad Request" should only be sent if the token was invalid or the logout actually failed. If the specified session does not exist, or the user has no sessions (for those logout tokens without a sid) then the logout request can be considered to be "HTTP 200 OK" as the result is that the session(s) no longer exists.

Note that earlier drafts of the back-channel logout specification mandated the use of different response codes, for example an HTTP 501 response to indicate the logout failed. For existing implementations, CIS2 Authentication will continue to accept responses based on these drafts.


Example use cases

This section given some examples on how the features described above could be used. These examples are provided for illustration only - you should take into account your own security and usability needs.

AAL3 use case

To fully comply with letter of the NIST requirements for AAL3 session management, you should implement the following.

  1. When you detect a new user accessing your web application, make an authentication request with a prompt=login parameter. On successful authentication, retrieve the ID token to identify the user, create an application session and create an activity timer for the session. 
  2. If the user has been inactive for 15 minutes or more between visits to the web application, make an authentication request with a prompt=login parameter. On successful authentication, retrieve the ID token and validate that the identity is the same as that used to create the application session. 
  3. If the user has been active for 12 hours without re-authenticating as a result of step 2, make an authentication request with a prompt=login parameter. On successful authentication, retrieve the ID token and validate that the identity is the same as that used to create the application session. 
  4. Provide an option for the user to sign out of the application, at which point the application session should be terminated.

Note that for most authenticators, including smartcards using Smartcard Connect, use of the prompt=login parameter will result in the user being prompted to provide credentials definitively proving their presence. Whereas for smartcard authentications using the Identity Agent, a user interaction will only occur if the Identity Agent no longer holds an active session, thus user presence is only guaranteed in so much as their smartcard has not been removed from the smartcard reader.

You may also have a requirement to only allow a single user session at a time. We recommend you implement this requirement in your own business logic.

AAL3 use case with sensitive operations

For particularly sensitive operations within your application, you may wish to add an additional confirmatory step before performing such operations.

Two options are possible, as follows.

Option 1 - prompt=none

Before performing the sensitive action, make an authentication request with a prompt=none parameter. If an active CIS2 Authentication session exists in the user's browser then an authorisation code will be returned as normal and you should retrieve the ID token and validate that the identity is the same as that used to create the application session.

Note that for smartcard authentications using the Identity Agent this will prove that the user has not removed their smartcard from the smartcard reader and it can be inferred that the user is present. Whereas for other authenticators, including smartcards using Smartcard Connect, this only gives assurance that the user has previously been authenticated (at the time given by the auth_time claim in the ID token) and the session has not expired - presence of the user cannot be inferred.

Note that the mechanism by which the user was authenticated can be determined from the amr claim in the ID token as described in Authenticator guidance for developers.

Option 2 - prompt=login

Before performing the sensitive action, make an authentication request with a prompt=login parameter. On successful authentication, retrieve the ID token and validate that the identity is the same as that used to create the application session.

Note that for most authenticators, including smartcards using Smartcard Connect, this will result in the user being prompted to provide credentials and thus presence of the user is guaranteed. Whereas for smartcard authentications using Identity Agent, a user interaction will only occur if Identity Agent no longer holds an active session, thus user presence can be inferred in so much as their smartcard has not been removed from the smartcard reader.

When considering this option thought should be given as to the frequency of use. Too frequent use may give an unacceptable user experience for users of most authenticators.

SSO use case

If you do not need to meet the stringent standards required for NIST AAL3 session management, or if your application is likely to be deployed alongside other applications using CIS2 Authentication, you may choose to take advantage of the CIS2 Authentication to obtain the benefits of single sign-on (SSO).

Two options are possible, as follows.

Option 1 - no prompt parameter

Make an authentication request without providing a prompt parameter. If the user has an active session as the result of an authentication by another application then they will not be asked to re-authenticate and the resulting ID token will contain an auth_time claim containing the time that the user was last authenticated. If the user does not have an active session then a new authentication will occur. In either case the resulting ID token will contain an auth_time claim containing the authentication time. You can use this information to determine whether you wish to create your own application session or to request a new authentication using the prompt=login parameter.

Note that the existence of a previous authentication does not guarantee the current presence of the user. The level of risk to accept is a matter for you but it should be noted that for NIST AAL3 session management a period of inactivity of 15 minutes is seen as grounds for re-authentication.

Option 2 - no prompt parameter with max_age

The option above can be modified by the use of a max_age parameter. In this case re-authentication will occur even if a CIS2 Authentication session exists, if the previous authentication occurred longer ago than the time specified in the max_age parameter. The max_age time should be expressed in seconds, for example max_age=900 will result in re-authentication if 15 minutes has elapsed since the previous one.

The same caveat applies to this option as for option 1.


Last edited: 17 March 2026 10:59 am