Volver a la wiki

T5 (Auditoría Suprema R6): Eliminación del fallback a primer tenant en operaciones multi-tenant

Problema

El código heredado (era monoemresa) contenía el antipatrón Organization.objects.first() como fallback en ~26 call-sites:

Consecuencia: Un principal autenticado sin organización asignada (o anónimo en ciertos endpoints legacy) caía automáticamente al primer tenant de la BD:

En un producto SaaS multi-cliente, esto es innegociable.

Solución

Fail-closed: eliminar todos los fallbacks. La regla es estricta:

  1. get_current_org(request) retorna None si el user no tiene org (no intenta adivinar)
  2. require_org(request) (nuevo) lanza HttpError(403) si no hay org — para endpoints que REQUIEREN contexto
  3. Endpoints read-only (/api/users, /api/search, /api/logs, /api/status) retornan listas vacías si get_current_org() es None
  4. Endpoints write (PUT /api/settings/...) lanzan 404 si no hay org
  5. Vistas (views.py): dashboard y reports muestran vacío, no caen a otro tenant

Además: rack_editor ahora scoped a org. Antes get_object_or_404(Rack, id=...), ahora get_object_or_404(Rack, id=..., organization=org).

Cambios de código

Alineación

Impacto esperado

✅ Breaking: un bot/script que dependa de Organization.objects.first() como fallback fallará (intencional — forza uso explícito de org context) ✅ No-op para usuarios normales: todo principal tiene org asignada en flujos normales ✅ Seguridad: cierra cross-tenant read/write en admin flows

Estado actual

Merged a main el 2026-06-11 (commit e786894). Suite de tests en Docker sin regresiones (diff de fallos vs base = 0).

Véase también

Subir