Volver a la wiki

Cerrar Broken Access Control en el CRUD de racks y en /api/settings

Contexto

Ronda de revisión funcional del 23-08-2026 (tasks #241 y #251) encontró que ninguna escritura del CRUD nuclear de racks (racks/api/racks.py, 13 endpoints) comprobaba el rol del usuario — solo get_current_org(request) filtraba por organización. Un usuario readonly podía crear, editar, clonar y borrar racks; un operator podía ejecutar operaciones que sus propios docstrings marcaban “(Admin)”: crear/aplicar plantillas y borrado permanente de la papelera.

En paralelo, /api/settings tenía 3 escrituras sin portero: session-timeout (ajuste de TODA la organización), onboarding/complete y onboarding/reset — solo exigían estar logueado.

Precedente: el helper require_perm (ver [[entity—core—service—require-perm]]) ya se había aplicado sistemáticamente en blueprints (s105), network ([[decision—20260609—require-perm-unified-authorization]]), vistas de monitoring ([[decision—20260604—broken-access-control-vistas-observatory]]) y signage ([[decision—20260609—signage-broken-access-control]]). El CRUD nuclear de racks (distinto de blueprints/api/racks.py, que sí tenía el guard desde s105) quedó fuera de esas rondas.

Opciones consideradas

  1. Guard manual endpoint a endpoint, sin test de contrato: rápido, pero repite el mismo error de fondo — un endpoint nuevo futuro puede volver a quedar sin gate y nadie lo nota hasta que alguien lo explota.
  2. require_perm en cada escritura + test registry-driven que recorre las operaciones REGISTRADAS en el router (no una lista a mano) y falla si alguna no llama a require_perm. Un endpoint nuevo sin gate rompe el CI solo.

Decisión elegida

Opción 2. require_perm(request, "racks", "edit") en las 13 escrituras de racks/api/racks.py + el restore de la papelera; require_perm(request, "racks", "admin") en las 4 operaciones destructivas/plantilla (create_template, apply_template, permanent_delete_rack, empty_rack_trash). require_perm(request, "users", "admin") en las 3 escrituras de /api/settings, con el esquema de session-timeout acotado a 0-120 (la API deja de depender de que la UI valide). El editor (racks/views.py::rack_editor) pasa can_edit = has_permission(user, "racks", "edit") al contexto y templates/editor.html/base.html ocultan la botonera de escritura a quien no lo tiene — cosmética honesta, la barrera real sigue siendo la API.

De regalo (task #251 pieza 1): las dos alarmas internas de core/tasks.py (check_tenant_integrity, monitor_db_connections) morían con TypeError al saltar porque pasaban un campo extra_data que [[entity—core—model—systemlog]] no tiene — el detalle pasa ahora al campo details (TextField) con level/category correctos.

Consecuencias

Pros:

Contras / riesgo asumido:

Status

Accepted — mergeado y desplegado en v1.82.0 (commit 38c182bc, PR #418).

Véase también

Subir