¿Cómo mantener el control de acceso bajo control cuando tu arquitectura crece en microservicios, roles y recursos? Este enfoque declarativo te ayuda a definir reglas legibles, seguras y escalables, sin caer en la complejidad ni perder el gobierno.
En el desarrollo de sistemas distribuidos basados en microservicios, uno de los mayores retos técnicos y de gobernanza es establecer un modelo de control de acceso que sea:
- Centralizado, pero no invasivo
- Flexible, pero seguro por defecto
- Expresivo, pero fácil de mantener
- Y sobre todo, escalable, sin volverse una pesadilla al crecer el número de recursos, roles y reglas
En este artículo te presento un enfoque declarativo para la definición de permisos en un ecosistema de microservicios, inspirado en ideas de RBAC, pero diseñado para ser portable, semántico y extrapolable.
🎯 Objetivo
Construir un sistema de autorización que permita:
- Definir permisos a nivel de acciones y atributos por recurso
- Asociarlos a roles con posibles relaciones de herencia
- Evaluar condiciones simples (ej.
role == "admin",role in (...)) - Ser consumido por los microservicios de forma eficiente y cacheable
- Evolucionar fácilmente en el tiempo con cambios mínimos
🧱 Estructura conceptual
El modelo se basa en tres conceptos principales:
- Roles: identificadores semánticos (
viewer,editor,admin) que pueden heredar de otros roles. - Recursos: entidades lógicas del sistema (
tenant,invoice,user) que tienen acciones (read,update, ...) y atributos (name,secretKey, ...). - Reglas de acceso: expresadas en un DSL (lenguaje específico de dominio) muy legible y conciso, con soporte para condiciones básicas.
✍️ Ejemplo de reglas declaradas
role editor extends viewer;
role admin extends editor;
resource tenant:author extends tenant;
match tenant {
actions {
allow read, list if role in ("admin", "editor");
allow update, delete if role == "admin";
}
attributes {
allow name, description if role in ("admin", "editor");
deny secretKey if role != "admin";
}
}
match tenant:author {
actions {
allow update if role == "admin" or user.id == resource.authorId;
}
}
🧠 Consideraciones de diseño
1. Política de evaluación conservadora
Se aplica una estrategia deny-by-default y deny-prevalece-sobre-allow, con las siguientes reglas:
- Si no hay ninguna regla que coincida con una acción o campo → se deniega el acceso.
- Si alguna regla coincidente dice
deny→ se deniega, aunque otras diganallow. - Solo si todas las reglas coincidentes dicen
allow→ se permite.
2. Herencia estructural opcional
La herencia de roles y recursos se define explícitamente:
role admin extends editor;
resource invoice:summary extends invoice;
Esto permite un modelo de seguridad evolutivo, donde roles más generales pueden delegar permisos en roles más especializados, o recursos secundarios heredan comportamientos por defecto.
⚙️ Aplicación en un sistema de microservicios
🔄 Flujo de integración:
- Cada microservicio registra sus recursos (acciones, atributos) durante el arranque.
- El servicio IAM central mantiene el conjunto completo de reglas de acceso.
- Las reglas se evalúan y extrapolan para cada combinación de rol y recurso.
- El resultado se convierte en una estructura cacheable, fácilmente consumible vía API o como archivos estáticos por los microservicios.
- Cuando las reglas cambian, los microservicios pueden utilizar
ETagoIf-Modified-Sincepara minimizar el tráfico y evitar recálculos innecesarios.
✅ Ventajas del enfoque
| Ventaja | Descripción |
|---|---|
| 🔒 Seguro por defecto | Las omisiones no abren puertas: sin regla explícita no hay acceso |
| ✨ Legibilidad humana | El DSL es limpio, mantenible y fácil de versionar en Git |
| 📦 Compatible con caché | Los permisos extrapolados pueden entregarse como JSON estático |
| 🧩 Modular y extensible | Puedes añadir condiciones más expresivas, etiquetas, herencia condicional, etc. |
| 🔁 Desacoplado | Los microservicios no necesitan saber cómo se evalúan las reglas |
🧪 Posibles extensiones
- Condiciones más complejas: soporte para
and,or, valores deuser,resourceocontext. - Tags de atributos: por ejemplo, permitir el acceso a todos los campos con
tag:public. - Soporte para scopes OAuth2: mapeo entre permisos y scopes API.
- UI de administración: formularios dinámicos generados a partir del árbol de recursos y reglas.
🚀 Conclusión
Este modelo ofrece un equilibrio ideal entre declaratividad, seguridad y mantenibilidad para entornos distribuidos modernos. A través de una DSL ligera y una política de evaluación coherente, puedes mantener el control de acceso en crecimiento sin perder la visibilidad ni caer en la complejidad.
Si estás construyendo una plataforma orientada a microservicios, adoptar un enfoque así puede ahorrarte meses de trabajo y evitar errores costosos en el futuro.

Comentarios
Publicar un comentario