¿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
ETag
oIf-Modified-Since
para 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
,resource
ocontext
. - 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