Written by Technical Team | Last updated 30.09.2025 | 13 minute read
When you build anything that touches patient communications, security is not a nice-to-have — it is the backbone of trust. NHS Notify enables organisations to send messages through channels such as SMS, email, letters and the NHS App, but the gateway for safe, reliable access is NHS Digital’s API Management (APIM) platform, coupled with modern authorisation patterns built on OAuth2 and JSON Web Tokens (JWT). This article takes a practical, engineering-first look at how to secure your NHS Notify API integration end-to-end. It explains how APIM fits into the picture, how to implement resilient OAuth2 flows, how to design JWTs that stand up to scrutiny, and how to harden your production environment so security is not left to chance. The aim is to go beyond platitudes and into the architectural and operational decisions that make the difference between a merely functional integration and one you can defend in a penetration test, a data-protection audit, or a live incident.
At the heart of most modern NHS platform integrations is the NHS Digital APIM layer. Think of APIM as both a secure front door and a policy enforcement point that sits between your client application and the downstream services that actually process messages. APIM terminates TLS, authenticates callers, applies reusable policies (such as IP allow-listing, rate limiting and schema validation), and forwards only compliant traffic to the service behind it. This separation of concerns gives security teams a consistent control plane, while allowing the product team behind NHS Notify to evolve the service without forcing every consumer to constantly rework connectivity and protection patterns.
APIM’s value to security is not just in authentication. In most deployments, APIM is where you define and enforce global controls that would otherwise be duplicated in every client: strict TLS configuration, request and response size limits to blunt payload-based attacks, header and parameter validation to reduce injection risks, and anomaly detection to identify unusual call patterns. The best integrations treat APIM policies as a versioned part of their own codebase, reviewed alongside application changes so the security posture evolves in lockstep with functional releases. It is a common mistake to treat APIM configuration as an operational footnote; treat it instead as a first-class artefact with peer review and change control.
From a connectivity perspective, you should assume two trust boundaries: between your system and APIM, and between APIM and the backend services that implement Notify functionality. Your responsibility is the former. Establish mutual trust with APIM using TLS, strong client credentials, and a predictable IP footprint. If you operate in the public cloud, expose your integration through a stable egress range or private connectivity so your identity is not purely token-based but also network-bounded. For organisations with a hybrid estate, a managed outbound proxy that centralises egress and logging can simplify compliance and speed up incident response when you need to trace requests post-hoc.
Resilience is a security feature. APIM is commonly configured with rate limits and quotas to protect shared infrastructure from noisy neighbours or abusive traffic. Your integration must be architected to handle 429 (Too Many Requests) responses without falling over. That means exponential back-off, jitter, and a queue-based architecture that decouples message creation from transmission. The security relevance might not be obvious, but it is plain: when pressure mounts — say, a vaccination campaign message burst — failure modes that cause retries without control can resemble denial-of-service behaviour and trigger protective blocks. Build a producer-consumer pattern that can smooth spikes and you will earn both operational stability and a better security reputation.
Observability completes the picture. APIM is a rich source of telemetry: status codes, latency histograms, policy hits, and anomaly flags. Pipe these signals into your central SIEM and dashboard them against business-level events (campaign launch, release train cutover, data-centre maintenance). Security incidents seldom announce themselves as “breach detected”; they appear as a subtle shift in patterns. An abnormally high rate of 401s could indicate stale tokens or a credential leak. A sudden change in payload sizes might suggest probing. When your monitoring is aligned with APIM’s lens, you shorten the distance between a weak signal and an actionable response.
In most machine-to-machine NHS integrations, the OAuth2 client credentials flow is the workhorse. Your service presents its client identifier and proves possession of a secret or private key to obtain an access token from the authorisation server fronted by APIM. That token is then attached to each request to NHS Notify. The simplicity is appealing, but the devil is in the details: token lifetimes, audience and scope configuration, and how you cache and rotate secrets determine whether your integration is efficient and secure or brittle and leaky. As a rule, fetch tokens just in time, cache them centrally with automatic refresh when the expiry threshold is approaching, and never spray tokens into logs or distributed traces.
Scopes are not decorative. They encode exactly what your integration is allowed to do — for example, create a notification, retrieve delivery status, or manage templates. Resist the temptation to request broad scopes “just in case”. Least privilege is not only a design principle; it is a compensating control when other layers fail. If a token leaks, a narrow scope turns a critical incident into a constrained nuisance. In larger organisations, encode scope-assignment into your infrastructure-as-code so approvals and reviews are explicit and auditable. This also helps avoid accidental privilege creep when teams copy environment variables and scripts between sandboxes and production.
OAuth2 is the protocol; JWT is the envelope your privileges travel in. A JWT is a signed blob of JSON that tells NHS Notify who you are and what you may do. The choice of signing algorithm and how you manage keys is not administrative trivia; it is a primary defence line. Prefer asymmetric algorithms such as RS256 or PS256 so that the private key used to sign tokens never leaves your control and the corresponding public key can be distributed safely via a JWKS endpoint. Avoid HS256 for inter-organisation trust; shared secrets scale poorly and complicate rotation. If you already depend on a hardware security module or a cloud KMS, generate and store the signing key there so private material is never present on developer workstations or CI runners.
Claims design is where many integrations wobble. Start with the essentials: iss (issuer) must unambiguously identify your authorisation server; sub (subject) should refer to the calling system, not a human identity, if the flow is machine-to-machine; aud (audience) must match the API resource you are addressing; exp (expiry) and iat (issued at) must be present and short. Short tokens reduce blast radius if intercepted, but there is a performance trade-off; combine short expiries with caching and graceful refresh. Include a jti (JWT ID) to uniquely identify each token and enable replay detection. If your estate is large, embed a minimal scp or roles claim and let APIM map that to policy, rather than carrying verbose entitlements in the token.
Audience validation deserves special emphasis. The aud claim is the receiving system’s best immediate evidence that the token was minted for it. When tokens are minted for broad audiences, confusion attacks become easier: a token intended for a different API might be mistakenly accepted. Set aud to the specific NHS Notify resource or API identifier and make validation strict on both sides. It is tempting during early testing to accept “any trusted token”; resist that shortcut. Similarly, make token acceptance clock-skew tolerant but bounded — a few minutes is reasonable — and reject tokens with nbf (not before) in the future by more than your skew threshold.
Key rotation is where operational reality meets cryptography. Design for rolling changes with zero downtime. Publish public keys via a JWKS endpoint with a kid (key ID) header in each token so verifiers can select the right public key. When rotating, introduce the new key, start signing new tokens with it, and keep the old one published until its last signed tokens are naturally expired and drained. In your verifier, cache JWKS material for a short interval and fall back to refetch on cache miss; never hard-code public keys in application code. If your platform supports it, trigger JWKS cache invalidation when you publish a new key so rollovers complete in minutes rather than hours.
Payload minimalism is also a security feature. JWTs are often logged and mirrored in traces in spite of best intentions. Keep claims lean, avoid embedding personally identifiable information, and never include free-form text. If your messaging use case needs to carry context (campaign identifiers, cohort names, correlation IDs), place those in your request body or headers, not in the JWT. The token’s job is authentication and authorisation, not application-level metadata transport. A lean token surface reduces the risk that downstream systems accidentally process sensitive claims in unintended ways.
Finally, plan for verification failure as a normal event. Expired tokens, unknown kid values after rotation, or malformed signatures should lead to clear 401/403 responses. But your integration must decide whether to drop, retry, or re-mint in each case. For example, if verification fails with an unknown kid, your client should attempt to refresh its JWKS cache and retry once; if still failing, escalate to human operators. This pattern prevents transient cache issues from cascading into outages, while ensuring you do not spin in unbounded retry loops that look like abuse to APIM.
In production, security is less about algorithms and more about the behaviours your system exhibits under pressure. The first behaviour to pin down is transport trust. While HTTPS with server authentication is table stakes, mutual TLS (mTLS) gives you a second, independent proof that the caller is who it says it is. With mTLS, your client presents a certificate issued by a trusted authority; APIM validates it before even reaching the authorisation layer. This closes off entire categories of token-abuse attacks because possession of a valid token is no longer sufficient — the caller must also present a valid client certificate. Rotate client certificates on a schedule and automate distribution using your platform’s secret store so the process is boring and frequent rather than dramatic and rare.
Your network posture should reflect the principle of smallest possible blast radius. Prefer a fixed, known egress path — whether that is NAT with a small pool of public IPs, a private link if supported, or a controlled gateway — so that APIM can apply inbound network-based controls. Lock down outbound rules from your integration hosts or containers so they can only reach APIM and essential dependencies. This reduces the chance that compromised workloads can exfiltrate tokens or data to arbitrary destinations. Pair this with egress logging that records destination, SNI, and byte counts; it is invaluable in incident reconstruction and in tuning anomaly detectors that look for unusual traffic patterns.
Security is not only a runtime property; it is a governance discipline. If your integration processes patient contact information or message content, you should complete and maintain a Data Protection Impact Assessment that describes the data flows, purposes, retention rules and sharing arrangements. The exercise is not paperwork for its own sake: it clarifies who is the controller and who is the processor for each data element, how consent and opt-out preferences are honoured, and what lawful basis applies to each message. Implement those conclusions as code — for example, retention TTLs in your message database and suppression logic that respects exclusion lists or demographics flags where appropriate.
Auditing must be designed, not bolted on. Capture an immutable trail for high-value actions: token acquisition events, message submission, status retrieval, template changes, and administrative operations. Include correlation IDs so you can follow a message from your UI through your integration layer into APIM and back. Store audit logs in a write-once or tamper-evident store, and surface them in a dashboard that operational teams can query without developer intervention. When an incident occurs, the difference between hours and minutes is often how quickly you can prove what did and did not happen.
Clinical safety is sometimes overlooked in messaging systems because they seem purely administrative. In practice, message timing, content and delivery reliability can have patient safety implications. Treat content templates as configuration with change control and peer review. Test fallbacks so that, for example, failure to deliver via the NHS App results in a timely alternative rather than silent loss. Include negative test cases that simulate consent withdrawal and deceased flags so your system demonstrates correct suppression behaviour. In governance terms, bring your clinical safety officer into the design when you define routing policies and failure modes; these are not just engineering decisions but safety decisions.
A final word on people and process. Even the best cryptography fails when secrets are mishandled. Limit who can view client credentials and private keys; prefer just-in-time, short-lived access via break-glass procedures over standing privileges. Run regular secrets-hygiene scans across repositories to catch accidental commits. Drill your incident response: practice rotating keys under time pressure, revoking certificates, and invalidating tokens. When you can perform these manoeuvres calmly in an exercise, you will do them swiftly in a crisis. That confidence is a security control in its own right, and it is the kind your patients would choose if they could look behind the curtain.
By approaching NHS Notify integration through the combined lenses of APIM policy, OAuth2 hygiene, JWT discipline, and operational hardening, you construct a layered defence that is resilient to both mistakes and malice. The payoff is not only compliance but reliability at scale, predictable behaviour under stress, and a platform your clinicians and communications teams can trust for the messages that matter.
Is your team looking for help with NHS Notify integration? Click the button below.
Get in touch