Lista de verificación de aislamiento por inquilino para prototipos SaaS: evita errores comunes
Usa esta lista de verificación de aislamiento por inquilino para detectar y arreglar fallos multitenant en APIs, almacenamiento, jobs y analytics antes de lanzar tu prototipo SaaS.

Por qué falla el aislamiento por inquilino en prototipos SaaS
Una filtración de datos por inquilino es fácil de imaginar: un cliente inicia sesión, hace clic en “Proyectos” y ve el nombre, la factura, el archivo o la lista de usuarios de otra persona. A veces es algo más pequeño, como una sugerencia de autocompletar que contiene el contacto de otra empresa, o un total del panel que incluye silenciosamente datos de otras cuentas.
Esto ocurre en prototipos porque “el inicio de sesión funciona” no es lo mismo que “los datos están aislados”. Muchos builds generados por IA o realizados con prisa ponen páginas tras autenticación, pero no aplican comprobaciones de inquilino de forma coherente en todos los puntos donde se leen, escriben o procesan datos. Un endpoint filtra por user_id, otro se olvida de filtrar. Un trabajo en background se ejecuta sin contexto de inquilino. Una clave de caché se comparte. La interfaz puede verse correcta, pero las reglas subyacentes son desiguales.
Algunas formas comunes en las que las primeras apps SaaS multitenant filtran datos:
- Endpoints de API que aceptan un ID de registro y lo devuelven sin verificar que pertenezca al inquilino del llamador
- Consultas a la base de datos que omiten un filtro por inquilino en un camino de código (a menudo pantallas de administrador, exportaciones, búsqueda)
- URLs de almacenamiento de objetos o rutas de archivos que no están por inquilino
- Jobs en segundo plano que procesan “todos los registros” en lugar de “los registros de este inquilino”
- Eventos de analytics etiquetados con el inquilino equivocado, mezclando informes entre clientes
El coste de una pequeña filtración rara vez es pequeño. La confianza cae rápido, la carga de soporte aumenta y llega la pérdida de clientes. Si manejas datos personales, una filtración puede desencadenar notificaciones de brecha, problemas contractuales o complicaciones de cumplimiento.
Para un fundador no técnico, un buen aislamiento significa una promesa clara: los datos de cada cliente se comportan como si vivieran en su propia caja, aunque ejecutes una sola app. Una lista de verificación práctica de aislamiento por inquilino debe cubrir todos los lugares por donde pueden moverse los datos: APIs, base de datos, archivos, jobs, caché y analytics. Si heredaste un prototipo que “funciona en su mayoría” pero te parece arriesgado, FixMyMess puede auditar el código y señalar dónde se rompe el aislamiento antes de que incorpores más clientes.
Conceptos básicos de multitenancy y los límites que debes definir
Single-tenant significa que cada cliente tiene su propia app o base de datos aislada. Multi-tenant significa que los clientes comparten la misma app (y a menudo la misma base de datos), y tu código debe garantizar la separación. Los prototipos suelen empezar “funcionando en su mayoría” y luego rompen el aislamiento cuando se lanza una función rápida.
El primer límite a definir es la identidad del inquilino: ¿dónde aprende la app a qué inquilino pertenece esta petición? En la mayoría de apps SaaS, debe provenir del contexto de usuario autenticado (token o sesión) verificado por el servidor. No debe provenir de algo que el cliente pueda cambiar libremente, como una query string (por ejemplo, ?tenantId=...), un campo en el body de la petición o un header personalizado.
Los límites de aislamiento que debes establecer temprano
Piensa en el aislamiento por inquilino como un conjunto de muros que debes construir en varios sitios:
- Límite de petición: cada solicitud de API resuelve un inquilino, una vez, en el servidor
- Límite de datos: cada lectura/escritura está acotada a ese inquilino (no solo las lecturas)
- Límite de almacenamiento: los archivos están separados por inquilino y el acceso se verifica en el servidor
- Límite de jobs: el trabajo en background se ejecuta con un contexto explícito de inquilino
- Límite de analytics: eventos y dashboards nunca mezclan inquilinos
Si estás creando una lista de verificación de aislamiento por inquilino, trata cada muro como obligatorio. Faltar uno solo basta para una filtración.
Tablas compartidas vs bases de datos separadas
Las tablas compartidas (una sola base de datos, una columna tenant_id) son más rápidas de construir y más baratas de operar, pero necesitan guardarraíles estrictos como scoping impuesto y constraints. Bases de datos separadas (o esquemas) pueden reducir el blast radius y facilitar el cumplimiento, pero añaden carga operativa (migraciones, reporting, gestión de conexiones).
Una regla simple: si esperas un pequeño número de inquilinos de alto valor con requisitos estrictos, considera separación física más fuerte. Si esperas muchos inquilinos pequeños, las tablas compartidas son comunes, pero solo si aplicas scoping en todas partes, no en “la mayoría” de los lugares.
Dónde ocurren las filtraciones con más frecuencia
La mayoría de las filtraciones de datos por inquilino en prototipos no son hackers entrando. Ocurren cuando un error honesto convierte una suposición single-tenant en un bug multi-tenant. Por eso una lista de verificación de aislamiento es menos sobre ataques sofisticados y más sobre quitar las armas de fuego inocentes.
Primero, decide qué es un “inquilino” en tu producto (org, workspace, cuenta). Escríbelo, ponlo en comentarios de código y usa el mismo significado en todas partes. Muchas filtraciones comienzan cuando la UI usa “workspace”, la API usa “org” y la base de datos usa “account_id”.
Las rutas de filtración más comunes parecen aburridas, pero se lanzan todo el tiempo:
- Adivinación de IDs y acceso directo a objetos: un endpoint carga
/invoices/123sin comprobar que la factura 123 pertenezca al inquilino del llamador. - Consultas mal acotadas: una consulta filtra por
user_idpero olvidatenant_id, así que usuarios que comparten dominio de email o rol ven filas extra. - Buckets o carpetas de almacenamiento compartidos: archivos almacenados con claves predecibles y reglas de acceso que no incluyen contexto de inquilino.
- Jobs en background sin contexto de inquilino: un job ejecuta “enviar informe semanal” para el inquilino equivocado porque la carga de la cola no incluía
tenant_id. - Atajos de administrador y soporte: endpoints “temporales”, paneles de debug o exportaciones que omiten el camino normal de autorización.
Las filtraciones indirectas son aún más fáciles de pasar por alto porque nadie “ve” los registros crudos. Vigila funciones como búsqueda, autocompletar, dashboards y exportaciones CSV. Un solo conteo, resultado top o lista de “elementos recientes” puede revelar que otro inquilino tiene un cliente llamado X o un proyecto titulado Y.
Si heredaste un prototipo generado por IA, trata cada consulta, job y acceso a almacenamiento como sospechoso hasta que puedas señalar una comprobación clara del límite de inquilino.
Cómo imponer aislamiento en tus APIs (paso a paso)
El aislamiento por inquilino suele fallar en las APIs porque el contexto de inquilino se maneja “a veces” en lugar de “siempre”. El enfoque más seguro es tratar el contexto de inquilino como la autenticación: una única fuente de verdad, aplicada en cada petición.
Un patrón repetible para APIs
Comienza decidiendo dónde es autoritativo el contexto de inquilino. Elige exactamente uno: reclamos del token (común con JWT) o sesión del lado servidor. Todo lo demás es solo entrada.
Luego implementa un guard único que se ejecute para cada endpoint:
- Lee el usuario autenticado y el inquilino desde tu fuente de verdad elegida.
- Ignora cualquier tenantId que venga del cliente (body, query string, headers). Si lo necesitas para enrutar, trátalo como una pista y compáralo con el inquilino autenticado.
- Ejecuta una comprobación de autorización consistente (el usuario pertenece al inquilino, rol permitido para la acción).
- Pasa el contexto de inquilino a los métodos de servicio, no solo a los controladores. Evita helpers “globales” que puedan ejecutarse sin inquilino.
- Devuelve la misma forma de error para “no encontrado” y “no permitido” cuando un desajuste de inquilino pudiera revelar datos (por ejemplo, responde como si el registro no existiera).
Un ejemplo concreto: un endpoint como GET /invoices/:id parece inofensivo, pero si el handler carga Invoice.findById(id) antes de comprobar el inquilino, puedes filtrar datos adivinando IDs. La solución es acotar la consulta: “buscar factura por id Y tenant”. Haz lo mismo para actualizaciones y borrados.
Prueba rápida de dos inquilinos
Mientras construyes, mantén dos inquilinos de prueba abiertos en perfiles de navegador separados. Crea registros similares en ambos y luego intenta copiar y pegar IDs entre inquilinos. Si algo aparece, tu lista de verificación de aislamiento acaba de encontrar un bug real.
Si heredaste un prototipo generado por IA, este es un fallo común que FixMyMess ve en auditorías: el contexto de inquilino existe, pero no se aplica de forma consistente en todos los endpoints.
Aislamiento en la base de datos: consultas, constraints y guardarraíles
La mayoría de las filtraciones por inquilino ocurren porque la base de datos acepta una consulta que “parece correcta” pero olvidó un filtro. Si quieres una lista de verificación práctica, empieza aquí: haz que sea difícil ejecutar una consulta sin scope, incluso por accidente.
Primero, asume que cada camino de lectura se usará para listas y búsquedas. Esos son los lugares donde los desarrolladores suelen escribir una consulta reutilizable y olvidar incluir la condición de inquilino. Una buena regla: si una tabla es propiedad de un inquilino, cada consulta debe incluir tenant_id, incluidos conteos, exportaciones, autocompletar y “elementos recientes”.
Guardarraíles que atrapan errores
Las comprobaciones en el código ayudan, pero las reglas en la base de datos capturan errores cuando el código cambia. Añade tenant_id a cada tabla propiedad de inquilino y refuérzalo con constraints e índices. Por ejemplo, usa unicidad compuesta como (tenant_id, email) para usuarios y asegura claves foráneas que incluyan el scope de inquilino (o valida la coincidencia de inquilino en triggers cuando FK compuestas no sean prácticas).
Guardarraíles rápidos para añadir pronto:
- Añadir
NOT NULL tenant_iden tablas de propiedad de inquilino. - Usar índices compuestos que empiecen por
tenant_idpara acelerar consultas acotadas. - Usar constraints únicos compuestos para evitar colisiones entre inquilinos.
- Bloquear valores por defecto de “tenant” en producción.
Row-level security (RLS) y tablas “globales”
Row-level security puede ayudar cuando múltiples servicios o caminos de consulta tocan las mismas tablas. Funciona mejor cuando cada conexión establece un contexto de inquilino y puedes probarlo de forma fiable. No sustituye a una buena autorización, pero reduce el blast radius cuando alguien olvida un filtro.
Para tablas “globales” como planes o plantillas, separa los datos verdaderamente globales de las personalizaciones por inquilino. Un patrón seguro común es: las filas globales no tienen tenant_id, y las personalizaciones por inquilino viven en una tabla diferente que sí es propiedad del inquilino.
Finalmente, planifica el acceso de soporte/admin. Usa un rol o endpoint separado, exige selección explícita de inquilino y registra cada lectura/escritura administrativa con quién, cuándo y qué inquilino. Si heredaste un esquema generado por IA donde esto está desordenado, FixMyMess puede auditar consultas y constraints rápidamente y señalar dónde puede romperse el aislamiento.
Archivos y object storage: prevenir accesos cruzados accidentales
Los archivos son un lugar común donde los prototipos filtran datos. El código suele “funcionar” con un solo bucket y una sola carpeta, y luego rompe el aislamiento cuando un segundo inquilino sube un archivo con el mismo nombre o cuando una URL compartida se reenvía.
Empieza con una regla: todo objeto almacenado necesita un límite de inquilino inequívoco. El patrón más simple es un prefijo de tenant requerido en la clave de almacenamiento (por ejemplo, tenants/<tenant_id>/...) y la app debe negarse a leer o escribir cualquier cosa que no coincida con el inquilino actual.
Evita buckets públicos y URLs públicas de larga duración por defecto. Si necesitas compartir, prefiere URLs firmadas de corta duración que se generen solo después de que tu servidor verifique identidad y pertenencia al inquilino. Nunca confíes en una ruta de archivo o clave de objeto proporcionada por el cliente.
Tus endpoints de descarga y vista previa son los verdaderos guardianes. Un bug común: GET /files/:id carga un registro en la BD por id y luego devuelve el archivo, pero la consulta olvida WHERE tenant_id = ?. Un filtro faltante se convierte en una brecha entre inquilinos. Trata esto como parte de tu lista de verificación de aislamiento.
También vigila los metadatos. Nombres de archivo, datos EXIF, propiedades de PDF o campos “uploaded_by” pueden exponer nombres de inquilinos, IDs internas o direcciones de correo cuando se comparten archivos.
Una auditoría rápida que puedes ejecutar hoy:
- Confirma que cada clave de objeto incluye un prefijo de inquilino y que se hace cumplir en el servidor.
- Revisa que cada lookup de archivo incluya
tenant_iden la consulta y en la autorización. - Asegura que el acceso compartido use URLs firmadas de corta duración y no objetos públicos.
- Elimina o reescribe metadatos sensibles al subir (especialmente imágenes y PDFs).
- Define reglas de retención y eliminación a nivel de inquilino y verifica la eliminación completa al offboarding.
Si heredaste un prototipo generado por IA (Lovable/Bolt/v0/Cursor/Replit), FixMyMess frecuentemente encuentra reglas de almacenamiento que parecen correctas en el código pero no se aplican de forma coherente en producción.
Jobs en background y colas: mantener el contexto de inquilino intacto
El trabajo en background es donde el aislamiento por inquilino se rompe silenciosamente. La petición API tenía el tenant ID y los permisos correctos, pero al pasar trabajo a una cola ese contexto puede desaparecer. Entonces un worker toma un job, se ejecuta con acceso “sistema” y toca datos del inquilino equivocado.
Una regla simple ayuda: cada job debe llevar su contexto de inquilino en la carga al crearse. Eso suele significar tenant_id más los identificadores mínimos necesarios (como user_id o invoice_id), y nada que pueda “buscarse después” sin comprobaciones.
Nunca confíes en “usuario actual” dentro de un worker. Los workers no tienen un usuario realmente logueado, y cualquier estado global compartido (como un objeto de usuario cacheado o un esquema de base de datos por defecto) puede apuntar al último job que se ejecutó. En su lugar, el worker debería establecer explícitamente el scope de inquilino al inicio del job y validarlo antes de hacer cualquier otra cosa.
Los reintentos también pueden causar filtraciones. Si un job falla y se reintenta, asegúrate de que la payload del retry aún incluya el tenant ID y que el worker vuelva a aplicar el scoping en cada intento. Lo mismo aplica a dead-letter queues: al inspeccionar o reproducir jobs fallidos, el contexto de inquilino debe estar presente y visible.
Las colas compartidas están bien, pero los logs mixtos por inquilino son riesgosos. Si tu worker registra bodies de peticiones, errores SQL o volcados completos de objetos, puedes filtrar datos de un inquilino en logs que otro personal (o herramientas) puede ver. Registra con tenant IDs y identificadores cortos, no con registros completos.
Comprobaciones rápidas que detectan la mayoría de los problemas:
- Crea un job y confirma que
tenant_idestá almacenado en la payload del job y aparece en los logs del worker. - En el worker, falla rápido si
tenant_idfalta o no coincide con el tenant del registro recuperado. - En reintentos y manejo de dead-letter, verifica que el scoping se vuelva a aplicar y no se “recuerde”.
- Añade límites por inquilino o fairness en las colas para que un inquilino ruidoso no deje sin recursos a otros.
Si heredaste un prototipo generado por IA, los workers suelen ser donde el contexto de inquilino es implícito e inseguro. FixMyMess puede auditar las rutas de colas y workers y reparar problemas de aislamiento rápido, antes de que se conviertan en un incidente de datos.
Caché, sesiones y notificaciones: riesgos ocultos entre inquilinos
Caching y sesiones son fáciles de “configurar y olvidar” en prototipos. Por eso suelen ser una razón habitual por la que una lista de verificación de aislamiento falla en la práctica. La petición de un inquilino calienta la caché y el siguiente inquilino recibe la misma respuesta.
Un ejemplo sencillo: tu API devuelve /settings para el usuario actual. Lo cacheas bajo settings por 5 minutos. El Inquilino A lo consulta primero, luego el Inquilino B ve el logo, plan o incluso el email de facturación del Inquilino A. Nadie te “hackeó”: simplemente hay una clave de caché que ignora al inquilino.
Claves de caché, invalidación y objetos “compartidos”
Haz que la identidad de la caché coincida con la identidad de los datos. Si los datos están scopeados por inquilino, la caché también debe estarlo, incluida la invalidación.
- Incluye
tenant_id(y a menudo el rol de usuario) en las claves de caché para respuestas de API. - Invalida por inquilino cuando cambien datos del inquilino, no solo por endpoint.
- Ten cuidado con caches “globales” (feature flags, plantillas) que silenciosamente contengan campos específicos de un inquilino.
- Prefiere cachear IDs y volver a verificar el acceso al leer cuando los datos sean sensibles.
Sesiones, notificaciones y logs
Las sesiones también pueden cruzar fronteras si no las enlazas firmemente. Un token de sesión debe mapear a un user y a un tenant, y cada petición debe confirmar ambos.
Antes de lanzar, revisa estas áreas:
- El almacenamiento de sesiones evita replay entre inquilinos (token -> user_id + tenant_id, verificado en cada petición).
- Restablecimientos de contraseña, invitaciones y magic links incluyen contexto de inquilino y expiran rápido.
- Emails, SMS y notificaciones in-app verifican que el destinatario pertenece al inquilino al momento de enviar.
- Los logs nunca almacenan secretos (API keys, tokens) ni datos sensibles de inquilinos “para depuración”.
Si heredaste un prototipo generado por IA, estos problemas suelen esconderse en código glue. FixMyMess puede hacer una auditoría rápida para encontrar caches que ignoran inquilinos, sesiones débiles y rutas de notificación inseguras antes de producción.
Ejemplo: una filtración simple y cómo ocurre
Una pequeña agencia y una panadería local se registran en el mismo prototipo SaaS. Ambas crean “clientes” en la app y usan una página de lista para encontrarlos.
El prototipo almacena registros como clients(id, tenant_id, name, email). El endpoint API parece inofensivo: GET /api/clients?search=ann.
El bug: la consulta filtra por el término de búsqueda, pero olvida el inquilino.
Así que la agencia busca “Ann” y obtiene también a “Ann Smith” de la panadería. Al principio nadie lo nota porque solo ocurre cuando los nombres coinciden.
Empeora en sitios que reutilizan la misma consulta. Una exportación CSV saca “todos los clientes coincidentes” e incluye filas entre inquilinos. Un job en background que manda “resumen semanal de clientes” usa la misma lógica y adjunta registros equivocados. Un widget de dashboard cuenta “clientes nuevos esta semana” entre todos, de modo que la panadería ve números inflados y la agencia ve una caída inexplicable.
Una solución rápida es añadir un filtro por inquilino en ese endpoint. Eso detiene la filtración inmediata, pero es frágil porque el siguiente endpoint puede repetir el error.
Una solución adecuada suele tener dos capas:
- Hacer que el scope de inquilino sea automático en la API (derivar
tenant_iddel usuario autenticado, no de parámetros de la petición). - Añadir guardarraíles en la base de datos (RLS o constraint requerido para que consultas sin scope fallen).
- Asegurar que exportaciones, emails y consultas de analytics usen la misma vía de acceso acotada.
Para evitar regresiones, mantén una prueba repetible que falle ruidosamente: crea dos inquilinos, inserta un registro con el mismo nombre en ambos, llama al endpoint de lista como Inquilino A y afirma que cada fila devuelta tiene el tenant_id de Inquilino A. Ejecútala para la API y para el job de exportación.
Si heredaste un prototipo generado por IA, este patrón exacto es común. Equipos como FixMyMess a menudo encuentran la filtración en un endpoint y la siguen hasta helpers de consulta compartidos y jobs en background para arreglarlo de una vez en todos lados.
Lista de auditoría: comprobaciones rápidas en todo el stack
Una lista de verificación de aislamiento por inquilino es más útil cuando te obliga a buscar el mismo error en distintos lugares: “falta o se ignora tenant id”. Ejecuta esta auditoría cada vez que añadas una nueva función, un endpoint nuevo o una tarea en background.
Empieza con estas comprobaciones rápidas:
- APIs: el inquilino debe derivarse del lado servidor (sesión de usuario, token o subdominio), no aceptarse del cliente como campo de confianza. Cada ruta que lea o escriba datos debe aplicar el scope del inquilino, incluidos endpoints “admin” e internos.
- Base de datos: cada tabla propiedad de inquilino tiene una clave de inquilino y no puedes insertar una fila sin ella. Las consultas siempre están acotadas por inquilino y existe un guardarraíl (constraints, políticas o tests) que falle ruidosamente cuando falta el scope.
- Archivos y object storage: las rutas son por inquilino (por ejemplo, un prefijo por inquilino), el acceso está firmado o de otro modo protegido, y “público por defecto” está apagado. No confíes en la UI para ocultar archivos de otros inquilinos.
- Jobs en background: los jobs llevan contexto de inquilino explícito, lo validan antes de empezar y registran de forma segura (sin secretos ni datos crudos de clientes). Los reintentos no deben perder el contexto de inquilino.
- Analytics y exportaciones: los eventos incluyen identificadores de inquilino, los dashboards están filtrados por inquilino y las exportaciones (CSV, emails, “descargar todo”) no pueden incluir datos de otros inquilinos.
Prueba de humo de 10 minutos
Crea dos inquilinos: “Acme” y “Beta”. Crea un registro en cada uno (un usuario, factura, archivo y un evento de analytics). Luego intenta ataques simples: cambia un ID en una URL, reenvía una llamada API estando logueado en el otro inquilino o ejecuta una exportación desde cada inquilino.
Si encuentras aunque sea una lectura entre inquilinos, trátalo como bloqueador de producción. Los equipos suelen pedir a FixMyMess una auditoría rápida de aislamiento en prototipos generados por IA porque estas brechas se esconden en rutas copiadas, handlers de jobs y pantallas admin “temporales”.
Trampas comunes de multitenancy que debes evitar
La mayoría de las filtraciones no vienen de un gran error único. Vienen de pequeños atajos que parecen inofensivos en un prototipo y luego llegan a producción.
Trampas que causan filtraciones reales
Vigila estos patrones cuando ejecutes tu lista de verificación:
- Aceptar tenantId desde la UI, query string o body y usarlo directamente en consultas. El servidor debería derivar el contexto del inquilino del usuario autenticado o token, no de la entrada del usuario.
- Asegurar los endpoints CRUD principales pero olvidar las rutas “secundarias” como búsqueda, count, export, autocompletar y webhooks. Estas suelen consultar tablas más amplias y son fáciles de pasar por alto en reviews.
- Mantener un endpoint “admin” compartido y asumir que es seguro porque no está en la UI. Sin checks de rol estrictos y un scope claro de inquilino permitido, se convierte en una puerta trasera universal.
- Usar caché en endpoints de listas sin una clave de caché consciente del inquilino. Una respuesta cacheada puede servirse a muchos inquilinos, especialmente cuando hay paginación y filtros.
- Dejar que analytics mezclen inquilinos y luego tomar dashboards como fuente de verdad. Una vez que los datos mezclados están en los informes, la gente toma decisiones basadas en ellos y es difícil limpiarlo.
Un ejemplo simple: tu API acota correctamente /invoices por inquilino, pero /invoices/export solo comprueba “está logueado” y ejecuta una consulta amplia. Un cliente hace clic en Exportar y recibe filas de otras empresas.
Si heredaste un prototipo generado por IA, estos problemas aparecen mucho porque el código se duplica y es “casi igual” entre rutas. FixMyMess suele ver un endpoint actualizado con scoping mientras tres rutas similares aún filtran datos.
Una buena regla: cada petición, cada consulta, cada entrada de caché y cada evento deben llevar contexto de inquilino explícitamente, y fallar cerrado cuando falte.
Próximos pasos: endurecer el aislamiento antes de producción
Antes de incorporar clientes reales, decide cómo vas a arreglar el aislamiento: parchear el prototipo que tienes o reconstruir solo las partes de riesgo (auth, data access layer, jobs). Parchear es más rápido cuando la arquitectura está medianamente sana. Reconstruir es más seguro cuando las comprobaciones de inquilino están dispersas por el código o cuando la app mezcla “quién es el usuario” con “a qué inquilino pertenece”.
Una forma práctica de avanzar es tratar el aislamiento como un bloqueo de release y añadir un pequeño plan de regresión que puedas ejecutar cada vez que cambies algo sensible. Incluso una simple “suite de pruebas de dos inquilinos” detecta la mayoría de las filtraciones.
Plan de endurecimiento sencillo de 1 hora
Trabaja estos pasos en orden:
- Elige dos inquilinos de prueba (Inquilino A e Inquilino B) y crea datos idénticos en ambos.
- Ejecuta tus flujos principales estando logueado como Inquilino A e intenta acceder a Inquilino B cambiando IDs en la URL, body y filtros.
- Dispara jobs en background (emails, exportaciones, webhooks) y confirma que solo tocan el inquilino correcto.
- Revisa claves de object storage y URLs firmadas para asegurar que están scopeadas por inquilino.
- Verifica que los eventos de analytics incluyan contexto de inquilino y que, por defecto, no puedan consultarse entre inquilinos.
Programa una auditoría corta de aislamiento justo antes del lanzamiento. El objetivo no es la perfección, sino la confianza de que tus caminos de mayor riesgo están cubiertos y que tu “lista de verificación de aislamiento” está realmente aplicada por código y no por convenciones.
Si tu prototipo fue generado por herramientas como Lovable, Bolt, v0, Cursor o Replit, asume que los límites de inquilino no fueron diseñados cuidadosamente. FixMyMess puede hacer una auditoría de código gratuita para mapear dónde se pierde el contexto de inquilino y luego endurecer auth, acceso a datos y preparación para el despliegue para que tus primeros clientes reales no sean tu suite de pruebas.