MyBotBoxMyBotBox
Architecture

リクエストパイプライン

すべての 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) をキーとする行であり、エグゼキューターは実行全体を通じて userIdworkspaceId を引き回します。これにより、ワークフローは自身のテナント境界内のデータのみを読み書きできます。マルチテナンシーを参照してください。