ADRactivecreado Tue Jun 09#network#security#authorization#architecture#permissions#django-ninja#core#multi-tenancy
Contexto
Antes de sa4, el módulo network mezclaba tres patrones de autorización:
is_admin(request.user)— binario, no granular.request.user.roledirecto — acoplamiento a esquema de roles.- 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_groupsget_device_detailsget_network_statusget_device_statusget_device_network_configlist_backups← solo metadatos, noconfig_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_batchforce_check_device← + anti-SSRF (ALTA #2)save_device_network_configcreate_device_groupassign_devices_to_groups
Endpoints admin (mutaciones peligrosas)
trigger_backupsave_backupdelete_backuprestore_backupdelete_device_group
Por qué require_perm es mejor
| Aspecto | Antes | Con require_perm |
|---|---|---|
| Granularidad | view/edit/admin | Explícita por endpoint |
| Fail-safe | Falta gate → vulnerable | Falta gate → NameError → fix rápido |
| Acoplamiento | request.user.role directo | Centralizado en core.utils |
| Errores | AttributeError 500 | 403 Forbidden limpio |
| Testing | Mezcla de fixtures | viewer_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 derequire_perm.
Véase también
- [[feature—network—auditoria-sa4-devices-backups-groups]]
- [[concept—saas—multi-tenancy]]
- [[concept—security—authorization]]
- [[entity—core—service—require-perm]]
Referenciado desde
- Auditoría Suprema · network sub-área 4 (Devices/Backups/Groups) — Seguridad de credenciales y configuraciones
- Auditoría Suprema 2 · Tanda 1 (core) — cerrar gates de permiso que faltaban
- Cerrar Broken Access Control en el CRUD de racks y en /api/settings
- Refactor R7 lote P2 · Autorización por scope módulo (is_admin → require_perm)