Tema 8
Autenticar a un sujeto responde quién es. Autorizar responde qué puede hacer. Esa diferencia parece simple, pero detrás de ella hay uno de los problemas más delicados del diseño de sistemas: traducir reglas de negocio, riesgo y contexto en decisiones claras, consistentes y auditables sobre el acceso a recursos.
Muchas aplicaciones hacen bien el login, pero fallan justo después: una vez autenticado el usuario, el sistema no define con suficiente precisión qué operaciones puede ejecutar, sobre qué objetos, bajo qué condiciones y con qué límites. Ahí aparece el problema de autorización.
En sistemas simples, la autorización puede parecer una lista corta de roles o flags. En entornos reales, en cambio, suele reflejar reglas de negocio, jerarquías, relaciones, segregación de funciones, contexto operativo y niveles de riesgo.
Este tema presenta la base conceptual para entender esa capa. Antes de estudiar modelos específicos como RBAC o ABAC, conviene entender qué compone una decisión de autorización y por qué implementarla mal produce tanto vulnerabilidades como caos operativo.
La autorización es el proceso mediante el cual un sistema decide si una identidad autenticada puede realizar una acción determinada sobre un recurso concreto, en un contexto dado.
Esta definición contiene varias piezas importantes:
La autorización no se limita a decir “sí” o “no”. También puede restringir alcance, forzar controles extra o devolver decisiones condicionadas.
En conversaciones técnicas suele mezclarse permiso con política, pero no son exactamente lo mismo.
| Concepto | Qué representa | Ejemplo |
|---|---|---|
| Permiso | Capacidad concreta asignada o derivada | Puede editar usuarios |
| Política | Regla o conjunto de reglas que gobiernan la decisión | Solo puede editar usuarios de su propio tenant y no superadministradores |
En términos simples, el permiso suele ser una unidad más directa; la política es la lógica que determina cuándo, cómo y bajo qué condiciones ese permiso aplica.
Una decisión de autorización madura casi siempre puede descomponerse en cuatro partes:
Este esquema evita pensar la autorización de manera vaga. En lugar de preguntar “¿este usuario es admin?”, conviene preguntar “¿este sujeto puede ejecutar esta acción sobre este recurso bajo estas condiciones?”. Esa formulación obliga a diseñar mejor.
Un ejemplo simple de autorización sería: “solo administradores pueden borrar usuarios”. Pero en sistemas reales la regla suele ser más rica. Por ejemplo:
Estos casos muestran por qué la autorización no puede reducirse siempre a un rol aislado. A menudo intervienen relaciones, atributos y límites contextuales.
La autorización está profundamente conectada con la lógica de negocio. No es solo una capa técnica separada del dominio. De hecho, muchas reglas de negocio críticas se expresan como restricciones de acceso.
Por ejemplo, “solo finanzas puede aprobar pagos mayores a cierto umbral” es una regla del negocio, pero al mismo tiempo es una regla de autorización. Lo mismo ocurre con segregación de funciones, permisos por tenant o restricciones por etapa del proceso.
El problema aparece cuando estas reglas se dispersan caóticamente por controladores, pantallas, consultas y servicios sin un modelo claro. Entonces la autorización se vuelve inconsistente y difícil de auditar.
En arquitectura de autorización suele distinguirse entre:
En muchos sistemas pequeños ambas funciones viven juntas. En arquitecturas más maduras o distribuidas, pueden separarse: una API gateway, un middleware o un servicio consulta políticas definidas en otro componente especializado.
Esta separación puede mejorar consistencia, pero también exige buen diseño para no perder contexto ni introducir latencia o ambigüedad.
Otro punto importante es cuándo se aplica la decisión. Algunas veces el sistema decide antes de ejecutar cualquier operación. Otras, primero obtiene un conjunto de datos y luego filtra lo visible.
Ambos enfoques existen, pero deben usarse con cuidado. Si el filtrado posterior se implementa mal, pueden aparecer fugas por errores de consulta, respuestas parciales, caches o endpoints alternativos. En general, cuanto antes se incorpore la restricción al flujo real del recurso, más confiable será el control.
No toda autorización opera en el mismo nivel. Hay al menos dos planos muy comunes:
Muchas vulnerabilidades aparecen cuando una aplicación protege bien la función general, pero falla en el nivel de objeto. Por ejemplo, un usuario autenticado puede acceder al endpoint correcto, pero manipulando un ID termina viendo datos ajenos. Esto conecta con problemas como IDOR y acceso horizontal indebido.
Algunas capacidades se asignan de forma explícita. Otras se derivan de rol, grupo, relación o atributos del sujeto. También pueden surgir de estados temporales o de políticas contextuales.
Por ejemplo:
Entender esta diferencia es importante para modelar cambios. Los permisos explícitos son precisos pero difíciles de escalar. Los derivados son más mantenibles, pero requieren mayor claridad en reglas y fuentes de datos.
Uno de los principios más importantes en autorización es el de deny by default. Si el sistema no puede establecer con claridad que una acción está permitida, debería denegarla.
Este principio reduce el riesgo de accesos inesperados por omisión, rutas nuevas no protegidas o reglas incompletas. En cambio, los diseños permisivos por defecto suelen romperse con facilidad cuando el sistema crece o cambia.
Un diseño demasiado amplio vuelve inseguro el sistema. Uno excesivamente granular puede volverlo inmanejable. El desafío está en encontrar una granularidad útil: suficientemente precisa para controlar riesgos, pero no tan fragmentada que nadie pueda entender ni operar el modelo.
La granularidad razonable depende del dominio. En algunos casos basta con lectura, escritura y administración. En otros hacen falta distinciones como aprobar, publicar, delegar, ver parcialmente o exportar.
En APIs la autorización suele exponerse de forma más explícita porque cada endpoint representa operaciones concretas. Sin embargo, eso no simplifica automáticamente el problema. De hecho, muchas APIs fallan porque confunden token válido con acción permitida.
Una API madura debería verificar:
Si alguno de estos pasos falta, la API puede habilitar accesos laterales, verticales o entre clientes distintos.
La interfaz también participa, pero no debe ser el único punto de control. Ocultar botones o menús según el rol puede mejorar experiencia y reducir errores, pero no constituye una decisión de seguridad suficiente.
El backend o el recurso real debe validar siempre. Si una acción se protege solo en frontend, un usuario con conocimientos mínimos puede invocar directamente el endpoint o manipular la solicitud.
Las decisiones de autorización no deberían quedar invisibles. Cuando una operación es crítica, conviene registrar qué identidad actuó, sobre qué recurso, qué política se aplicó y si la decisión fue permitir o denegar.
Esta trazabilidad es valiosa para:
No siempre es necesario loguear cada detalle de forma exhaustiva, pero sí debe existir suficiente contexto en operaciones de alto impacto.
Todo lo visto hasta aquí prepara el terreno para los modelos concretos que estudiaremos en el tema siguiente. RBAC, ABAC, DAC, MAC y otras variantes no son más que formas distintas de estructurar y automatizar las decisiones que ya describimos: quién puede hacer qué, sobre qué, bajo qué condiciones.
Si se entiende bien la base, luego resulta mucho más fácil evaluar qué modelo encaja mejor con cada sistema.
La autorización es el punto donde la identidad se convierte en capacidad operativa real. Si esta capa está mal diseñada, un sistema autenticado puede seguir siendo inseguro. Si está bien resuelta, las reglas de acceso se vuelven más claras, auditables y consistentes con el negocio.
En el próximo tema analizaremos los principales modelos de control de acceso: DAC, MAC, RBAC, ABAC y ReBAC, comparando sus fortalezas, límites y escenarios de uso.