Resolviendo la Contaminación de Datos Multi-Tenant en Tareas en Cola con devlog-ist/landing
En el proyecto devlog-ist/landing, nos enfocamos en corregir un problema crítico que afectaba la integridad de los datos en un entorno multi-tenant. Este proyecto es una plataforma que permite a múltiples inquilinos (tenants) compartir la misma infraestructura, pero manteniendo sus datos completamente aislados. El problema específico que abordamos era la contaminación de datos entre tenants debido a un caché estático del esquema en los workers de la cola.
El Problema: Caché Estático y Reconexiones de PDO
El TenantManager mantenía un caché estático $currentAppliedSchema. En workers de larga duración como los de Horizon, las reconexiones de PDO podían provocar que se omitiera search_path después de la reconexión. Esto significaba que un worker podía procesar trabajos para un tenant utilizando el esquema de otro, resultando en contaminación de datos.
La Solución: Reinicio del Estado del Tenant y Filtro de Seguridad
Para solucionar este problema, implementamos las siguientes medidas:
- Eliminación del Caché Estático: Se eliminó el caché estático
$currentAppliedSchemadelTenantManager. - Reinicio del Estado del Tenant: Se implementó un listener
JobProcessingque reinicia el estado del tenant antes de cada trabajo en la cola. Esto asegura que cada trabajo se ejecute con el esquema correcto. - Filtro de Seguridad Adicional: Se añadió un filtro
user_ida las consultas del proyecto de contenido como defensa en profundidad. Esto proporciona una capa adicional de seguridad para prevenir el acceso no autorizado a los datos. - Migración para Limpiar Datos Contaminados: Se incluyó una migración para limpiar los datos contaminados en los esquemas de los tenants afectados.
// Ejemplo ilustrativo del listener JobProcessing
class JobProcessingListener
{
public function handle(JobProcessing $event)
{
Tenant::setTenant($event->job->tenant_id);
}
}
El Resultado
Con estas medidas, se resolvió la contaminación de datos multi-tenant, asegurando que cada tenant acceda solo a sus propios datos. El reinicio del estado del tenant antes de cada trabajo, junto con el filtro de seguridad adicional, proporciona una solución robusta y confiable.