MyBotBoxMyBotBox
Architecture

Pipeline de Solicitudes

Las puertas compartidas de autenticación, autorización y límite de tasa por las que pasa cada solicitud a la API.

Cada solicitud a la API atraviesa el mismo proceso antes de que se ejecute cualquier lógica de negocio. Estas puertas son implementaciones únicas y reutilizables — no código por ruta — por lo que la seguridad se comporta de forma consistente en toda la superficie.

Las puertas

Middleware — verifica la presencia de la sesión, aplica la Política de Seguridad de Contenido y cortocircuita durante el modo de mantenimiento.

Autenticación — verifica la cookie de sesión de Firebase (o un JWT interno para llamadas entre servicios) y reconcilia el usuario en la base de datos. Falla con 401.

Autorización (RBAC) — resuelve el permiso más alto del solicitante para la entidad objetivo (lectura < escritura < administrador), con alcance al workspace. Falla con 403.

Límite de tasa — un contador de ventana deslizante en rutas costosas y públicas. Falla con 429.

Handler — la solicitud validada llega a la lógica de negocio verificada por Zod.

Flujo de solicitud

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

Almacén del límite de tasa

El limitador utiliza por defecto una ventana en memoria local al proceso. Cuando se configura una URL de Redis, cambia a una ventana deslizante respaldada por Memorystore (Lua atómico) compartida entre todas las instancias del servidor, de modo que un único usuario no puede superar su límite distribuyendo solicitudes entre réplicas.

El cliente Redis se conecta de forma diferida y el limitador falla abierto hacia la memoria — una interrupción de la caché nunca puede bloquear el inicio ni generar un error 500 en una solicitud. Se degrada a límites por instancia hasta que Redis se recupere.

Aislamiento de inquilinos

La autorización siempre tiene alcance de workspace. Un permiso es una fila con clave (userId, entityType, entityId), y el ejecutor propaga userId y workspaceId a lo largo de toda la ejecución — de modo que un flujo de trabajo solo puede leer y escribir datos dentro del límite de su propio inquilino. Consulte Multi-tenancy.