Skip to main content

User-restricted RESTful APIs - NHS Care Identity Service 2 combined authentication and authorisation

Learn how to integrate your software with our user-restricted RESTful APIs - using our NHS Care Identity Service 2 combined authentication and authorisation pattern.

Overview

This page explains how to integrate your software with our user-restricted RESTful APIs.

In particular, it describes the NHS Care Identity Service 2 (NHS CIS2) combined authentication and authorisation pattern, which uses our OAuth 2.0 authorisation server.

For a full list of available patterns, see Security and authorisation.


When to use this pattern

Use this pattern when:

  • accessing a user-restricted RESTful API
  • the end user is a healthcare worker
  • you want a simpler integration
  • you do not need the healthcare worker's identity information

In particular, this pattern is not appropriate when building GP software.


How this pattern works

In this pattern, authentication and authorisation are done together. Authentication is done by NHS CIS2 Care Identity Authentication API but we co-ordinate that under the covers behind our OAuth2.0 authorisation server. Your application only needs to be registered with the API Platform, not NHS CIS2.

The healthcare worker authenticates with either an NHS smartcard or a more modern alternative. To use smartcards, you need to be connected to the Health and Social Care Network (HSCN).

The following diagram illustrates the pattern:

include
access token
include...
Calling Application
Calling Applicati...
User-Restricted
API
User-Restricted...
authenticate
user
authenticate...
Authorization Server
(OAuth2.0)
Authorization Ser...
authenticate and
authorise user
authenticate and...
get access
token
get access...
NHS CIS2
(Open ID Connect)
NHS CIS2...
Healthcare worker
Healthcare worker
Viewer does not support full SVG 1.1 Context diagram of combined authentication with CIS2 and authorisation with OAuth 2.0


The following sequence diagram shows how the various components interact:

Calling Application
Calling Applic...
Authorization Server
Authorization...
NHS CIS2
NHS CIS2
Calling Application
Calling Applic...
Authorization Server
Authorization...
User-Restricted API
User-Restricte...
do something
do something
launch application
launch application
redirect to
authorisation
redirect to...
redirect to authorisation (/oauth2/authorize)
redirect to authorisation (/oauth2/authorize)
redirect to authentication
redirect to authentication
display sign in page (or equivalent)
display sign in page (or equivalent)
redirect to authentication
redirect to authentication
redirect back to authorisation
redirect back to authorisation
sign in
sign in
redirect back to calling application
(with authorisation code)
redirect back to calling application...
redirect back to authorisation
redirect back to authorisation
redirect back to
calling application
redirect back to...
display home page
display home page
return access token
return access token
get token
(/oauth2/token)
get token...
call user-restricted API
(include access token)
call user-re...
Healthcare worker / Browser
Healthcare worker / Browser
time passes
time passes
Viewer does not support full SVG 1.1 Sequence diagram of combined authentication with CIS2 and authorisation with OAuth 2.0


In words:

  1. The healthcare worker launches the calling application.
  2. The calling application redirects the healthcare worker's browser to our OAuth2.0 authorisation endpoint (/oauth2/authorize).
  3. The healthcare worker signs in to their NHS CIS2 account (using a smartcard and PIN, or thumbprint reader, or other method).
  4. Our authorisation server redirects control back to the calling application, with an authorisation code.
  5. The calling application calls our OAuth2.0 token endpoint (/oauth2/token), with the authorisation code, and receives an access token in return.
  6. Time passes, until the healthcare worker needs to access a user-restricted API.
  7. The calling application calls the user-restricted API, including the access token.

Using this pattern with CIS

If you are already using our original Care Identity Service (CIS) in your application, see Using CIS2 with CIS for API access.


Tutorial

You can learn how to use this security pattern with our hands-on user-restricted RESTful API tutorial.

Bear in mind that the tutorial only teaches you the basic flow. You also need to read the detailed integration instructions below to understand how to handle alternative flows such as error scenarios and token refreshes.


Detailed integration instructions

The following diagram shows the high level integration phases with the API platform and the sections below it explain in detail how to use this security pattern.

