Skip to main content

Keep your software secure

Learn about key concepts and practices you need to secure your application (or software)

Overview

As a software developer, you will undertake many design activities that build security in each layer of your application. This page focuses on your responsibilities when your software connects to NHS England APIs to work with sensitive patient and healthcare data.

Some of the existing standards or compliance that are particularly important to consider are:

The first three are aimed at how you secure your company and its servers, whereas OWASP focuses on how you build applications.

This page expands on some key concepts, definitions and patterns that help secure your applications.


Accessing NHS England APIs

If you want to connect to NHS England APIs, we ask you to go through an onboarding process where you check your product against our compliance and security requirements.

Security assurances asked for during onboarding

Security assurances asked for during onboarding

  • it is your responsibility to design a solution that meets the needs of a confidential client
  • it is your responsibility to store credentials and tokens securely
  • it is your responsibility to rotate keys regularly
  • it is your responsibility to have soft controls in place for when your hard controls cannot deal with risks around human processes

Confidential clients

To help you design your application, the OAuth standard defines two types of devices (which can be a phone, laptop, server or similar):

  • public client
  • confidential client

A public client is one that isn't able to keep your application secrets secure. For instance, you have little or no control over the browser of a user. To help ensure your application doesn't lose data or secrets, you design your service to keep the sensitive items away from the `public client`.

NHS England currently does not support public clients, nor some variants of desktop clients, nor native apps. We are working on options for this.

When connecting to NHS England services, we require your software to do it from somewhere secure. This could be a data centre or cloud provider. Your server, when connecting to NHS England is acting as a `client`, and we require it to meet the definition of an OAuth `confidential client`. 

This is not a fixed standard, but says you need to design your software (and its deployment process) to be secure. You do this by considering "hard" (technical) controls such as:

  • access control
  • physical security
  • encryption and cryptography
  • software updates and patching

These need to be supplemented by "soft" controls:

  • risk based compliance activities
  • organisational controls

Your organisation should have already completed a Data Security Protection Toolkit (DSPT) which covers all this.

However, you as a developer (or tech lead), need to design your application to keep your secret material on secure servers.

For more detail, you can read the OAuth 2.0 standard that defines these client types: Section 2.1 of RFC6749.


Credentials and secrets

Your software will need to store credentials (e.g. username and passwords) for many internal and external services. In addition, you might need to keep arbitrary secrets such as a key to unlock encrypted data.

To keep these secure you should:

  • store the values in a secure vault
  • restrict access
  • audit who looks at the values
  • never write unencrypted values to storage
  • the software should only retrieve the values at runtime
  • encrypt them, whilst in transit, e.g. use HTTPS

Ideally you should go further and remove all human access:

  • in your deployment pipelines, automate the creation of secrets
  • place them straight into the secure vault
  • only allow your software to retrieve the unencrypted values
  • never let the values leave your "confidential client" boundary (except for use!)

There are also newer advanced technologies, such as HSMs (Hardware Security Modules) and TPMs (Trusted Platform Modules). For some types of situations, these can be leveraged to improve security.

 


Tokens

Tokens are used instead of passwords and other secrets to massively reduce exposure of sensitive values. They can, additionally, convey data (termed claims) between different parts of the solution.

There are many resources to help you learn about the full definitions, this section focuses on three main types:

  • Access
  • Refresh
  • ID (Identity)

Access tokens are used on every API request, and show that your software is allowed to access that API (or not). Under OAuth it is placed in the Authorization header as a bearer type, and you don't need any other proof. We keep the life time very short for access tokens because they are so sensitive.

Refresh tokens are useful for user-restricted situations, where you need to access APIs longer than the 10 minute life time of the Access token. Rather than asking the user to re-authenticate you can use the Refresh token to get a new Access token. Your system needs to prove that it is the owner of that Refresh token when asking for the Access token, so it is not as sensitive as the Access token.

ID tokens are designed to be transparent and contain information about the identity of the token holder. You can gain access to APIs by swapping an ID token for Access tokens, but just having the ID token isn't enough. You have to prove that your system has been authorised for this by authenticating your software (`client authentication` in OAuth terminology).

