Un client m'a appelé un jeudi après-midi fin 2023 — une fintech reconvertie dans la santé-tech, ils venaient d'embaucher un consultant en conformité qui avait examiné leur codebase Next.js et remis une liste de trois pages de problèmes. « Nous pensions que le mettre sur AWS suffisait », a dit le fondateur. Il y croyait sincèrement. Et honnêtement ? J'avais entendu cette même phrase de probablement six équipes différentes avant la sienne.
La conformité HIPAA est l'un de ces domaines où tout le monde croit comprendre la surface — signer un BAA, choisir un fournisseur cloud conforme, c'est fait. Mais la Règle de sécurité HIPAA ne se soucie pas de la page marketing de votre fournisseur d'hébergement. Elle se soucie de la façon dont votre application gère, stocke, transmet et audite les informations de santé protégées (PHI). Next.js — en tant que framework — n'est ni conforme ni non conforme en standard. Ce que vous construisez par-dessus est tout.thinksthey understand the surface — sign a BAA, pick a compliant cloud provider, done. But theHIPAA Security Ruledoesn't care about your hosting provider's marketing page. It cares about how your application handles, stores, transmits, and audits Protected Health Information (PHI). Next.js — as a framework — is neither compliant nor non-compliant out of the box. What you build on top of it is everything.
Alors laissez-moi vous parcourir ce qui compte vraiment en 2026, basé sur les architectures réelles que j'ai construites et les véritables erreurs que j'ai vues des équipes faire.
---
Ce que « Next.js conforme à la HIPAA » signifie vraiment
Les gens confondent la conformité des infrastructures avec la conformité des applications. Ce ne sont pas la même chose.
Votre fournisseur cloud (AWS, GCP, Azure — choisissez-en un) peut signer un Business Associate Agreement avec vous. C'est un document légal établissant qu'ils protégeront les PHI sur leur infrastructure selon les règles HIPAA. AWS dispose d'une liste de services éligibles HIPAA qui mérite d'être mise en signet. Mais un BAA d'AWS ne signifie pas que votre app Next.js est conforme. Loin de là.HIPAA-eligible services listthat's worth bookmarking. But a BAA from AWS doesn't mean your Next.js app is compliant. Not even close.
La couche applicative est votre responsabilité. Toujours. Le framework n'est qu'un véhicule.yourresponsibility. Always. The framework is just a vehicle.
Voilà le truc — Next.js 14+ (et jusqu'en 2026, l'App Router est entièrement mature) vous donne les server components, les server actions, le middleware, et les edge functions. Chacun d'entre eux a des implications différentes pour le traitement des PHI. Un server component qui interroge une base de données patients et passe des données à un client component — où vivent ces données? Combien de temps? Est-ce qu'elles finissent dans un cache navigateur? Ce ne sont pas des préoccupations hypothétiques.
---
Le problème de la surface d'exposition des PHI
Avant d'écrire une ligne de code, je fais faire un exercice à chaque client en health-tech : cartographier chaque endroit où les PHI pourraient toucher l'application. Pas où ils devraient la toucher. Où ils pourraient.shouldtouch it. Where itcould.
Cela inclut :
- Les paramètres URL (j'ai vu des IDs patients dans les query strings — ne faites pas ça)
- Le localStorage et sessionStorage du navigateur
localStorageandsessionStorage - Gestion d'état côté client (stores Zustand, Redux, React context)
- Cache de fetch Next.js et la couche Data Cache
- Output de logs depuis console.log en développement qui se glisse en production
console.logduring development that sneaks into production - Outils de suivi d'erreurs comme Sentry (plus de détails à ce sujet dans un instant)
- Pipelines d'analytics — GA4, Segment, Amplitude
Les deux derniers causent des problèmes à plus d'équipes que presque n'importe quoi d'autre. Début 2024, Seahawk avait un client en télémédecine qui avait configuré Sentry pour la surveillance d'erreurs. Un move standard. Sauf que leurs error boundaries capturaient l'intégralité de l'objet props au crash — ce qui incluait les détails des rendez-vous et les indicateurs de santé des utilisateurs. Sentry n'était pas couverte par leur BAA. C'est une violation qui n'attendait que de se produire.
Nettoyer votre suivi d'erreurs
Si vous utilisez Sentry avec du code adjacent à PHI, utilisez le hook beforeSend pour nettoyer les champs sensibles avant qu'ils quittent le navigateur. Sans exception. Quelque chose comme ça est non-négociable :beforeSendhook to scrub sensitive fields before they leave the browser. Full stop. Something like this is non-negotiable:
`` beforeSend(event) { if (event.user) { delete event.user.email; delete event.user.ip_address; } return event; } ``beforeSend(event) { if (event.user) { delete event.user.email; delete event.user.ip_address; } return event; }``
Sentry dispose d'un chemin de conformité HIPAA — ils signeront un BAA — mais vous devez toujours configurer les données que vous leur envoyez. Le BAA ne nettoie pas automatiquement vos payloads.HIPAA compliance path— they'll sign a BAA — but you still need to configure what data you send them. The BAA doesn't sanitise your payloads automatically.
---
Authentification et gestion des sessions
C'est ici que je vois le plus de raccourcis. Les équipes se tournent vers NextAuth.js (maintenant Auth.js), connectent un fournisseur et considèrent que c'est fait. Auth.js est une bonne bibliothèque. Mais les paramètres par défaut ne sont pas des paramètres par défaut conformes à la HIPAA.
Quelques points spécifiques :
- Stockage du jeton de session — Auth.js utilise par défaut une session basée sur un cookie, ce qui convient, mais vous devez définir explicitement httpOnly, secure et sameSite: 'strict'. Ne l'assumez pas.— Auth.js defaults to a cookie-based session, which is fine, but you need
httpOnly,secure, andsameSite: 'strict'explicitly set. Don't assume. - Expiration de la session — La norme Déconnexion automatique de la HIPAA (§164.312(a)(2)(iii)) exige que les sessions se terminent après une période d'inactivité définie. Le nombre n'est pas prescrit, mais 15 minutes est la norme de l'industrie pour les applications cliniques. Mettez en place un minuteur d'inactivité dans votre layout. Je construis généralement cela comme un hook personnalisé qui déclenche une action serveur pour invalider la session.— HIPAA's Automatic Logoff standard (§164.312(a)(2)(iii)) requires that sessions terminate after a defined period of inactivity. The number isn't prescribed, but 15 minutes is the industry standard for clinical applications. Wire up an inactivity timer in your layout. I usually build this as a custom hook that fires a server action to invalidate the session.
- MFA — Non strictement mandatée par le texte de la HIPAA, mais essayez d'expliquer à un auditeur de l'OCR pourquoi vous ne l'avez pas implémentée après une violation. Utilisez TOTP via quelque chose comme otplib ou appuyez-vous sur un fournisseur d'identité comme Auth0 ou Clerk qui a MFA intégré et signera un BAA.— Not strictly mandated by HIPAA's text, but try explaining to an OCR auditor why you didn't implement it after a breach. Use TOTP via something like
otplibor lean on an identity provider like Auth0 or Clerk that has MFA baked in and will sign a BAA. - Journalisation d'audit des événements d'authentification — Chaque connexion, échec de connexion et déconnexion doit être enregistré avec un horodatage et un identificateur utilisateur. Chaque seul.— Every login, failed login, and logout needs to be logged with a timestamp and user identifier. Every single one.
Je ne vais pas vous dire qu'Auth.js est mauvais pour ce cas d'usage — je l'ai déployé en production sur des projets HIPAA. Mais vous devez ajouter délibérément les exigences de conformité par-dessus.
---
Données en transit et au repos
Le transit est la partie facile. TLS 1.2 minimum, TLS 1.3 de préférence, partout. Pas seulement votre domaine principal — vos routes API, vos fonctions edge, vos webhooks. Si vous êtes sur Vercel, c'est géré. Si vous auto-hébergez sur EC2 ou exécutez Next.js dans un conteneur Docker derrière un reverse proxy NGINX, vous devez le configurer vous-même. J'ai examiné des bases de code où les appels service-to-service internes se faisaient toujours en HTTP parce que « c'est à l'intérieur du VPC ». Ce n'est pas une position acceptable.
Au repos, c'est plus difficile. Quelques détails qui comptent :
- Chiffrement de la base de données — AWS RDS avec chiffrement activé (utilise AES-256 via AWS KMS). C'est une case à cocher, mais vous devez réellement la cocher et le documenter.— AWS RDS with encryption enabled (uses AES-256 via AWS KMS). This is a checkbox, but you need to actually check it and document it.
- Chiffrement au niveau des champs pour les données très sensibles — Pour des choses comme les numéros de sécurité sociale, les diagnostics ou les listes de médicaments, j'ajoute souvent une deuxième couche de chiffrement au niveau de l'application en utilisant une bibliothèque comme @aws-sdk/client-kms pour envelopper/dérouler les clés. Le surcoût est réel, mais le risque aussi.— For things like SSNs, diagnoses, or medication lists, I often add a second layer of encryption at the application level using a library like
@aws-sdk/client-kmsto wrap/unwrap keys. Overhead is real, but so is the risk. - Next.js Data Cache — Celui-ci en prend beaucoup au dépourvu. L'App Router met en cache les réponses fetch par défaut. Si vous récupérez les données patient dans un composant serveur avec fetch(), vous avez besoin de { cache: 'no-store' } sauf si vous gérez très délibérément la revalidation. Une réponse mise en cache contenant des PHI assis dans la mémoire ou le système de fichiers du serveur est un problème.— This one catches people out. The App Router caches fetch responses by default. If you're fetching patient data in a server component with
fetch(), you need{ cache: 'no-store' }unless you're very deliberately managing revalidation. A cached response containing PHI sitting in the server's memory or filesystem is a problem. - Sauvegardes — Chiffrées. Testées. Documentées. Évident, mais j'ai audité des systèmes où les sauvegardes existaient mais n'avaient jamais été restaurées une seule fois.— Encrypted. Tested. Documented. Obvious, but I've audited systems where the backups existed but had never been restored once.
---
Journalisation d'audit : la partie que personne ne veut construire
Voici quelque chose que je vais dire clairement — la journalisation d'audit est la chose la plus ennuyeuse et la plus importante que vous construirez dans une application de health-tech. Chaque accès à des PHI doit être enregistré. Pas seulement les écritures. Les lectures aussi.
La norme HIPAA Audit Controls (§164.312(b)) exige des « mécanismes matériels, logiciels et/ou procéduraux qui enregistrent et examinent l'activité dans les systèmes d'information contenant ou utilisant des ePHI ». Concrètement, cela signifie : vous devez conserver un journal immuable de qui a accédé à quelles données de patient, quand, et d'où.HIPAA Audit Controls standard(§164.312(b)) requires "hardware, software, and/or procedural mechanisms that record and examine activity in information systems that contain or use ePHI." What that means practically: you need an append-only log of who accessed what patient data, when, and from where.
Je construis cela comme une couche middleware dans Next.js. Pour les projets App Router, j'intercepte dans middleware.ts pour la journalisation au niveau des routes et j'ajoute un wrapper de service léger autour de toute fonction de requête de base de données qui touche aux tables PHI. Les enregistrements de journal sont écrits dans une table de base de données séparée (ou un service comme AWS CloudTrail si vous voulez des garanties d'immuabilité) — jamais dans la même table que les PHI eux-mêmes.middleware.tsfor route-level logging and add a thin service wrapper around any database query function that touches PHI tables. The log records get written to a separate database table (or a service like AWS CloudTrail if you want immutability guarantees) — never the same table as the PHI itself.
Un enregistrement d'audit minimal ressemble à ceci :
user_id — qui— whoresource_type + resource_id — quoi+resource_id— whataction — read / write / delete— read / write / deleteip_address — d'où (anonymisée au niveau du réseau est acceptable)— where (anonymised at the network layer is fine)timestamp (UTC, toujours UTC)(UTC, always UTC)request_id — pour corréler avec vos journaux d'application— to correlate with your application logs
Ne laissez pas les développeurs faire console.log(patientRecord) et appeler cela une piste d'audit. J'ai vu cela. Ce n'en est pas une.console.log(patientRecord)and call it an audit trail. I've seen this. It's not.
---
Choisir votre stack d'infrastructure
La réponse honnête est qu'en 2026, il y a une poignée de stacks que je recommanderais réellement pour une application Next.js HIPAA en production.
Vercel + PlanetScale/Neon + Clerk est le stack pour l'expérience développeur. Vercel signera un BAA (plan entreprise — oui, ça coûte de l'argent). PlanetScale et Neon ont tous les deux des niveaux éligibles HIPAA. Clerk gère l'authentification et signera un BAA. C'est rapide à déployer et raisonnable à gérer. Le compromis : le coût à grande échelle et une certaine perte de contrôle de l'infrastructure.is the developer-experience stack. Vercel will sign a BAA (enterprise plan — yes, it costs money). PlanetScale and Neon both have HIPAA-eligible tiers. Clerk handles auth and will sign a BAA. This is fast to ship and reasonable to operate. The tradeoff is cost at scale and some loss of infrastructure control.
AWS (ECS/EKS pour l'application Next.js) + RDS Aurora + Cognito est le stack entreprise. Plus de surcharge opérationnelle. Beaucoup plus de contrôle. Le modèle de responsabilité partagée d'AWS est bien documenté et la couverture BAA est large. Si votre client est un système hospitalier ou un assureur, il va probablement vous poser des questions détaillées sur votre architecture AWS.is the enterprise stack. More operational overhead. Much more control. AWS's shared responsibility model is well-documented and the BAA coverage is broad. If your client is a hospital system or an insurer, they're probably going to ask about your AWS architecture in detail.
Render ou Railway — je vous conseille de vous en écarter pour tout ce qui est sérieusement réglementé. Ce sont d'excellents outils, mais leur histoire de conformité HIPAA est mince.— I'd steer clear for anything seriously regulated. They're great tools, but their HIPAA compliance story is thin.
Une chose que je veux signaler : le Edge Network et les Edge Functions de Vercel ne sont pas couverts par HIPAA selon leur BAA au début 2026. Si vous exécutez une logique qui touche aux PHI dans un middleware edge, il y a une lacune. Exécutez plutôt cette logique dans des fonctions serverless (runtime Node.js).notHIPAA-covered under their BAA as of early 2026. If you're running logic that touches PHI in edge middleware, that's a gap. Run that logic in serverless functions (Node.js runtime) instead.
---
Intégrations tiers : où la conformité va mourir
Tous les tiers que vous intégrez et qui touchent aux PHI ont besoin d'un BAA. Ça semble évident. Voici la liste qui pose réellement problème aux équipes :
- Outils de support client (Intercom, Zendesk) — si un patient envoie un message à propos de sa santé, c'est des PHI dans votre plateforme de support
- Outils de formulaires (Typeform, Jotform) — les formulaires d'admission des patients sont des PHI
- Fournisseurs d'email (SendGrid, Postmark) — si le corps de l'email contient des informations de santé, un BAA est nécessaire
- Outils de feature flags (LaunchDarkly, Statsig) — généralement sans problème, mais si vous transmettez des attributs utilisateur incluant l'état de santé pour évaluer les flags, c'est des PHI
- CRM (HubSpot, Salesforce) — beaucoup d'équipes healthtech synchronisent les données des patients dans ces outils sans y réfléchir
Postmark signera un BAA. SendGrid (via Twilio) aussi, sur les forfaits payants. Twilio pour les SMS également. LaunchDarkly a un parcours BAA. Ce ne sont pas des options obscures — le processus BAA est généralement une soumission de formulaire et quelques jours ouvrables.
Ceux qui ne signeront pas ou ne peuvent pas signer un BAA? Ne les intégrez nulle part près des PHI. C'est aussi simple que ça.
---
FAQ
Déployer mon app Next.js sur Vercel la rend-elle conforme à la HIPAA?
Non. Vercel peut signer un accord d'associé commercial sur son plan entreprise, ce qui signifie qu'ils acceptent certaines obligations HIPAA pour l'infrastructure qu'ils contrôlent. Mais votre code applicatif, votre conception de base de données, vos logs, vos intégrations tierces — rien de tout cela n'est couvert par la BAA de Vercel. La conformité est partagée à travers chaque couche de la pile, et la couche applicative est votre responsabilité.
Dois-je chiffrer les données dans une route API Next.js avant de les envoyer au client ?
TLS gère le chiffrement en transit, donc vous n'avez pas besoin de chiffrer manuellement le corps de la réponse HTTP. Ce que vous devez faire, c'est vous assurer que vous ne renvoyez que les informations PHI minimales nécessaires pour l'opération — pas des dossiers patients complets quand vous n'avez besoin que d'un nom, par exemple. Le principe du « minimum nécessaire » est intégré à HIPAA et devrait façonner votre conception de réponse API dès le départ.
Le cache intégré de l'App Router de Next.js est-il sûr pour les PHI ?
Pas par défaut. Le Data Cache et le Full Route Cache dans l'App Router peuvent mettre en cache les réponses contenant des PHI, ce qui est problématique. Pour toute route ou appel fetch qui touche aux données patients, utilisez { cache: 'no-store' } sur les appels fetch et ajoutez export const dynamic = 'force-dynamic' aux segments de route. Lisez attentivement la documentation de caching de Vercel — elle est dense mais importante.{ cache: 'no-store' }on fetch calls and addexport const dynamic = 'force-dynamic'to route segments. Review Vercel'scaching documentationcarefully — it's dense but important.
Quel est le minimum de logs que j'ai besoin pour une piste d'audit HIPAA ?
Au minimum : qui a accédé à quoi, quand et d'où. C'est l'ID utilisateur, l'identifiant de ressource, le type d'action, l'horodatage et l'adresse IP. Les logs doivent être inviolables (en ajout seulement, non modifiables par le code applicatif) et conservés — la plupart des cadres de conformité suggèrent six ans, ce qui correspond à l'exigence de conservation de la documentation de HIPAA.
Puis-je utiliser React Query ou SWR pour la récupération de données dans une application HIPAA ?
Oui, mais avec prudence. Les deux bibliothèques mettent en cache les réponses côté client, ce qui signifie que les PHI peuvent rester dans la mémoire du navigateur. Définissez staleTime: 0 et cacheTime: 0 (React Query) ou dedupingInterval: 0 (SWR) pour les requêtes qui retournent des PHI. Videz également le cache des requêtes à la déconnexion de manière explicite — ne comptez pas sur le démontage des composants pour gérer cela.staleTime: 0andcacheTime: 0(React Query) ordedupingInterval: 0(SWR) for queries that return PHI. Also clear the query cache on logout explicitly — don't rely on component unmounting to handle this.
---
Je veux être honnête sur quelque chose : la conformité HIPAA est vraiment difficile à mettre en œuvre correctement, et aucun framework — Next.js ou autre — ne la rend facile. Les équipes que j'ai vues réussir sont celles qui la traitent comme un problème d'architecture dès le départ, pas comme une liste de contrôle à cocher avant le lancement. Le framework, c'est correct. Les lacunes se situent presque toujours dans les décisions prises autour de lui.
Commencez par la cartographie de la surface des PHI. Tout le reste en découle.