Set up your application
Set up your appli...
Authorise your application
Authorise your ap...
Interact with our user-restricted APIs
Interact with our...
Phase 1
Phase 1
Phase 2
Phase 2
Phase 3
Phase 3
Viewer does not support full SVG 1.1 Phase 1 set up your application, phase 2 authorise your application, phase 3 interact with our user-restricted APIs

Environments and testing

As well as production, we have a number of test environments. Each environment is paired with a suitable CIS2 environment. In the steps below, make sure you use the appropriate URL base path:

Environment Sign-in method Availability URL base path Paired CIS2 environment
Sandbox Simulated sign-in - no smartcard needed Hello World API only (all other sandbox APIs are open-access) sandbox.api.service.nhs.uk/oauth2 Not applicable
Integration test Simulated sign-in - no smartcard needed - second generation All APIs int.api.service.nhs.uk/oauth2-mock Not applicable
Integration test Simulated sign-in - no smartcard needed - first generation - deprecated All APIs int.api.service.nhs.uk/oauth2-no-smartcard Not applicable
Integration test NHS CIS2 - smartcard and PIN or modern alternative All APIs int.api.service.nhs.uk/oauth2 Integration (INT)
Production NHS CIS2 - smartcard and PIN or modern alternative All APIs api.service.nhs.uk/oauth2 Live

For more information on testing, see Testing APIs.


Phase 1: Set up your application

This section explains the detailed steps to set up your application before you can initiate authorisation. The steps involved are:

  • register your application on the API platform
  • trigger the authorisation journey
  • healthcare worker completes authentication and authorisation
  • receive authorisation results

Step 1: Register your application on the API platform

To use this pattern, you need to create an application. This gives you access to your API Key and Secret, and allows you to specify your Callback URL, all of which you will need later in the process.

  1. If you do not already have one, create a developer account.
  2. Navigate to my developer account and sign in.
  3. Select 'My applications' and 'Manage your applications'.
  4. Select 'New app'.
  5. Enter details for your application and click 'add application' to create it.
  6. Select your application and then 'edit more application details'.
  7. Make a note of the API Key and Secret.
  8. In the list of APIs, find the API you want to use and activate it by clicking 'Enable' and 'save'.
  9. Enter the Callback URL for your application. See step 4 for more details.

Step 2: Trigger the authorisation journey

When you want to start authorisation, your software should launch a browser window, or redirect the current browser window to our OAuth 2.0 authorisation endpoint:

https://api.service.nhs.uk/oauth2/authorize

Note: the above URL is for our production environment. For other environments, see Environments and testing.

You need to include a number of parameters to make it work:

Parameter Description
response_type The OAuth 2.0 response type. Currently the only acceptable value is code.
client_id

Your application's API Key from step 1.

redirect_uri

Your application's Callback URL from step 1, URL encoded. We use this to send users back to your application after successful (or unsuccessful) authorisation.

state A value your software should generate randomly and then store for later. This is for security purposes - we pass it back to your application via the redirect_uri and used in step 4 to recognise a legitimate redirect.

Here's an example redirect:

curl -X GET "https://api.service.nhs.uk/oauth2/authorize?\
response_type=code\
&client_id=ToabcdPayTQACdxyzJK1234nKUD0Ag7J\
&redirect_uri=https%3A%2F%2Fwww.example.com%2Fcallback\
&state=30de877c-ee2f-15db-8314-0800200c9a66"

Note: the URL in the above example is for our production environment. For other environments, see Environments and testing.

Error scenarios

If there is an issue with your call to our authorisation endpoint, we will return an error response to the healthcare worker's browser, as follows:

Error scenario HTTP status Error code Error message
Response type is missing 302 (Found) invalid_request response_type is missing
Response type is invalid 302 (Found) unsupported_response_type response_type is invalid
Client ID (API Key) is missing  401 (Unauthorized) invalid_request client_id is missing
Client ID (API Key) is invalid 401 (Unauthorized) invalid_request

client_id is invalid

Client ID (API key) is not authorised for the /authorise endpoint 401 (Unauthorized)

access_denied

API Key supplied does not have access to this resource. Please check the API Key you are using belongs to an app which has sufficient access to access this resource.
Redirect URI (Callback URL) is missing 400 (Bad Request) invalid_request redirect_uri is missing
Redirect URI (Callback URL) is invalid 400 (Bad Request) invalid_request redirect_uri is invalid
State is missing 302 (Found) invalid_request state is invalid

