5.5 KiB
US-MMD001-006: Aplicar RLS por Taller
Metadata
| Campo | Valor |
|---|---|
| ID | US-MMD001-006 |
| Epica | EPIC-MMD-001 - Fundamentos |
| Modulo | fundamentos |
| Prioridad | P0 |
| Story Points | 5 |
| Sprint | Sprint 1 |
| Estado | Backlog |
| Asignado a | Por asignar |
Historia de Usuario
Como sistema, quiero aplicar Row-Level Security (RLS) en todas las tablas por workshop_id, para garantizar que cada taller solo vea y modifique sus propios datos.
Descripcion Detallada
RLS (Row-Level Security) es una caracteristica de PostgreSQL que permite filtrar filas automaticamente basandose en el usuario actual. Cada query se filtra automaticamente por el workshop_id del usuario logueado, garantizando aislamiento total de datos entre talleres.
Criterios de Aceptacion
Escenario 1: Aislamiento de datos entre talleres
DADO que existen 2 talleres: "Diesel Express" y "Mecanica Industrial"
CUANDO un usuario de "Diesel Express" consulta ordenes de servicio
ENTONCES solo ve las ordenes de "Diesel Express"
Y no ve ninguna orden de "Mecanica Industrial"
Escenario 2: Contexto de sesion automatico
DADO que un usuario inicia sesion en "Diesel Express"
CUANDO el sistema establece la sesion
ENTONCES se configura automaticamente app.current_workshop_id = 'uuid-diesel-express'
Y todas las queries filtran por ese workshop_id
Escenario 3: Insercion con workshop_id automatico
DADO que un usuario de "Diesel Express" crea una nueva orden
CUANDO inserta el registro
ENTONCES el sistema asigna automaticamente workshop_id del contexto
Y no se requiere especificar workshop_id manualmente
Escenario 4: Proteccion contra acceso cruzado
DADO que un usuario de "Diesel Express" intenta acceder a orden de "Mecanica Industrial"
CUANDO hace GET /api/orders/{id-de-mecanica-industrial}
ENTONCES el sistema retorna 404 Not Found
Y no revela que el registro existe en otro taller
Escenario 5: SuperAdmin ve todos los talleres
DADO que un SuperAdmin accede al sistema
CUANDO consulta datos
ENTONCES puede ver registros de todos los talleres
Y puede filtrar por taller especifico
Implementacion Tecnica
Configuracion de Contexto
-- Funcion para establecer contexto
CREATE OR REPLACE FUNCTION set_workshop_context(p_workshop_id UUID)
RETURNS VOID AS $$
BEGIN
PERFORM set_config('app.current_workshop_id', p_workshop_id::TEXT, FALSE);
END;
$$ LANGUAGE plpgsql;
-- Funcion para obtener contexto
CREATE OR REPLACE FUNCTION get_current_workshop_id()
RETURNS UUID AS $$
BEGIN
RETURN NULLIF(current_setting('app.current_workshop_id', TRUE), '')::UUID;
END;
$$ LANGUAGE plpgsql;
Politicas RLS por Tabla
-- Ejemplo: Tabla service_orders
ALTER TABLE service_management.service_orders ENABLE ROW LEVEL SECURITY;
-- Politica de lectura
CREATE POLICY service_orders_select ON service_management.service_orders
FOR SELECT
USING (workshop_id = get_current_workshop_id() OR is_superadmin());
-- Politica de insercion
CREATE POLICY service_orders_insert ON service_management.service_orders
FOR INSERT
WITH CHECK (workshop_id = get_current_workshop_id());
-- Politica de actualizacion
CREATE POLICY service_orders_update ON service_management.service_orders
FOR UPDATE
USING (workshop_id = get_current_workshop_id());
-- Politica de eliminacion
CREATE POLICY service_orders_delete ON service_management.service_orders
FOR DELETE
USING (workshop_id = get_current_workshop_id());
Tablas a Proteger
| Schema | Tabla | RLS |
|---|---|---|
| workshop_core | workshops | Solo SuperAdmin |
| workshop_core | work_bays | Por workshop_id |
| workshop_core | service_catalog | Por workshop_id |
| service_management | service_orders | Por workshop_id |
| service_management | diagnostics | Por workshop_id |
| parts_management | parts | Por workshop_id |
| parts_management | movements | Por workshop_id |
| vehicle_management | vehicles | Por workshop_id |
Tareas Tecnicas
Database:
- DB-015: Crear funcion set_workshop_context()
- DB-016: Crear funcion get_current_workshop_id()
- DB-017: Crear funcion is_superadmin()
- DB-018: Aplicar RLS a todas las tablas de negocio
- DB-019: Crear trigger para auto-asignar workshop_id en INSERT
Backend:
- BE-020: Middleware para establecer contexto al inicio de request
- BE-021: Ejecutar set_workshop_context() en cada conexion
- BE-022: Tests de penetracion entre tenants
Frontend:
- No aplica (transparente para frontend)
Dependencias
Depende de:
- US-MMD001-001: Configurar taller
- MGN-004 Tenants (Core)
Bloquea:
- Todas las demas US (requieren RLS activo)
Tests de Seguridad Requeridos
| Test | Descripcion | Resultado Esperado |
|---|---|---|
| Cross-tenant SELECT | Intentar leer datos de otro taller | 0 registros |
| Cross-tenant UPDATE | Intentar modificar datos de otro taller | 0 registros afectados |
| Cross-tenant DELETE | Intentar eliminar datos de otro taller | 0 registros afectados |
| Direct ID access | Acceder por ID a registro de otro taller | 404 Not Found |
| SuperAdmin access | SuperAdmin accede a cualquier taller | Exito |
Definition of Done (DoD)
- RLS habilitado en todas las tablas
- Contexto se establece automaticamente
- Tests de penetracion pasando
- SuperAdmin puede ver todo
- Documentacion de seguridad
Creada por: Requirements-Analyst Fecha: 2025-12-06