API y empresas

Aislamiento entre empresas: las pruebas negativas que una API multi-tenant necesita

Autenticarse como una empresa no alcanza. IDs, cursores, filtros, exports e idempotencia deben resistir intentos cruzados sin revelar ni modificar recursos de otro tenant.

Por Marco Ferreiro ·

Dos gabinetes transparentes separados que contienen fichas de distintos colores

Una API multi-tenant puede autenticar correctamente a todos sus clientes y aun así mezclar datos entre empresas. El error aparece cuando una operación confía en un identificador recibido, en una pantalla que ocultó un botón o en un filtro que alguien olvidó aplicar.

La prueba decisiva es negativa: una empresa intenta leer o modificar un recurso ficticio de otra y el sistema no sólo lo impide, sino que evita revelar si existe.

Autenticación y aislamiento responden preguntas distintas

La autenticación responde quién presenta la solicitud. La autorización decide qué puede hacer ese sujeto sobre un objeto concreto. NIST SP 800-162 describe ABAC como la evaluación de atributos del sujeto, objeto, operación y, cuando corresponde, entorno frente a una política.

En un producto para empresas, el tenant es un atributo central, pero no el único. También importan rol, estado del recurso, propósito, alcance de la credencial y operación solicitada. Un administrador de la empresa A sigue sin tener derechos sobre la empresa B.

La interfaz no es una frontera. Ocultar un enlace o reemplazar un selector no impide que alguien envíe la petición directamente.

Preparar dos universos completamente sintéticos

Creá empresa_alpha y empresa_beta en un entorno de prueba. Cada una recibe:

No uses patentes, nombres ni actas reales. El objetivo es verificar relaciones, no realismo personal. Guardá los fixtures como código para recrearlos sin depender del estado residual de una ejecución anterior.

La prueba básica: cambiar sólo el objeto

Ejecutá una lectura válida como Alpha y conservá método, ruta, parámetros y encabezados. Repetila cambiando únicamente el ID por uno perteneciente a Beta.

El resultado cruzado debe ser una denegación controlada. No debe devolver campos parciales, contar coincidencias, cargar miniaturas ni emitir eventos destinados a Beta. La misma técnica se repite para actualizar, borrar, descargar y reintentar.

OWASP destaca la autorización rota a nivel de objeto porque los IDs suelen ser controlados por el cliente. Que sean UUID difíciles de adivinar no reemplaza el control: pueden aparecer en logs, URLs, correos o relaciones.

IDs anidados y rutas engañosas

Una ruta como /empresas/alpha/reportes/reporte_beta contiene un tenant correcto y un objeto incorrecto. El servidor debe verificar que el reporte pertenece realmente a Alpha; no alcanza con autorizar el primer segmento.

Probá también:

Cada repositorio o servicio debe recibir el contexto de autorización necesario. Si el chequeo vive sólo en la ruta HTTP, un job interno podría omitirlo.

Cursores, filtros y búsquedas también son objetos

Un cursor puede codificar posición, filtros o referencias a una consulta anterior. Entregar a Alpha un cursor creado para Beta y recibir la siguiente página sería una fuga aunque los IDs directos estén protegidos.

La matriz debe intercambiar cursores, filtros guardados, tokens de descarga y enlaces firmados. También conviene probar combinaciones de include, orden y búsqueda textual: un contador total o una sugerencia autocompletada puede revelar datos sin devolver la fila.

Los caches se aíslan con claves que incorporan el tenant y todos los factores de autorización relevantes. Una respuesta cacheada para Beta nunca debe servirse a Alpha por compartir ruta pública.

Exportaciones y procesos asíncronos

Una exportación suele separarse en dos pasos: crear el trabajo y descargar el archivo. Ambos requieren autorización. Probá que Alpha no pueda consultar el estado, adivinar la ruta del objeto almacenado ni recibir la notificación de un trabajo de Beta.

En colas, el mensaje debería llevar un tenant autenticado por el servicio productor, no uno aceptado ciegamente desde el cuerpo original. El consumidor vuelve a aplicar sus invariantes antes de leer o escribir.

También revisá nombres de archivo, metadatos, métricas y trazas. La Ley 25.326 exige condiciones técnicas de integridad y seguridad para bases con datos personales; aislar salidas auxiliares forma parte de esa responsabilidad, aunque el endpoint principal sea correcto.

Idempotencia sin colisiones entre empresas

Si dos tenants usan la clave reintento-1, no deben compartir resultado. El espacio de idempotencia necesita incluir tenant, operación y, según el contrato, actor o recurso.

La prueba crea primero una operación en Beta y repite la misma clave desde Alpha con un cuerpo distinto. Un diseño correcto procesa o rechaza la solicitud según las reglas de Alpha; jamás devuelve el resultado de Beta ni considera ambas acciones idénticas.

Hacé lo mismo con webhooks, locks y deduplicación de colas. Las claves globales son un atajo peligroso cuando el cliente controla su valor.

Evitar un oráculo de existencia

Muchas APIs responden 404 para un recurso inexistente o inaccesible, aunque RFC 9110 permite distintas políticas. Lo importante es la consistencia. Compará:

Si el recurso ajeno tarda mucho más porque el sistema primero lo carga y después niega acceso, la diferencia puede revelar existencia. La prueba fija tolerancias razonables sin exigir tiempos idénticos al microsegundo.

Qué registrar cuando una prueba falla

El reporte no debe copiar el dato ajeno que logró ver. Registrá el fixture sintético, la operación, el control esperado, la respuesta saneada y el punto donde se omitió la política. Corregí la causa común en la capa compartida antes de agregar parches ruta por ruta.

Una suite útil corre en cada cambio y genera tenants nuevos para evitar falsos positivos por caché. Su afirmación final es acotada: las fronteras probadas negaron todas las combinaciones cruzadas observadas. No reemplaza revisión de arquitectura, pero convierte el aislamiento en una propiedad comprobable.

Metodología

Alcance
Matriz de autorización negativa inspirada en ABAC, controles NIST y riesgos de autorización por objeto para dos tenants totalmente ficticios.
Unidad de análisis
Una combinación de sujeto autenticado, tenant, operación, objeto, canal de salida y resultado observable.
Cobertura
Lectura, escritura, búsqueda, cursores, exportaciones, trabajos asíncronos e idempotencia; estándares consultados el 14 de agosto de 2026.

Limitaciones

Fuentes

Preguntas frecuentes

¿Alcanza con incluir tenant_id en todas las consultas SQL?

No. Es una defensa importante, pero también deben cubrirse almacenamiento de objetos, cachés, colas, exports, jobs y cualquier autorización previa a la consulta.

¿Un 404 para recursos ajenos resuelve la filtración de existencia?

Ayuda si es consistente, pero también deben compararse cuerpo, encabezados, tiempos, métricas y efectos laterales. Una diferencia observable puede seguir funcionando como oráculo.

¿Estas pruebas pueden ejecutarse con datos de producción?

No hace falta. Dos tenants y recursos totalmente sintéticos permiten probar la frontera con menor riesgo y pueden recrearse en cada ejecución automatizada.

Notas relacionadas