リクエストパイプライン
すべての API リクエストが通過する、共通の認証・認可・レート制限ゲート。
すべての API リクエストは、ビジネスロジックが実行される前に同じ関門を通過します。これらのゲートはルートごとのコードではなく、単一の再利用可能な実装であるため、サービス全体にわたってセキュリティの動作が一貫しています。
ゲートの概要
ミドルウェア — セッションの存在を確認し、コンテンツセキュリティポリシーを適用し、メンテナンスモード中はリクエストを短絡させます。
認証 — Firebase セッション Cookie(またはサービス間通信用の内部 JWT)を検証し、データベースユーザーと照合します。失敗時は
401 を返します。
認可(RBAC) — ワークスペースを スコープとして、対象エンティティに対する呼び出し元の最上位権限(read < write < admin)を解決します。失敗時は
403 を返します。
レート制限 — 負荷の高いルートおよびパブリックルートに対するスライディングウィンドウカウンター。失敗時は 429 を返します。
ハンドラー — バリデーション済みのリクエストが Zod でチェックされたビジネスロジックに到達します。
リクエストフロー
sequenceDiagram
autonumber
actor C as Caller
participant E as Edge
participant G as API Guards
participant A as Auth
participant Z as RBAC
participant L as Rate Limiter
participant H as Handler
C->>E: HTTPS request
E->>G: Route handler
G->>A: requireApiAuth()
A-->>G: session or null
alt not authenticated
G-->>C: 401 Unauthorized
else authenticated
G->>Z: requireWorkspaceAccess(min)
Z-->>G: permission or null
alt insufficient permission
G-->>C: 403 Forbidden
else authorized
G->>L: checkRateLimit(key)
alt limit exceeded
L-->>C: 429 Too Many Requests
else within limit
G->>H: validated request
H-->>C: 200 + data
end
end
endレート制限ストア
リミッターはデフォルトでプロセスローカルのインメモリウィンドウを使用します。Redis URL が設定されている場合は、全サーバーインスタンス間で共有される Memorystore バックのスライディングウィンドウ(アトミック Lua)に切り替わります。これにより、単一ユーザーがリクエストを複数のレプリカに分散させて制限を回避することを防ぎます。
Redis クライアントは遅延接続であり、リミッターはメモリへのフェイルオープンとなります — キャッシュが停止しても、起動がクラッシュしたり、リクエストが 500 エラーになることはありません。Redis が回復するまでの間、インスタンスごとの制限にフォールバックします。
テナント分離
認可は常にワークスペーススコープです。グラントは (userId, entityType, entityId) をキーとする行であり、エグゼキューターは実行全体を通じて userId と workspaceId を引き回します。これにより、ワークフローは自身のテナント境界内のデータのみを読み書きできます。マルチテナンシーを参照してください。