Step 3: Healthcare worker completes authentication and authorisation

Authentication

Using the browser session your software triggered in step 2, the healthcare worker signs in to their NHS CIS2 account.

If they are using an NHS smartcard, they need the following:

  • an HSCN connection
  • a smartcard reader attached to their device
  • the Identity Agent software installed on their device
  • the NHS Credential Management software installed on their device

To see which versions of Windows operating systems and browsers are supported, see Supported operating systems and browsers.

To download Identity Agent and NHS Credential Management software over your HSCN connection, see Configurations recommended by Care Identity Authentication.

If testing with our second generation mock authorisation service, enter the user ID for the test user you want to use.

If testing with our first generation mock authorisation service, simply click the 'sign in' button - you do not need any credentials.

Authorisation

Normally with OAuth 2.0, the end user is then required to grant authority to your software to act on their behalf. However, for healthcare workers using NHS APIs, we do not require the healthcare worker to explicitly grant authority, so all the healthcare worker needs to do is sign in.


Step 4: Receive authorisation results

Once the healthcare worker has completed authorisation, our authorisation server will redirect the healthcare worker's browser back to your software.

You need to provide a callback endpoint on your web server for this. If your software does not have a web server, you will need to create one. For alternative approaches, please contact us.

You need to tell us the location of your callback endpoint so we know where to redirect back to. This is the Callback URL you specified in step 1 above.

Your callback endpoint will need to expect the following query parameters:

Parameter Description
code The authorisation code, which you will need in the next step
state The value of the state parameter you passed to our authorisation endpoint

We return state back to you so you can be sure the callback has come from us. For security reasons you should check the state we returned is the same as the state you sent.

Here's an example redirect after a successful authorisation:

// Example successful authorisation redirect
HTTP/1.1 302 Found
https://testapp.domain.com/callback?code=fXplvYDHxhSDTnYOYSgX4DM9sp0&state=30de877c-ee2f-15db-8314-0800200c9a66


Phase 2: Authorise your application

This section explains the steps to get your application authorised before calling the user-restricted API. The steps involved are:

  • exchange authorisation code for access token
  • store access token for later use

Step 5: Exchange authorisation code for access token

Once you have an authorisation code, you need to call our token endpoint to exchange it for an access token. This is an HTTP POST to the following endpoint:

https://api.service.nhs.uk/oauth2/token

Note: the above URL is for our production environment. For other environments, see Environments and testing.

You need to include the following query parameters:

Parameter Description
grant_type

This is the authorization_code 

client_id Your application's API key
client_secret Your application's secret
redirect_uri Your application's Callback URL, URL encoded
code authorization_code, as received in step 4

Here's a complete example, as a CURL command:

curl -X POST -H "content-type:application/x-www-form-urlencoded" --data \
"grant_type=authorization_code\

&client_id=[YOUR-API-KEY]\
&client_secret=[YOUR-SECRET]\
&redirect_uri=[YOUR-CALLBACK-URL]\
&code=[AUTHORIZATION-CODE]" \
https://api.service.nhs.uk/oauth2/token

Note: the URL in the above example is for our production environment. For other environments, see Environments and testing.

You will receive a response with a JSON response body, containing the following fields:

Field Description
access_token The access token you use when calling our user-restricted APIs
expires_in The time after which the access token will expire, in seconds
refresh_token A token for refreshing the access token once it has expired (see step 9 below)
refresh_count The number of times the token has been refreshed so far
refresh_token expires in The time after which the refresh token will expire, in seconds
token_type Bearer

Here's an example:

{'access_token': 'Sr5PGv19wTEHJdDr2wx2f7IGd0cw',
 'expires_in': '599',
 'refresh_count': '0',
 'refresh_token': '7qvwCqqUUAmzMjRbQyrhdddwBQUJ9vmt',
 'refresh_token_expires_in': '35999',
 'token_type': 'Bearer'}

Error scenarios

If there are any issues with your call to our token endpoint, we return an error response, as follows:

