こんにちは、個人開発をしているようへいです!
Convex を本格的に活用する上で、「セキュリティをどう設計するか」は常に重要なテーマでした。これまで 3 つのアプリケーションを開発する中で、試行錯誤を重ねた結果、ようやく自信を持っておすすめできる高セキュリティなアーキテクチャが完成しましたので、その内容を共有します。
🧭 なぜ3層構造が必要なのか?
現代のSaaS・Webサービスは、「認証」「UI/アプリ」「データ処理」を明確に分けることで、安全性・拡張性・保守性を最大化します:
層 役割 担当
Auth0 認証・JWT発行 誰なのかを確認する
Next.js (Vercel) UI・SSR・セッション管理 どう使うかを制御する
Convex データ処理・API・認可 何ができるかを決定する
👉 この3層が連携することで、「本人確認 → 体験提供 → データ操作」という安全な流れが成立します。
🔐 JWT が不可欠な理由
Convex は「ステートレス」=リクエストごとに“誰が呼んでいるか”の証明が必要です。
その証明書として使われるのが、Auth0 が発行する JWT(JSON Web Token) です。
JWT の役割 内容
🪪 認証 ユーザーが誰であるか(sub, email)を伝える
✅ 署名検証 本物のAuth0が発行したことを確認する
🎯 Audience 自分(Convex用API)向けであることを確認する
🕐 期限管理 有効期限内であることを確認する
👉 Convex はセッションを記憶しないため、毎回JWTを送ることで「私は本物です」と自己証明する仕組みです。
🧱 認証フロー全体図
1️⃣ Auth0:JWT発行の設計
✅ 設定ポイント
Application Type: Regular Web Application
Callback URL:
Logout URL:
Allowed Web Origins:
Signing Algorithm: RS256(必須)
✅ API の作成
Identifier(Audience):
Access Token Lifetime: 300〜900秒(5〜15分)
2️⃣ Next.js (Vercel):セッションとトークン管理
📁 ディレクトリ構成
src/
└─ app/
└─ api/
└─ auth/
└─ [...auth0]/route.ts ← Auth0エンドポイント
└─ middleware.ts ← 認証ルーティング
✅ 認証エンドポイント(App Router)
✅ SSRで安全なセッション確認
✅ Convex呼び出し時に JWT を付与
3️⃣ Convex:JWT 検証とアクセス制御
✅ JWT 検証は auth.getUserIdentity() で自動化
🔒 Convex は以下を自動で検証します:
✅ 署名(RS256)
✅ iss(AUTH0_ISSUER_BASE_URL と一致)
✅ aud(AUTH0_CLIENT_ID または Audience と一致)
✅ exp(有効期限)
🔐 セキュリティのベストプラクティス
項目 | 推奨設定 |
---|---|
⏱️ JWT 有効期限 | 5〜15分 |
🔄 Refresh Token | 有効化して自動更新 |
🍪 HttpOnly Cookie | XSS対策(JSからトークン非参照) |
🔐 Convex | auth.getUserIdentity() を必ず使用 |
🎯 Audience | Convex 専用のものを発行(他APIのトークン拒否) |
🌐 HTTPS | 必須(HTTP通信禁止) |
📁 環境変数設定 | ✅ AUTH0_ISSUER_BASE_URL + AUTH0_CLIENT_ID ベース |
🧩 Next.js (Vercel)
🔐 Convex 側(JWKS ではなく Issuer + Client ID)
変数名 | 内容 | 例 |
---|---|---|
AUTH0_ISSUER_BASE_URL | Auth0 ドメイン | https://dev-xxxxxx.us.auth0.com |
AUTH0_CLIENT_ID | クライアントID(aud 検証用) | abc123 |
AUTH0_AUDIENCE | API Audience | https://api.yourapp.com |
✅ 運用時のチェックリスト
チェック項目 | 状態 |
---|---|
✅ Auth0 API で Audience を作成し、5〜15分に設定 | ✅ |
✅ Next.js は HttpOnly Cookie + SSR でセッション管理 | ✅ |
✅ Convex は auth.getUserIdentity() による検証実装済み | ✅ |
✅ HTTPS 有効・Issuer / Audience の検証が通る | ✅ |
✅ 環境変数が dev/prod で分離・安全管理されている | ✅ |
🧠 最後に:全体の設計思想(再確認) | - |
レイヤー | 役割 | JWTの役割 |
---|---|---|
Auth0 | 誰かを確認(認証) | 正しい署名付きトークンを発行する |
Next.js | UI/SSR/セッション管理 | トークンを安全に保管・APIへ転送 |
Convex | データアクセス制御 | トークンの署名・発行元・対象を検証して許可/拒否 |
🔑 ポイントまとめ:
Convex は 状態を持たない → JWT による「毎回の本人証明」が必要
JWT は「署名付きの入館証」 → 偽造・なりすまし・他アプリのトークンを防げる
AUTH0_ISSUER_BASE_URL + AUTH0_CLIENT_ID によって、署名・発行者・対象すべての検証が可能
✅ 一言まとめ
Auth0 が「誰か」を保証し、Next.js が「どのように使うか」を制御し、Convex が「何ができるか」を判断する。
それらを結びつける共通言語が JWT であり、AUTH0_ISSUER_BASE_URL + AUTH0_CLIENT_ID の組み合わせでこそ、その“身分証”は本物として安全に検証できる。
あなたの個人開発にお役立ちできれば幸いです!
ではまた!