Access and Refresh tokens are the most sensitive. These must be kept on the confidential client(s).

ID tokens are still sensitive, but are intended to be (under specific conditions) passed around to grant access or identify a user. For instance, your application might require the identity of the user in the web browser (public client), so the ID token might be made available there. 


Private keys

Public and private key pairs deliver highly secure authentication - but the security is dependent on the private keys being kept safe. If a bad actor gets hold of the private key, they can pretend to be you.

Two important ways to help keep your private keys secure are:

  • reduce (remove) humans being able to see the private key
  • rotate your keys regularly

Passwords have to be passed between systems, giving opportunities for malicious actors or compromised systems to get hold of it. Cryptographic security allows you to never pass the underlying secret (private key), making it significantly more secure.

To reduce the number of occasions when the private key needs to be visible you can:

  • use automation in your CD (Continuous Deployment) pipeline to create the public and private key pair
  • put the private key into a secure vault, and don't ever write it to disk
  • when your software needs to sign the data, it should pull it down from the secure vault to just the server (VM / container) that needs it. Don't distribute to every server
  • if it is a high performance environment you can cache it in memory, but encrypt it - a number of languages now provide this feature natively

It is now technically possible to keep secrets hidden from both humans and other systems by using a Hardware Security Module (HSM).  The HSM creates public and private key pairs, and then accepts requests to sign payloads with the private key. The private key is never allowed to leave the HSM.

When designing your cryptographic security consider:

  • randomness of your private key
  • length of private key
  • algorithms used
  • your code should never be tied to a specific algorithm, although it can specify a minimum as a configuration option

Make sure you are following the latest guidance, and when a new standard or recommendation comes out ensure it is planned into future releases of your software.

 


Zero downtime key rotation

Your cyber security group should have policies in place, but we recommend you rotate your private keys monthly. There are more and more exploits which sit quietly in background that are hard to notice. By doing this, if a key is leaked / stolen it limits the impact.

Also consider that annual processes can mean teams can struggle to remember what to do each year - potentially even leading to service outage. By going for more frequent rotation, it encourages you to automate the process.

Zero downtime key rotation is the largest benefit of using the JSON Web Key Set (JWKS) approach, you don’t even need to involve any other third party when changing keys.

The standards work together for zero downtime in the following ways:

  • you publish your own public keys – you don’t rely on anyone else
  • near the time of rotation, you publish both the old and new keys
  • the standards allow you to publish both in the same file (a JWKS endpoint), using a key unique identifier (kid) to distinguish between them
  • your application starts to use the new key and changes the kid in all new JWTs
  • after a suitable period, you can remove the old public key

This dual running period allows any in-progress requests and any cached versions of your public key to expire. It is important that third parties, that use your JWKS, have a relatively low caching period (e.g. 24 hours). Alternatively, the standard specifies the logic of retrieving a new JWKS file when the kid is not found in the cached version.

When working with the API Platform, we only support one JWKS url per environment. We do offer hosting of your JWKS, however, this is only intended for new projects with tight timescales. Once you are up and running, switch to hosting your own JWKS endpoint.  


Automating rotation

Whilst the private key JWT rotation is a simple concept, there are quite a few design aspects to get right. 

This is a list of considerations to help you implement it:

  • do automate the creation of public private key pairs – maybe create a dedicated deployment pipeline to rotate keys
  • the JWKS doesn’t have to be on the server with the private keys – you could publish it on a Content Delivery Network (CDN) or similar
  • never use the same private / public key pair across environments
  • ideally do not use the same JWKS endpoint for more than one environment
  • make key generation and use as simple as possible. For instance, if it makes deployment easier to have many private / public key pairs in on one environment then do so

Rotating your credentials

Standard practice is to rotate your passwords and other credentials regularly.

Similar to key rotation, if you can automate the process it significantly improves security. Once automated, e.g. in your CI / CD pipeline, you could also consider monthly rotation.

However, the systems you are connecting to might not support zero downtime credential rotation. You need to assess the potential impacts to ensure you don't reduce the availability of your service by doing this.

Last edited: 23 October 2023 4:54 pm