Error scenario HTTP status Error code Error message
Client secret is missing  401 (Unauthorized) invalid_request client_secret is missing
Client secret is invalid  401 (Unauthorized) invalid_client client_id or client_secret is invalid
Client ID (API key) is missing  401 (Unauthorized) invalid_request client_id is missing
Client ID (API key) is invalid  401 (Unauthorized) invalid_client client_id or client_secret is invalid
Grant type is missing  400 (Bad Request) invalid_request grant_type is missing
Grant type is invalid  400 (Bad Request) unsupported_grant_type grant_type is invalid
Redirect URI (Callback URL) is missing  400 (Bad Request) invalid_request redirect_uri is missing
Redirect URI (Callback URL) is invalid  400 (Bad Request) invalid_request redirect_uri is invalid
Authorisation code is missing

 400 (Bad Request)

invalid_request

authorization_code is missing

Authorisation code is invalid  400 (Bad Request) invalid_grant authorization_code is invalid

Step 6: Store access token for later use

Your access token lasts for 10 minutes and you can use it multiple times. If you'll be making more than one API call for this user, store your access token securely for later use.

This reduces the load on our authorisation server and also reduces the chance of your application hitting its rate limit.

For details on what to do if your access token has expired, see refresh token below.

using System; using System.Collections.Generic; 

using System.IdentityModel.Tokens.Jwt; 

using System.Security.Claims; 

using System.Security.Cryptography.X509Certificates; 

using IdentityModel; 

using Microsoft.IdentityModel.Tokens;



public class JwtHandler

{    

     private readonly X509Certificate2 _cert;

     private readonly string _audience;

     private readonly string _clientId;

     private readonly string _kid;



     public JwtHandler(string pfxCertPath, string audience, string clientId, string kid)

     



{          _audience = audience;          _clientId = clientId;          _kid = kid;          _cert = new X509Certificate2(pfxCertPath);      }

     public string generateJWT(int expInMinutes = 1)

     {

         var now = DateTime.UtcNow;



         var token = new JwtSecurityToken(

             _clientId,

             _audience,

             new List<Claim>

             



{                  new ("jti", Guid.NewGuid().ToString()),                  new (JwtClaimTypes.Subject, _clientId),              }

,

             now,

             now.AddMinutes(expInMinutes),

             new SigningCredentials(

                 new X509SecurityKey(_cert, _kid),

                 SecurityAlgorithms.RsaSha512

             )

         );

         var tokenHandler = new JwtSecurityTokenHandler();



         return tokenHandler.WriteToken(token);

     }

}

Phase 3: Interact with our user-restricted APIs

This section explains the detailed activities that you need to perform to call a user-restricted API. The activities involved are:

  • determine the healthcare worker's role
  • call a user-restricted API
  • refresh your access token
  • request a new token from us

Step 7: Determine the healthcare worker's role

With NHS CIS2, healthcare workers are allocated one or more roles by their Registration Authority, for example Clinical Practitioner or Nurse.

Some of our APIs require you to send the healthcare worker's role when you call the API.

Some of our APIs also require you to implement national role-based access control (RBAC) within your software to ensure that the healthcare worker only has access to functions and information that are appropriate for their role.

If the healthcare worker has more than one role, they must select a role before using your software.

There are two ways to determine the healthcare worker's role:

1. Custom approach for smartcard users

If the healthcare worker signs in to their NHS CIS2 account with an NHS smartcard, the Identity Agent software on their device prompts them to select a role immediately after they sign in.

Healthcare workers with one role

If the healthcare worker has only one role, the Identity Agent automatically selects it for them. You do not need to send the role in the request header as the API retrieves it from the Identity Agent software on the healthcare worker's machine.

Healthcare workers with more than one role

If the healthcare worker has more than one role, they have to select one of them when prompted by Identity Agent software immediately after they sign in. You do not need to send the role in the request header, as the API retrieves it from the Identity Agent software on the healthcare worker's machine. However, if you need to override the selected role, you can send another role in the request header, which we then validate against the healthcare worker’s information.

To get the full list of the healthcare worker's roles, make an HTTP GET request to our /userinfo endpoint:

https://api.service.nhs.uk/oauth2/userinfo

To do this, you need the access token from step 5 above,

Error scenarios

