Written by Technical Team | Last updated 15.08.2025 | 18 minute read
NHS Care Identity Service 2 (CIS2) is the national identity and access management platform designed for professionals and approved partners who need secure access to NHS systems. Unlike citizen-facing logins, CIS2 is aimed at workforce authentication where assurance, auditability and policy controls must meet the bar for clinical safety, privacy and regulatory obligations. When you integrate with CIS2, you’re plugging into a high-assurance trust fabric that ensures people are who they claim to be, they’re acting in the right role, and they’re using a modern, phishing-resistant authentication method.
OpenID Connect (OIDC) is the protocol layer CIS2 uses to federate identity. It sits on top of OAuth 2.0 and gives you the standard building blocks—authorisation requests, ID Tokens, UserInfo—so your application doesn’t have to invent its own session model or token semantics. With OIDC, your service delegates authentication to CIS2, then consumes signed tokens to establish a session, determine the user’s role, and apply access controls. The flow is familiar to modern developers and, crucially, interoperable with widely used libraries and frameworks.
FIDO2 and WebAuthn bring the phishing-resistant factor. Where passwords and OTPs can be phished or replayed, WebAuthn binds a private key to the user’s authenticator and the origin of your site. In the CIS2 context, this typically manifests as security keys or platform authenticators (including passkeys), which deliver a cryptographic challenge-response the moment the professional logs in. The upshot is reduced attacker success, lower help-desk burden, and a material uplift in user experience once the initial registration friction is out of the way.
From a product perspective, combining CIS2 (for identity proofing, federation and role/organisation context) with OIDC (for protocol compatibility) and FIDO2/WebAuthn (for strong authentication) gives you a pathway to implement “secure by default” authentication without sacrificing the ergonomics clinicians and administrators need. It also positions your solution to meet NHS cyber guidance and the industry push away from phishable factors.
At a high level, your service acts as an OIDC Relying Party (RP). You register a client with the CIS2 Identity Provider (OP), configure redirect URIs and metadata, and then perform the Authorisation Code flow with PKCE. The “with PKCE” detail matters; it protects the code exchange and is treated as table stakes for modern OIDC. When your user initiates sign-in, you redirect them to CIS2’s authorisation endpoint with a well-formed request containing your client ID, redirect URI, requested scopes, response type and code challenge. After a successful authentication ceremony—potentially including WebAuthn or passkey use—the OP posts an authorisation code to your redirect endpoint. Your server then performs a back-channel token exchange to obtain an ID Token and, optionally, an access token and refresh token depending on your registration and scopes.
Two aspects deserve special attention in a CIS2 context: claim quality and alignment with NHS policy. The ID Token is a signed JSON Web Token (JWT) containing OIDC core claims (such as iss, aud, exp, iat, sub) and NHS-specific attributes. You should assume tokens are short-lived and be ready to re-authorise or refresh gracefully. Your backend must verify the signature against the OP’s JSON Web Key Set (JWKS), check the issuer and audience, and enforce expiry and nonce validation. The nonce links the front-channel request to the returned token, cutting off replay. Pair this with state validation to prevent CSRF in your login flow.
Roles and organisations are where CIS2 becomes more than just “log in”. Clinical systems often gate features by professional role or the organisation context the user has chosen for the session. If your product surfaces patient data, performs ordering, or exposes administrative functions, you’ll need to translate CIS2 claims into your authorisation model. This can be as simple as mapping role codes to application roles, or as sophisticated as a policy engine that evaluates claim bundles and context (such as site, job role, and the authentication assurance achieved).
Because CIS2 relies on OIDC, you inherit well-understood error handling patterns. Redirects may return error parameters (for example access_denied or interaction_required) where the identity provider needs additional steps or the user cancels. Plan for these gracefully and present actionable guidance, not cryptic error codes. On the token exchange, you’ll receive OAuth 2.0-style error responses; treat them as signals that either your configuration is out of step or the code exchange was intercepted or re-used. Robust logging (without leaking sensitive data) is essential for troubleshooting.
Token storage strategy is another architectural decision point. In a browser application backed by a server, prefer keeping tokens on the server side and using an HTTP-only session cookie for the browser. This limits exposure to client-side scripts and reduces the risk of token exfiltration. If you’re building a single-page application (SPA), consider a backend-for-frontend (BFF) pattern so that the front end never directly holds tokens. While OIDC supports a range of flows, NHS-facing applications almost always benefit from keeping sensitive material out of the browser whenever possible.
The introduction of FIDO2/WebAuthn affects the login ceremony, not your core OIDC plumbing. WebAuthn registration and authentication occur as part of the CIS2 identity provider’s interaction. You don’t need to implement WebAuthn ceremonies yourself unless you’re adding a second factor for your own app. What you do need is to be ready for a smoother user experience and to avoid breaking it: ensure your login redirects maintain origin integrity, avoid cross-domain pop-up gymnastics that confuse the browser’s origin checks, and keep your site on HTTPS with a stable domain so platform authenticators can bind correctly.
Before you write code, establish the end-to-end view of your traffic flows, dependencies and trust anchors. If you treat CIS2 purely as a “black box login” you’ll miss the crucial context around role and organisation selection and the assurance levels your clinical customers expect. Define what you need from identity (user ID, job role, organisation, assurance level, multi-tenancy context), where you’ll store it, and how you’ll re-hydrate a session if tokens expire mid-workflow.
Start with client registration. You’ll obtain a client ID, set allowed redirect URIs, and agree scopes. If you operate multiple environments (local, dev, staging, production), register their redirect URIs explicitly and keep them consistent. Decide whether you need a confidential client (server-side with client secret) or a public client (native application). For browser-based web apps, a confidential client with a server-side code exchange plus PKCE is the default. Ensure you understand the token lifetimes that will be configured for your client: there’s a world of difference between a five-minute access token with refresh and a short ID Token that requires periodic re-authentication.
Next, implement the OIDC Authorisation Code flow. Use a mature OIDC library in your chosen stack—this isn’t the place for hand-rolled crypto. Configure discovery from the OP’s metadata, enforce PKCE, and generate high-entropy state and nonce values per request. Store them securely (for example, in a server-side store keyed to the user’s session). On receipt of the callback, validate everything before exchanging codes: match the state, check the anti-replay requirements, and then go server-to-server for tokens. With tokens in hand, verify the ID Token signature and claims, then establish your session based on the canonical subject identifier and role/organisation context.
Finally, design how your application will represent and persist the user’s context. If a professional can act within multiple organisations or roles, be ready to prompt for a choice after login or accept a selection already made in the identity provider. Cache this context in your session store and include it in your audit metadata for every action that matters. If you support multi-tab usage, ensure that context changes are consistent across tabs without surprising mid-task switches.
Checklist to accelerate a clean first CIS2 integration:
If you get the UX right, FIDO2/WebAuthn will feel almost invisible to users while dramatically improving your security posture. The authenticators can be roaming (security keys over USB/NFC) or platform (built into the device and backed by biometrics). Passkeys generalise platform authenticators across devices, letting users sign in with a device-sync’d credential rather than a password or OTP. In the CIS2 journey, the identity provider handles the WebAuthn ceremony; your job is to avoid any integration choices that break the browser’s security model or confuse the user during redirects.
The single biggest enabler of smooth WebAuthn is origin stability. WebAuthn ties keys to the “Relying Party ID” (RP ID), which is derived from the domain. If your application ricochets the user across multiple subdomains during login, you’re more likely to hit confusing prompts or failures. Keep your login initiation and callback on the same primary domain and use clear, predictable URLs. Resist the temptation to open the provider’s authorisation screen in a pop-up; use a full-page redirect that respects the origin semantics and the browser’s back button.
Once authenticated, keep the session alive thoughtfully. Many clinical tasks are bursty—periods of intense interaction followed by pauses. If you set aggressive session timeouts you’ll interrupt flows and trigger repeated WebAuthn prompts through re-authentication. Pair a reasonable idle timeout with well-signposted renewal points, and consider preserving unsaved work if a timeout occurs. If your security model demands step-up authentication for sensitive actions, make that journey consistent with the main login and avoid introducing a weaker second factor.
Think carefully about account linking and first-time user journeys. Professionals might have been provisioned centrally, but your application still needs to create or link a local profile on first sign-in. This is an opportunity to capture preferences, confirm role mappings and consent to terms—but it’s also a chance to create friction. Keep first-run steps minimal and revisit non-essential configuration later, not during the critical moment a clinician is trying to complete a task.
Accessibility is non-negotiable. WebAuthn works well with biometrics and platform prompts, but your UI must remain operable for keyboard-only users, screen-reader users and people who cannot use biometrics. Ensure focus management is robust around redirects, describe the authentication step clearly, and provide alternative methods consistent with policy for those unable to use a particular authenticator type.
UX and security hardening patterns that pay off:
A sound integration is about more than a successful login—it must stand up to scrutiny on auditability, data minimisation and operational resilience. Start by defining the personal data you actually need to store. With OIDC, you receive claims that could be sensitive or unnecessary for your application. Persist only what you require for authorisation decisions, auditing and customer support. If you need to display a name, store the display name; if you only need the subject identifier and role code, don’t warehouse extra profile data because it “might be handy later”.
Audit trails should be complete but not noisy. Record when a session is established, refreshed and terminated, which roles and organisations were in effect, and the token identifiers necessary to link events across your logs without storing token bodies. For data protection impact assessments, this level of instrumentation helps demonstrate that access was authorised and consistent with policy. Equally, make sure your logs don’t become a liability by spilling PII or long-lived secrets.
Session management is a subtle but crucial control. Many security incidents boil down to session theft rather than protocol failure. Protect session cookies with HTTP-only and secure flags, rotate session identifiers after privilege changes, and terminate sessions on logout server-side. If you operate a multi-service platform, centralise session validation to avoid orphaned sessions on microservices that never hear about a logout. For native applications, use the system’s secure storage, and treat refresh tokens like crown jewels—locked down, bound to the device context if supported, and rotated regularly.
Key management and crypto agility matter even if you’re not the one signing tokens. OIDC providers rotate signing keys; your RP must track the OP’s JWKS, cache keys responsibly and handle rotations without observable downtime. Avoid pinning to a single key. Verify algorithms declared in the token against a whitelist; don’t accept none, and don’t trust the header alone—validate the signature against the advertised public keys from discovery metadata. Enforce clock skew tolerances but don’t be so strict that a few seconds of drift causes intermittent failures; five minutes of leeway is common and practical.
From a compliance perspective, authentication is just one leg of the journey. You also need to consider authorisation (role-based access control that aligns with clinical roles), consent where relevant, and information governance principles. If you process patient data based on role and organisation context, you should document how those contexts map to your access controls. Make it clear how you’ll handle edge cases such as locum staff, staff moving organisations, or users with multiple roles. The ability to react quickly to role changes is essential; plan for a nightly synchronisation at minimum and support “just in time” validation on login so that revocations take effect without delay.
Finally, build for operational resilience. Identity providers, like any service, can experience degradation. Your application should degrade gracefully if the OP is slow or temporarily unavailable: show a status page, queue non-urgent operations that depend on user context, and avoid hammering the provider with retries that worsen the situation. Maintain active contact with platform teams to get early warning of changes such as certificate rotations, endpoint deprecations or new scopes becoming mandatory.
Testing a CIS2 integration is not just about unit tests around the callback handler. It’s an end-to-end exercise that includes protocol correctness, role mapping fidelity, UX polish and operational readiness. Begin with protocol conformance tests using your chosen OIDC library’s built-in tools or community test suites. Validate discovery, PKCE generation, state and nonce handling, token exchange and verification. Introduce negative tests deliberately—incorrect client secrets, mismatched redirect URIs, expired codes—to ensure your error paths are as robust as your happy paths.
Broaden into integration scenarios that mimic real user journeys. Have testers log in with different role combinations and organisation contexts, switch roles mid-session if supported, and attempt actions that trigger step-up prompts. Observe how the UI behaves around WebAuthn challenges: are prompts visible? Do screen-readers announce them? Can users recover if they cancel a biometric prompt or detach a security key? These are the rough edges that turn into support tickets if you miss them before go-live.
Performance testing deserves a spotlight. OIDC redirects add round trips, and while identity providers scale, your application still needs to handle bursts—morning logons at the start of a clinic or when an outage clears. Profile your login path under load. If you render heavy pages immediately after login, you’re compounding latency at the exact moment users are least patient. Lightweight post-login landing pages help get users “to green” quickly while background components warm up, fetch role-scoped data and initialise caches.
Operational readiness is as much about people and runbooks as it is about code. Document how to rotate client secrets safely, how to roll back a misconfiguration and how to validate the OIDC metadata when something looks off. Provide your support team with a concise checklist: how to read logs for a failed code exchange, how to distinguish user cancellations from genuine errors, how to identify expired tokens versus clock skew. Include a playbook for responding to trust anchor changes or planned maintenance windows so you’re not diagnosing from scratch under pressure.
Troubleshooting in production often starts with a cryptic error during the authorisation step or token exchange. Your first triage question is origin and redirect integrity: does the callback match the registered URI exactly (including scheme and path)? Are you maintaining the state parameter end-to-end? If the user reports “something popped up and then disappeared”, suspect blocked pop-ups or cross-origin issues; that’s one reason to avoid pop-up flows for OIDC. If the error occurs after apparent success at the provider, focus on token verification: is your JWKS cache stale, has the signing key rotated, or are you rejecting a valid algorithm due to an overly strict configuration?
Time drift is a frequent culprit in intermittent verification failures. Tokens with short lifetimes plus skewed server clocks generate confusing “token used before issued” or “expired token” errors. Monitor NTP on every host that validates tokens. Also check that you’re not accidentally validating the wrong clock—container clock versus host clock can diverge in certain deployments if time sync is misconfigured. A small amount of tolerated skew prevents unnecessary flaps while still enforcing freshness.
Edge cases with WebAuthn merit their own debugging path. If users report being asked to authenticate repeatedly, examine your session renewal logic—perhaps silent refresh is not working, or you’re discarding sessions on non-fatal errors. If certain devices fail at the WebAuthn step, verify the browser and OS behaviour for platform authenticators and ensure your redirect domains satisfy the RP ID constraints. Where roaming keys are used, confirm that your sign-in page has obvious prompts to insert or tap the key; avoid “dead air” while the browser waits for an authenticator with no visible cue.
Before go-live, conduct a dress rehearsal with a representative pilot group. Choose clinicians and administrators who will use the full breadth of your features. Monitor the live logs for any unusual spikes in error rates, latency on the token exchange, or role-mapping mismatches. Collect feedback not just on success/failure but also on the feel of the flow: did anything surprise users, were prompts clear, and did they trust the process? This qualitative input is invaluable for smoothing the last wrinkles.
After launch, keep an eye on leading indicators. Rising help-desk contacts about login suggest confusion or a regression. Increased rates of interaction_required responses may indicate a policy change at the identity provider or a difference in device behaviour following an OS update. Create dashboards that correlate login errors with client versions, browsers and device types so you can spot patterns quickly. When you do need to make changes—say, to add a new scope, rotate a secret or adjust cookie attributes—release them first to a small cohort to validate assumptions in the wild.
In the longer term, treat authentication not as a one-and-done integration but as a living interface. Standards evolve; passkeys are improving rapidly, browsers tweak security models, and healthcare requirements shift. Keep your OIDC library up to date, track deprecations in endpoints or algorithms, and stay in dialogue with platform owners about upcoming changes. Consider adding defence-in-depth features like device binding or conditional access signals if they become available in your identity fabric. And periodically re-run your threat model: what was sufficient last year might not be adequate tomorrow, especially as attackers continue to target healthcare.
Integrating NHS CIS2 using OIDC, FIDO2 and WebAuthn is an opportunity to modernise your application’s security and streamline the user journey for busy professionals. Architect around the Authorisation Code flow with PKCE, keep tokens server-side, and rigorously validate ID Tokens. Let CIS2 handle the heavy lifting of high-assurance authentication while you focus on clean session design, reliable role and organisation mapping, and friction-light UX. Harden your implementation with strong cookie policies, discovery-driven configuration, JWKS rotation, and clear error paths. Test the edge cases that matter in clinical settings—timeouts, mid-task re-auth, role changes—and equip your support teams with the right diagnostics. With these foundations, you’ll deliver a sign-in flow that is secure by default, trusted by clinicians, and resilient under real-world pressure.
Is your team looking for help with CIS2 integration? Click the button below.
Get in touch