CreaRack-SL

Decisión arquitectónica · Unificación de gates con `require_perm` en network (sa4)

Contexto

Antes de sa4, el módulo network mezclaba tres patrones de autorización:

  1. is_admin(request.user) — binario, no granular.
  2. request.user.role directo — acoplamiento a esquema de roles.
  3. Sin gate — endpoints públicos sin intención clara.

Esto causaba:

  • Inconsistencia (mismo endpoint a veces gateado, a veces no).
  • Vulnerabilidades (endpoints sensibles olvidados).
  • AttributeError 500 con usuarios sin rol (Agent-JWT, anónimo).

Decisión

Usar require_perm(request, scope: str, level: str) de core.utils como función defensiva única para autorizar en toda la sub-área network.

# Antes
if not is_admin(request.user):
    return 403, {...}

# Después
require_perm(request, "network", "edit")  # levanta 403 si falla

Niveles de permiso en network

network:view   → lectura de metadatos (listas, estado, sin secretos)
network:edit   → lectura de secretos + mutación de configuración + device status
network:admin  → mutaciones de backup + delete group + health check

Implementación (sa4)

Endpoints view (lectura sin secretos)

  • list_device_groups
  • get_device_details
  • get_network_status
  • get_device_status
  • get_device_network_config
  • list_backups ← solo metadatos, no config_text

Endpoints edit (lectura de secretos, mutación)

  • get_device_credentials ← secretos SSH/SNMP descifrados (ALTA #1)
  • view_backup ← config_text en claro (ALTA #3)
  • compare_backups ← diff de secrets (ALTA #3)
  • download_backup ← config completa (ALTA #3)
  • update_device_status / update_devices_status_batch
  • force_check_device ← + anti-SSRF (ALTA #2)
  • save_device_network_config
  • create_device_group
  • assign_devices_to_groups

Endpoints admin (mutaciones peligrosas)

  • trigger_backup
  • save_backup
  • delete_backup
  • restore_backup
  • delete_device_group

Por qué require_perm es mejor

AspectoAntesCon require_perm
Granularidadview/edit/adminExplícita por endpoint
Fail-safeFalta gate → vulnerableFalta gate → NameError → fix rápido
Acoplamientorequest.user.role directoCentralizado en core.utils
ErroresAttributeError 500403 Forbidden limpio
TestingMezcla de fixturesviewer_user, operator_user, admin_user reutilizables

Trade-offs

  • Pro: Consistencia, seguridad defensiva, testable.
  • Contra: Dependency en core.utils.require_perm — si ese módulo cambia, toda network se ve afectada (pero es intencional: centralizar la lógica de autorización).

Próximos pasos

  • Aplicar mismo patrón en monitoring, signage, core (unificación global).
  • Documentar niveles de permiso por módulo en concepto central.
  • Refactor de helpers legacy (is_admin) → deprecation en favor de require_perm.

Véase también

  • [[feature—network—auditoria-sa4-devices-backups-groups]]
  • [[concept—saas—multi-tenancy]]
  • [[concept—security—authorization]]
  • [[entity—core—service—require-perm]]