FastAPI認証・認可の本番設計:JWT運用、権限制御、監査ログまで含めた実装パターン
FastAPI は実装が速い反面、認証・認可を最小構成のまま本番に出してしまい、後からセキュリティ事故に発展するケースが少なくありません。特に「JWT を入れたから安全」という誤解は危険です。
本記事では、開発速度を落とさずに本番で耐える認証基盤を作るための設計を、コード例と運用手順込みで解説します。
1. 認証と認可を分離して設計する
最初に押さえるべきは責務分離です。
- 認証(Authentication): 誰かを確認する
- 認可(Authorization): 何をしてよいか判定する
この2つを混ぜると、実装も監査も破綻します。FastAPI では dependency を分け、get_current_user と require_permission を独立させるのが基本です。
2. JWT は「短命 + リフレッシュ + 失効管理」で使う
アクセストークンを長寿命にすると、漏えい時の被害が大きくなります。実運用では以下が標準です。
- Access Token: 5〜15分
- Refresh Token: 7〜30日
- Refresh Token は DB 保存し、ローテーション時に旧トークンを失効
sub だけでなく、jti(トークンID)や scope を持たせると管理しやすくなります。
|
|
3. 鍵管理とローテーション
秘密鍵を .env に固定して数年運用するのは典型的な事故パターンです。最低限、次を実施します。
- KMS/Vault など外部シークレット管理を利用
kidをヘッダに持たせ、複数鍵を並行運用- 鍵ローテーション手順を runbook 化
ローテーションの要点:
- 新鍵を追加(検証側は新旧どちらも受理)
- 発行側を新鍵へ切替
- 旧鍵の有効期限を過ぎたら削除
この手順にすると、無停止で切替できます。
4. FastAPI Dependencyで認可を明示化
ロジック中で if user.role == "admin" を乱立させると、抜け漏れが起こります。権限チェックは dependency 化し、ルート定義に明示します。
|
|
ルート単位で要件が見えるため、レビュー効率と監査性が上がります。
5. RBAC/ABAC の使い分け
小規模なら RBAC(role-based)で十分ですが、顧客単位データや組織階層があると ABAC(属性ベース)を併用した方が安全です。
- RBAC:
admin,editor,viewer - ABAC:
tenant_id,resource_owner_id,department
実務では「ロールで粗く許可し、属性で絞る」が扱いやすいです。
6. マルチテナントで必須の防御
マルチテナント API では、ID 推測よりもテナント境界漏れが主要リスクです。対策は次の通りです。
- すべての DB クエリに
tenant_id条件を必須化 - 管理者 API でも境界を明示的に超える操作だけ許可
- 監査ログに
tenant_id,actor_id,resource_idを残す
SQLAlchemy でも repository 層で共通フィルタを強制すると漏れを減らせます。
7. 監査ログを設計段階で入れる
認証系は障害後に「誰が何をしたか」が必要になります。後付けだと間に合いません。最低限、次を記録します。
- ログイン成功/失敗(IP, user-agent, reason)
- 権限エラー(403)
- 重要操作(削除、権限変更、請求情報更新)
- トークン失効・再発行
フォーマットは JSON 構造化に統一し、SIEM や OpenSearch に流せる形にしておくと分析が速いです。
8. レート制限とブルートフォース対策
パスワード認証がある場合、レート制限なしは危険です。slowapi などを使い、ログイン系エンドポイントに制限を入れます。
|
|
さらに次を組み合わせると強化できます。
- 失敗回数に応じた遅延(progressive delay)
- CAPTCHA(必要時のみ)
- 異常IP/ASN の遮断
9. よくある実装ミス
ミスA: 署名検証はしているが aud/iss 未検証
結果:
- 他システム向けトークンを誤受理
対処:
- issuer/audience を厳格検証
- 想定外クレームは拒否
ミスB: refresh token の使い回しを検知しない
結果:
- 漏えい時に長期間乗っ取られる
対処:
- ローテーション時に旧トークン失効
- 再利用検知時はセッション全失効
ミスC: 認可チェックが一部エンドポイントで抜ける
結果:
- 水平権限昇格
対処:
- dependency ベースで強制
- 重要ルートにセキュリティテスト追加
10. テスト戦略(必須)
認証はユニットテストだけでなく、統合テストで権限境界を確認します。
- 有効トークン/期限切れ/改ざんトークン
- role ごとのアクセス可否
- tenant 越境アクセス拒否
- refresh token 再利用検知
pytest では fixture で role 別トークンを用意し、回帰を防ぎます。
11. 障害時 runbook(最低限)
インシデント時に迷わないよう、次を文書化しておきます。
- 鍵漏えい疑い時の全トークン失効手順
- 認証基盤障害時のフェイル動作(許可しすぎを防ぐ)
- 監査ログの検索手順
- 関係者通知テンプレート
特に「認証サーバーが落ちたとき、API をどうするか」は事前に決めておく必要があります。
12. 導入チェックリスト
- access token は短寿命(<=15分)
- refresh token は DB 管理 + ローテーション
- 鍵ローテーション手順がある
- ルート単位で認可 dependency が明示されている
- tenant 境界を DB レイヤーで強制している
- 監査ログ(認証/認可/重要操作)を構造化保存
- レート制限と異常検知がある
- 権限境界の統合テストがある
FastAPI の認証・認可は、フレームワーク機能だけでは守り切れません。トークン寿命設計、鍵運用、境界強制、監査、テスト、runbookまで含めて初めて、本番で信頼できるセキュリティ基盤になります。