If the healthcare worker's role validation is not successful, you get the following error messages when you call a user restricted API.  Follow steps 2 to 5, to avoid selected_roleid error message.

Error scenario HTTP status Error code Description
NHSD-session-URID is invalid 400 BAD_REQUEST nhsd-session-urid is invalid
selected_roleid is missing in your token 400 BAD_REQUEST selected_roleid is missing in your token

This is not a standards-compliant approach and does not work for other sign-in methods. If your software is already integrated directly with the Identity Agent, it might be appropriate to retrieve the selected healthcare worker role directly from NHS CIS2. 

For full details on how to do this, see parts 6 and 7 of the Spine External Interface Specification.

Here's a summary:

  1. Call the Identity Agent Ticket API to get the ID token for the healthcare worker's session.
  2. Call the Identity Server to get an SSO Token.
  3. Call the Identity Server to get the SAML Assertion.
  4. Get the ssbSessionRoleUid field from the Person block in the SAML assertion - this is the healthcare worker's selected User Role ID, for example 555021935107.

If the API also requires you to implement national RBAC:

  1. Find the Job Role Profile block in the SAML assertion where the uniqueIdentifier field record matches the above ssbSessionRoleUid.
  2. Get the nhsJobRoleCode field from the same Job Role Profile, for example S0030:G0100:R0570.
  3. Check this against the roles and activities in the national RBAC database.

2. Standards-compliant approach

You can get a full list of the healthcare worker's roles from our authorisation server, and present them to the healthcare worker to select a role. If the healthcare worker has only one role, you can select it for them automatically.

This approach uses open standards - OAuth 2.0 and Open ID Connect - and will work for all types of authentication, not just smartcards.

If you take this approach, healthcare workers signing in with an NHS smartcard will actually be prompted to select a role twice - once by the Identity Agent and once by your software. Their first selection will be ignored.

To use this approach, make an HTTP GET request to our /userinfo endpoint:

https://api.service.nhs.uk/oauth2/userinfo

Note: the above URL is for our production environment. For other environments, see Environments and testing.

You need to include the following headers in your call:

  • Authorization = Bearer <your access token from step 5>

Note: you should only call this endpoint within an hour of obtaining an access token. Requests made outside of this window will be rejected.

You will receive a response with a JSON response body, containing at least the following fields:

Field Description
nhsid_useruid A 12-digit identifier uniquely identifying the healthcare worker and is commonly referred to as 'SDS User ID'
name  The healthcare worker's full name.
nhsid_nrbac_roles An array of the healthcare worker's registered roles

Each of the entries in nhsid_nrbac_roles contains at least the following fields:

Field Description
org_code The organisation's ODS code
person_orgid A 12-digit identifier that uniquely identifies the healthcare worker's association with the organisation
person_roleid A 12-digit identifier that uniquely identifies the healthcare worker's role at the organisation. This is commonly referred to as 'SDS Role Profile ID'
role_code A colon-separated string of codes comprising a Primary, Secondary and Tertiary Job Role Code. This is commonly referred to as 'SDS Job Role Code'
role_name A colon-separated string of names comprising a Primary, Secondary and Tertiary Job Role Name

Here's an example:

The response may include extra optional fields. For more details on the possible fields returned, see the national rbac access section of the NHS CIS2 specification.


Step 8: Call a user-restricted API

Once you have an access token, you can call a user-restricted API.

You need to include the following headers in your call:

  • Authorization = Bearer <your access token from step 5>
  • NHSD-Session-URID  =  <healthcare worker role ID from step 7> (optional - not all APIs require this)

Here's an example, using a CURL command:

curl -X GET https://sandbox.api.service.nhs.uk/hello-world/hello/user \
-H "Authorization: Bearer [your access token from step 5]" \
-H "NHSD-Session-URID: [healthcare worker role ID from step 7]"

Note: the URL in the above example is for our sandbox environment. For other environments, see Environments and testing.

All being well, you’ll receive an appropriate response from the API, for example:

HTTP Status: 200
{
  "message": "Hello User!"
}

Error scenarios

If there is an issue with your access token, we will return an error response as follows:

