FastAPI本番運用ハードニング完全ガイド:セキュリティ・性能・障害対応を実装で固める
FastAPI は開発速度が高く、PoC から本番まで一気に進めやすいフレームワークです。しかし、早く作れることと安全に運用できることは別問題です。実際の障害は、コードの正しさよりも運用の隙から発生します。
本記事では、FastAPI を本番で安心して運用するためのハードニング手順を、実装可能な形でまとめます。対象は「すでにAPIが動いているが、運用強度を上げたい」チームです。
1. 入口防御:TLS、ヘッダ、レート制限
TLS終端とForwardedヘッダ
ロードバランサ配下で動かす場合、X-Forwarded-For と X-Forwarded-Proto の扱いを明確にします。誤るとクライアントIPが取れず、監査も制限も機能しません。
|
|
allowed_hosts をワイルドにしすぎると Host Header Injection の温床になります。
セキュリティヘッダ
最低限次を返します。
Strict-Transport-SecurityX-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy
APIでも無関係ではありません。管理画面やドキュメントUIを守る意味があります。
レート制限
ブルートフォースと突発負荷に備え、IPまたはAPIキー単位でレート制限を設定します。
- 認証系: 5 req/min
- 通常API: 60 req/min
- 高負荷検索: 20 req/min
Redis バックエンド方式にして、アプリ再起動でカウンタが失われないようにします。
2. 認証・認可の落とし穴を塞ぐ
JWT検証の必須項目
exp だけ見て通す実装は危険です。少なくとも次を検証します。
iss(発行者)aud(想定利用先)nbf(有効開始)kidに基づく鍵ローテーション
認可は「エンドポイント単位」ではなく「リソース単位」
/users/{id} のアクセス時に、path パラメータの id とトークンの主体を照合しない事故は頻発します。FastAPI の dependency で統一的に実施します。
|
|
3. 入出力の安全化:Pydanticだけでは不十分
Pydantic は型安全に強いですが、ビジネス制約は別で実装が必要です。
- 文字列長上限
- 許可文字セット
- SQL/NoSQLインジェクションの危険文字
- HTML/Markdown サニタイズ
特に検索APIやエクスポートAPIは、クエリ文字列が巨大化しやすく DoS の入口になります。max_length を必ず定義してください。
4. 性能ハードニング:ワーカ・DB・タイムアウト
Uvicorn/Gunicorn 構成
CPUコア数に応じて worker を決めます。目安は workers = 2 * core + 1 から開始し、実測で調整。
|
|
DB接続プール
asyncpg や SQLAlchemy async engine のプール上限を設定しないと、ピーク時に接続飽和します。
- min: 5
- max: 30(DB性能と相談)
- pool timeout: 5s
タイムアウト戦略
上流・下流の timeout を揃えないと、雪崩障害が発生します。
- 外部API呼び出し: connect 1s / read 3s
- DBクエリ: statement timeout 2s(重処理は別キュー)
- API全体: 10s で fail fast
5. 例外設計と障害時の挙動
本番障害では「500が出ること」より「500の意味が不明」なことが問題です。エラーレスポンス形式を固定し、trace_id を必ず返します。
|
|
内部例外はそのまま返さず、ログ側に stack trace を記録。ユーザーには安全な文言のみ返却します。
6. 可観測性:ログ・メトリクス・トレース
構造化ログ
JSON ログを標準化し、次を必須項目にします。
- timestamp
- level
- service
- trace_id
- user_id(可能なら)
- endpoint
- latency_ms
メトリクス
最低限:
- RPS
- エラー率(4xx/5xx)
- P50/P95/P99 latency
- DB遅延
- 外部API失敗率
トレース
OpenTelemetry で endpoint → service → DB をつなぐと、障害切り分けが劇的に速くなります。
7. デプロイ戦略:壊さずに出す
推奨は Blue/Green か Canary。FastAPI 単体の問題より、周辺設定差異が事故の原因になります。
リリース前チェックリスト:
- DB migration の後方互換性
- 依存ライブラリ脆弱性スキャン
- load test(代表3API)
- rollback 手順の実行確認
- feature flag で段階有効化
8. 運用で効くインシデント訓練
月1回、次の擬似障害を実施すると運用強度が上がります。
- DB遅延 3秒化
- 外部API 30% 失敗
- メモリリーク発生
- JWT鍵ローテーション失敗
重要なのは、復旧時間だけでなく「誰が何を見て判断したか」を記録することです。Runbook の更新まで含めて初めて訓練が完結します。
9. すぐ使える最小ハードニングチェック
- Host ヘッダ制限
- JWT
iss/aud/exp/nbf検証 - 全エンドポイントに認可 dependency
- 外部API timeout/retry/circuit breaker
- JSON 構造化ログ + trace_id
- P95 latency 監視とアラート
- rollback 手順が5分で実行可能
この 7 項目が揃うだけで、障害時の被害規模は大きく下がります。
まとめ
FastAPI は高速開発の武器ですが、本番運用では「早く作る」より「安全に壊れる」設計が重要です。入口防御、認証認可、性能制御、観測性、リリース運用をセットで整備すれば、チームは安心して機能開発に集中できます。
もし何から始めるか迷うなら、まずは trace_id 付きの構造化ログと timeout 統一から着手してください。最小の投資で、運用の見通しが一気に良くなります。
10. セキュアな開発フローを維持するためのCI設定
本番ハードニングはコードだけでなく、CI フローで担保する必要があります。推奨するジョブは次の通りです。
- 依存脆弱性スキャン(pip-audit / osv-scanner)
- SAST(bandit など)
- 型チェック(mypy)
- 負荷テストのスモーク(k6)
- OpenAPI 差分チェック(破壊的変更検出)
特に OpenAPI 差分チェックは有効です。意図しないレスポンス変更を早期に検知でき、フロントエンド障害を防げます。
11. バックアップと復旧を設計に含める
API 運用は「壊れない」ではなく「壊れても戻せる」が現実的です。最低限次を決めておきます。
- DB バックアップ頻度(例: 15分ごと増分、日次フル)
- 復旧目標(RTO/RPO)
- 復旧手順の担当と実行順
復旧訓練をしていないバックアップは、存在しないのと同じです。四半期に一度は検証環境でリストア演習を行ってください。
12. 監査対応を見据えたログ保全
B2B API では監査要件が後から増えることが多いです。最初から次を満たす設計にしておくと後で困りません。
- 監査ログとアプリログを分離
- 重要操作(権限変更、削除、課金操作)の証跡保存
- ログ保持期間の明確化(例: 180日)
- 改ざん検知(WORM ストレージや署名)
「誰が、いつ、何をしたか」を追えることは、障害解析だけでなく法務リスク低減にも直結します。
最終まとめ
FastAPI の本番運用は、フレームワーク知識だけでは足りません。セキュリティ、性能、可観測性、復旧性を一体で設計することが重要です。チェックリスト化し、CI と運用手順へ落とし込むことで、安定した開発速度を維持できます。