FastAPI本番運用ハードニング完全ガイド:セキュリティ・性能・障害対応を実装で固める

FastAPI は開発速度が高く、PoC から本番まで一気に進めやすいフレームワークです。しかし、早く作れることと安全に運用できることは別問題です。実際の障害は、コードの正しさよりも運用の隙から発生します。

本記事では、FastAPI を本番で安心して運用するためのハードニング手順を、実装可能な形でまとめます。対象は「すでにAPIが動いているが、運用強度を上げたい」チームです。

1. 入口防御:TLS、ヘッダ、レート制限

TLS終端とForwardedヘッダ

ロードバランサ配下で動かす場合、X-Forwarded-ForX-Forwarded-Proto の扱いを明確にします。誤るとクライアントIPが取れず、監査も制限も機能しません。

1
2
3
4
5
from fastapi import FastAPI
from starlette.middleware.trustedhost import TrustedHostMiddleware

app = FastAPI()
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["api.example.com", "*.example.com"])

allowed_hosts をワイルドにしすぎると Host Header Injection の温床になります。

セキュリティヘッダ

最低限次を返します。

  • Strict-Transport-Security
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Referrer-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 で統一的に実施します。

1
2
3
def authorize_user_resource(current_user, target_user_id: str):
    if not (current_user.is_admin or current_user.user_id == target_user_id):
        raise HTTPException(status_code=403, detail="forbidden")

3. 入出力の安全化:Pydanticだけでは不十分

Pydantic は型安全に強いですが、ビジネス制約は別で実装が必要です。

  • 文字列長上限
  • 許可文字セット
  • SQL/NoSQLインジェクションの危険文字
  • HTML/Markdown サニタイズ

特に検索APIやエクスポートAPIは、クエリ文字列が巨大化しやすく DoS の入口になります。max_length を必ず定義してください。

4. 性能ハードニング:ワーカ・DB・タイムアウト

Uvicorn/Gunicorn 構成

CPUコア数に応じて worker を決めます。目安は workers = 2 * core + 1 から開始し、実測で調整。

1
gunicorn app.main:app -k uvicorn.workers.UvicornWorker --workers 5 --bind 0.0.0.0:8000 --timeout 30

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 を必ず返します。

1
2
3
4
5
6
7
{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "unexpected error",
    "trace_id": "8f3d..."
  }
}

内部例外はそのまま返さず、ログ側に 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 単体の問題より、周辺設定差異が事故の原因になります。

リリース前チェックリスト:

  1. DB migration の後方互換性
  2. 依存ライブラリ脆弱性スキャン
  3. load test(代表3API)
  4. rollback 手順の実行確認
  5. 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 フローで担保する必要があります。推奨するジョブは次の通りです。

  1. 依存脆弱性スキャン(pip-audit / osv-scanner)
  2. SAST(bandit など)
  3. 型チェック(mypy)
  4. 負荷テストのスモーク(k6)
  5. OpenAPI 差分チェック(破壊的変更検出)

特に OpenAPI 差分チェックは有効です。意図しないレスポンス変更を早期に検知でき、フロントエンド障害を防げます。

11. バックアップと復旧を設計に含める

API 運用は「壊れない」ではなく「壊れても戻せる」が現実的です。最低限次を決めておきます。

  • DB バックアップ頻度(例: 15分ごと増分、日次フル)
  • 復旧目標(RTO/RPO)
  • 復旧手順の担当と実行順

復旧訓練をしていないバックアップは、存在しないのと同じです。四半期に一度は検証環境でリストア演習を行ってください。

12. 監査対応を見据えたログ保全

B2B API では監査要件が後から増えることが多いです。最初から次を満たす設計にしておくと後で困りません。

  • 監査ログとアプリログを分離
  • 重要操作(権限変更、削除、課金操作)の証跡保存
  • ログ保持期間の明確化(例: 180日)
  • 改ざん検知(WORM ストレージや署名)

「誰が、いつ、何をしたか」を追えることは、障害解析だけでなく法務リスク低減にも直結します。

最終まとめ

FastAPI の本番運用は、フレームワーク知識だけでは足りません。セキュリティ、性能、可観測性、復旧性を一体で設計することが重要です。チェックリスト化し、CI と運用手順へ落とし込むことで、安定した開発速度を維持できます。