2023年の遅い時期の木曜日の午後、あるクライアントから電話がありました。フィンテックからヘルステックへのピボットで、彼らはコンプライアンス担当者を雇ったばかり。その人物が彼らのNext.jsコードベースを見てから、3ページにわたる問題リストを手渡しました。「AWSに置くだけで十分だと思っていました」と創業者は言いました。彼は本気でそう信じていました。正直なところ、彼の前にも同じ言葉を6つの異なるチームから聞いていました。
HIPAAコンプライアンスは、みんなが表面的には理解していると思っているエリアの一つです。BAAに署名して、準拠したクラウドプロバイダーを選べば完了。でも、HIPAAセキュリティ規則はあなたのホスティングプロバイダーのマーケティングページを気にしません。アプリケーションが保護された健康情報(PHI)をどのように処理、保存、送信、および監査するかを気にしています。Next.jsはフレームワークとして、デフォルトではHIPAA準拠でもなければ非準拠でもありません。その上に構築するものがすべてです。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.
2026年に実際に重要なことを、実際に構築したアーキテクチャと、実際にチームが犯しているミスに基づいて説明します。
---
「HIPAA準拠Next.js」が実際に意味すること
インフラストラクチャコンプライアンスとアプリケーションコンプライアンスを混同する人が多いです。この二つは同じではありません。
クラウドプロバイダー(AWS、GCP、Azure — どれでもいいですが)はあなたとビジネスアソシエイト契約を結ぶことができます。これは、HIPAAルールに従ってインフラ上でPHIを保護するという法的文書です。AWSにはHIPAA対応サービスのリストがあり、ブックマークして持っておく価値があります。ただし、AWSとのBAA契約があっても、あなたのNext.jsアプリがコンプライアンスに準拠しているわけではありません。全然です。HIPAA-eligible services listthat's worth bookmarking. But a BAA from AWS doesn't mean your Next.js app is compliant. Not even close.
アプリケーション層はあなたの責任です。常にそうです。フレームワークは単なる乗り物に過ぎません。yourresponsibility. Always. The framework is just a vehicle.
ここが問題です。Next.js 14以上(そして2026年まで、App Routerは完全に成熟しています)はサーバーコンポーネント、サーバーアクション、ミドルウェア、そしてエッジ機能を提供します。それぞれに異なるPHI処理の意味合いがあります。患者データベースをクエリしてクライアントコンポーネントにデータを渡すサーバーコンポーネント — そのデータはどこに存在しますか?どのくらいの期間?ブラウザキャッシュに含まれていないでしょうか?これらは仮定の話ではありません。
---
PHIサーフェスエリアの問題
コードを1行書く前に、ヘルステック関連のすべてのクライアントに1つのエクササイズを実施させます。PHIがアプリケーションに触れる可能性のあるすべての場所をマップすることです。触れるべき場所ではなく、触れる可能性のある場所です。shouldtouch it. Where itcould.
それには以下が含まれます:
- URLパラメータ(クエリ文字列に患者IDが含まれているのを見たことがあります — やめてください)
- ブラウザのlocalStorageとsessionStorage
localStorageandsessionStorage - クライアントサイドのステート管理(Zustand stores、Redux、React context など)
- Next.js のフェッチキャッシュと Data Cache レイヤー
- 開発中の console.log の出力がうっかり本番環境に混入すること
console.logduring development that sneaks into production - Sentry のようなエラートラッキングツール(詳しくはすぐ後で)
- GA4、Segment、Amplitude といった分析パイプライン
最後の2つは、他のほぼすべてのことよりも多くのチームを悩ませます。2024年初頭、Seahawk はテレヘルス企業のクライアントがいて、エラーモニタリングのために Sentry を設定していました。標準的な対応です。ただし、そのエラーバウンダリーがクラッシュ時に props オブジェクト全体をキャプチャしていたのです。それには予約の詳細とユーザーの健康フラグが含まれていました。Sentry は BAA の対象外でした。これは起きるべくして起きた侵害です。
エラートラッキングのサニタイズ
PHI 関連のコードで Sentry を使用している場合は、beforeSend フックを使用して、ブラウザーを離れる前に機密フィールドをスクラブします。終わり。次のようなものは必須です: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 には HIPAA コンプライアンスパスがあります。BAA に署名します。ただし、それでも彼らに送信するデータを設定する必要があります。BAA は自動的にペイロードをサニタイズしません。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.
認証とセッション管理
認証とセッション管理
ここが最も近道を見かける箇所です。チームは NextAuth.js(現在の Auth.js)に手を出し、プロバイダーを接続して終わりにします。Auth.js は堅牢なライブラリです。しかし、デフォルト設定は HIPAA のデフォルトではありません。
具体的にいくつか挙げます:
- セッショントークンのストレージ — Auth.js はデフォルトでクッキーベースのセッションを使いますが、これは問題ありませんが、httpOnly、secure、sameSite: 'strict' を明示的に設定する必要があります。想定に任せてはいけません。— Auth.js defaults to a cookie-based session, which is fine, but you need
httpOnly,secure, andsameSite: 'strict'explicitly set. Don't assume. - セッションの有効期限 — HIPAA の自動ログオフ基準(§164.312(a)(2)(iii))では、セッションが定義された非アクティブ期間後に終了することが必須です。具体的な時間は規定されていませんが、臨床アプリケーションでは 15 分が業界標準です。レイアウトに非アクティブタイマーを組み込んでください。通常、私はサーバーアクションを実行してセッションを無効化するカスタムフックとして実装しています。— 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 — HIPAA のテキストでは厳密には義務付けられていませんが、侵害後に MFA を実装しなかった理由を OCR 監査人に説明してみてください。otplib のような TOTP を使うか、MFA が組み込まれており BAA に署名する Auth0 や Clerk などの ID プロバイダーに頼ってください。— 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. - 認証イベントの監査ログ — すべてのログイン、失敗したログイン、ログアウトは、タイムスタンプとユーザー識別子とともにログされる必要があります。すべてです。— Every login, failed login, and logout needs to be logged with a timestamp and user identifier. Every single one.
Auth.js がこのユースケースに対して間違っていると言うつもりはありません — HIPAA プロジェクトで本番環境に導入したことがあります。しかし、コンプライアンス要件を意図的に上に層として重ねる必要があります。
---
転送中および保存中のデータ
転送はシンプルです。TLS 1.2以上、できればTLS 1.3を、あらゆる場所で使用してください。メインドメインだけではなく、APIルート、エッジ関数、あらゆるウェブフックです。Vercelを使っていればこれは対応済みです。EC2で自分でホストしているか、Nginxリバースプロキシーbehind でNext.jsをDockerコンテナで運用しているなら、自分で設定する必要があります。私はコードベースを見直したことがあります。そこでは「VPC内だから」という理由で、サービス間の内部通信がまだHTTPでした。それは受け入れられる立場ではありません。
保存中のデータはより難しいです。重要な具体例をいくつか挙げます。
- データベース暗号化 — 暗号化が有効になったAWS RDS(AWS KMS経由でAES-256を使用)。チェックボックスですが、実際にチェックして、ドキュメント化する必要があります。— 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.
- 非常にセンシティブなデータのフィールドレベル暗号化 — SSN、診断、投薬リストのようなものについては、@aws-sdk/client-kmsのようなライブラリを使用してキーをラップ/アンラップするアプリケーションレベルの暗号化の第2レイヤーを追加することがよくあります。オーバーヘッドは実在しますが、リスクも同じくらい実在します。— 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 — これは多くの人をつかまえます。App Routerはデフォルトでfetch応答をキャッシュします。サーバーコンポーネント内でfetch()を使用して患者データを取得しているなら、再検証を非常に意図的に管理していない限り、{ cache: 'no-store' }が必要です。PHIを含むキャッシュされた応答がサーバーのメモリまたはファイルシステムに存在することは問題です。— 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. - バックアップ — 暗号化済み。テスト済み。ドキュメント化済み。明らかですが、バックアップが存在するものの、一度も復元されたことがないシステムを監査したことがあります。— Encrypted. Tested. Documented. Obvious, but I've audited systems where the backups existed but had never been restored once.
---
監査ログ:誰も構築したくない部分
ここでハッキリ言っておきます。監査ログは、ヘルスケアテックアプリで構築する最もつまらなく、最も重要なものです。PHIへのあらゆるアクセスを記録する必要があります。書き込みだけではなく。読み取りも同様です。
HIPAA監査管理基準(§164.312(b))では、「ePHIを含む、または使用する情報システムにおける活動を記録および検査するハードウェア、ソフトウェア、および/または手続きメカニズム」が要求されます。実際のところ、患者データに誰がいつどこからアクセスしたかについて、追記専用ログが必要です。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.
このログを Next.js のミドルウェアレイヤーとして実装しています。App Router プロジェクトの場合、middleware.ts でインターセプトしてルートレベルのログを取り、PHI テーブルに接触するデータベースクエリ関数の周りに薄いサービスラッパーを追加します。ログレコードは別のデータベーステーブル(または不変性の保証が必要な場合は AWS CloudTrail などのサービス)に書き込まれます。PHI 自体と同じテーブルには決して書き込みません。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.
最小限の監査レコードは次のようになります:
user_id — 誰が— whoresource_type + resource_id — 何を+resource_id— whataction — read / write / delete— read / write / deleteip_address — どこから(ネットワークレイヤーでの匿名化で問題ありません)— where (anonymised at the network layer is fine)timestamp(UTC、常に UTC)(UTC, always UTC)request_id — アプリケーションログとの関連付け用— to correlate with your application logs
開発者が console.log(patientRecord) を使用して監査証跡と呼ぶことを許さないでください。このような事例を見たことがあります。それは監査証跡ではありません。console.log(patientRecord)and call it an audit trail. I've seen this. It's not.
---
インフラストラクチャスタックの選択
正直なところ、2026年にはHIPAA対応のNext.jsプロダクション環境で実際に推奨できるスタックは限られています。
Vercel + PlanetScale/Neon + Clerkが開発者体験重視のスタックです。VencelはBAA(エンタープライズプラン — 有料です)に署名します。PlanetScaleとNeonの両方にHIPAA対応のティアがあります。Clerkは認証を担当し、BAA署名します。これは出荷が速く、運用も合理的です。トレードオフはスケール時のコストと、インフラの制御が若干限定されることです。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(Next.jsアプリ向けECS/EKS)+ RDS Aurora + Cognitoがエンタープライズスタックです。運用のオーバーヘッドが大きくなります。制御はより広がります。AWSの責任共有モデルはよく文書化されており、BAA適用範囲は広いです。クライアントが病院システムや保険者の場合、あなたの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やRailwayについては、規制が厳しい用途には控えることをお勧めします。素晴らしいツールですが、HIPAA対応のストーリーは薄いです。— I'd steer clear for anything seriously regulated. They're great tools, but their HIPAA compliance story is thin.
ここで指摘したいこと:Vercelのエッジネットワークとエッジファンクションは、2026年初現在、VencelのBAA対象ではありません。エッジミドルウェアでPHIに触れるロジックを実行している場合、それはギャップです。代わりにサーバーレス関数(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.
---
サードパーティ統合:コンプライアンスが崩れる場所
PHIに触れるサードパーティはすべてBAA署名が必要です。当たり前に聞こえますが、実際にチームを困らせるリストがあります:
- カスタマーサポートツール(Intercom、Zendesk)— 患者が健康に関するメッセージを送信した場合、それはサポートプラットフォーム内のPHIです
- フォームツール(Typeform、Jotform)— 患者の問診フォームはPHIです
- メールプロバイダー(SendGrid、Postmark)— メール本文に健康情報が含まれている場合、BAAが必要です
- フィーチャーフラグツール(LaunchDarkly、Statsig)— 通常は問題ありませんが、フラグを評価するためにヘルスステータスを含むユーザー属性を渡している場合、それはPHIです
- CRM(HubSpot、Salesforce)— 多くのヘルステックチームが患者データをこれらに同期していますが、十分に検討していません
PostmarkはBAAに署名します。SendGrid(Twilio経由)も有料プランであれば署名します。SMS用のTwilioも同様です。LaunchDarklyにはBAAの経路があります。これらは珍しいオプションではありません — BAA手続きは通常、フォーム送信と数営業日です
BAAに署名しない、またはできないもの? PHIの近くにはどこにも統合しないでください。それだけです
---
FAQ
VercelにNext.jsアプリをデプロイするだけで、HIPAA対応になりますか?
いいえ。Vercelはエンタープライズプランでビジネスアソシエイト契約(BAA)に署名できます。つまり、Vercelが管理するインフラストラクチャに対して、一定のHIPAAの義務を負います。しかし、アプリケーションコード、データベース設計、ロギング、サードパーティ統合——これらはすべてVercelのBAAでカバーされません。コンプライアンスはスタックのすべてのレイヤーに分散しており、アプリケーションレイヤーはあなたの責任です。
Next.jsのAPIルートでクライアントに送信する前に、データを暗号化する必要がありますか?
TLSは転送中の暗号化を処理するため、HTTPレスポンスボディを手動で暗号化する必要はありません。必要なことは、その操作に必要最小限のPHIだけを返すようにすることです——たとえば、名前が必要なだけの場合、患者記録全体ではなく。「最小限必要」という原則はHIPAAに組み込まれており、初日からAPIレスポンス設計の方針となるべきです。
Next.jsのAppRouterの組み込みキャッシング機能はPHIに対して安全ですか?
デフォルトではありません。AppRouterのDataCacheとFullRouteCacheはPHIを含むレスポンスをキャッシュする可能性があり、これは問題です。患者データに触れるルートやフェッチ呼び出しについては、フェッチ呼び出しで{ cache: 'no-store' }を使用し、ルートセグメントにexport const dynamic = 'force-dynamic'を追加してください。Vercelのキャッシング設定ドキュメントをよく確認してください——難しいですが重要です。{ cache: 'no-store' }on fetch calls and addexport const dynamic = 'force-dynamic'to route segments. Review Vercel'scaching documentationcarefully — it's dense but important.
HIPAA監査証跡に最低限必要なロギングとは何ですか?
最小限:誰が何にアクセスしたのか、いつ、どこからか。つまり、ユーザーID、リソース識別子、アクション種別、タイムスタンプ、IPアドレスです。ログは改ざん証拠能力を持つ必要があります(追記のみで、アプリケーションコードで編集不可)し、保持する必要があります——ほとんどのコンプライアンスフレームワークは6年を推奨しており、これはHIPAAの文書保持要件に合致しています。
HIPAAアプリケーションでReact QueryやSWRを使用できますか?
はい、ただし慎重に扱う必要があります。どちらのライブラリもクライアント側でレスポンスをキャッシュします。つまり、PHIはブラウザのメモリに残る可能性があります。PHIを返すクエリについては、staleTime: 0とcacheTime: 0(React Query)またはdedupingInterval: 0(SWR)を設定してください。また、ログアウト時にクエリキャッシュを明示的にクリアしてください——コンポーネントのアンマウントに頼らないでください。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.
---
正直に言うと、HIPAA準拠は本当に正しく実装するのが難しいし、Next.jsであれどのフレームワークであれ、簡単にしてくれるものはありません。うまくやっている組織は、ローンチ前のチェックリストとしてではなく、初日からアーキテクチャの問題として扱っている。フレームワーク自体は問題ではない。ギャップは、ほぼ常にそのフレームワークの周辺で下された判断にあります。
PHIの表面積マッピングから始めてください。その他のすべてはそこから派生します。