Error scenario HTTP status Error code
Access token is missing  401 (Unauthorized) invalid_credentials
Access token is invalid  401 (Unauthorized) invalid_credentials
Access token has expired 401 (Unauthorized) invalid_credentials

For details of API-specific error conditions, see the relevant API specification in our API catalogue.


Step 9: Refresh your access token

Your access token expires after 10 minutes and must be refreshed.

If your access token has expired, when you call a user-restricted API, you will receive a response with an HTTP status code of 401 (Unauthorized) and an error code of invalid_credentials.

To refresh the access token, submit the expired token's corresponding refresh token to our token endpoint using grant_type of refresh_token .

You can continue to request new access tokens for up to 1 hour.  When you refresh an access token, you get a new access token and it invalidates the original access token immediately. You also get issued a new refresh token to replace the one you just used.

Example request

curl -X POST -H "content-type: application/x-www-form-urlencoded" --data \
"client_secret=[YOUR-SECRET]\
&client_id=[YOUR-API-KEY]\
&grant_type=refresh_token\
&refresh_token=[REFRESH-TOKEN]" \
https://api.service.nhs.uk/oauth2/token

Note: the URL in the above example is for our production environment. For other environments, see Environments and testing.

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{  
   "access_token": "xjPOKAmxlLXQcHkRkBf37AiaGyEx",
   "expires_in": "599",
   "refresh_token": "A6dpFV8F1yjsca4zPr5GDO0n7raSB6TQ",
   "refresh_token_expires_in": "35999", 
   "refresh_count": "1",
   "token_type": "Bearer"
}

Error scenarios  

Error scenario HTTP status Error code Error Message
Client secret is missing 401 (Unauthorized) invalid_request client_secret is missing
Client secret is invalid 401 (Unauthorized) invalid_client client_id or client_secret is invalid
Client ID (API key) is missing 401 (Unauthorized) invalid_request client_id is missing
Client ID (API key) is invalid 401 (Unauthorized) invalid_client client_id or client_secret is invalid
Grant type is missing 400 (Bad Request) invalid_request grant_type is missing 
Grant type is invalid 400 (Bad Request) unsupported_grant_type grant_type is invalid 
Refresh token is missing 400 (Bad Request) invalid_request refresh_token is missing
Refresh token is invalid 401 (Unauthorized) invalid_grant refresh_token is invalid
Refresh token has already been used 401 (Unauthorized) invalid_grant refresh_token is invalid
Access token refresh period has expired 401 (Unauthorized)

invalid_grant

access token refresh period has expired
{

    "nhsid_useruid": "910000000001",

    "name": "USERQ RANDOM Mr",

    "nhsid_nrbac_roles": [

        {

            "org_code": "RBA",

            "person_orgid": "555254239107",

            "person_roleid": "555254240100",

            "role_code": "S8000:G8000:R8001",

            "role_name": "\"Clinical\":\"Clinical Provision\":\"Nurse Access Role\""

        },

        {

            "org_code": "RBA",

            "person_orgid": "555254239107",

            "person_roleid": "555254242102",

            "role_code": "S8000:G8000:R8000",

            "role_name": "\"Clinical\":\"Clinical Provision\":\"Clinical Practitioner Access Role\""

        },

        {

            "org_code": "RBA",

            "person_orgid": "555254239107",

            "person_roleid": "555254241101",

            "role_code": "S8000:G8000:R8003",

            "role_name": "\"Clinical\":\"Clinical Provision\":\"Health Professional Access Role\""

        }

    ]

}

Step 10: Request a new access token from us

You can continue to request new access_tokens for up to 1 hour.

After that, calls to our token endpoint will return an HTTP status code of 400 (Bad Request) and an error code of invalid_request.

If this happens, you must send the healthcare worker back through the full authorisation process from step 2 above.

Note that NHS CIS2 session cookies last for 10 hours, so the healthcare worker does not need to re-authenticate. However, the system might check, for example, that their smartcard is still inserted.


Revoking authority

If you use a smartcard to authenticate and then remove your smartcard from the reader, we revoke your access and refresh tokens using Back Channel Logout. This extra level of security ensures your tokens cannot be used if you are no longer present.

For details on how else to revoke an access token, contact us.

Last edited: 20 June 2022 5:05 pm