Hoy en día, teniendo en cuenta la creciente importancia de arquitecturas zero-trust que se basan en el principio de que nadie puede ser considerado de confianza y que se debe verificar siempre, la importancia de asegurar que los permisos concedidos son los mínimos necesarios cobra aún más importancia.

Además, la necesidad de cumplir con estándares de seguridad y conformidad son temas obligatorios a abordar en cualquier arquitectura, y la autorización es una parte crucial de cualquier solución, teniendo en cuenta que el principal riesgo de OWASP en 2021 fue el control de acceso roto.

Nos hemos inspirado en un post en Medium donde se propone un framework de Autenticación y Autorización utilizando Keycloak y OpenFGA, hemos tomado ese ejemplo y hemos implementado una PoC interna para comprobar su funcionamiento en un entorno real, utilizando infraestructura de cloud pública.

En este post exploraremos el modelo de autorización ReBAC (Relationship-based Access Control) y sus características y, en el próximo, veremos un ejemplo de implementación utilizando la herramienta open source OpenFGA junto con Keycloak.

Conceptos básicos

Autenticación y autorización

Durante el diseño de cualquier tipo de aplicación web, es fundamental asegurar que los usuarios/as y sistemas puedan acceder únicamente a la información y recursos a los que están autorizados. Aquí es donde entran en juego los conceptos de autenticación y autorización.

  • Autenticación. Cuando el usuario/a ingresa sus credenciales para acceder a un sitio web, se ejecuta el proceso de autenticación. Este proceso tiene como objetivo comprobar que el usuario/a es quien dice ser. Para lograrlo se utilizan uno o más factores de autenticación como pueden ser contraseña, PIN, TOTP (time based one time password).
  • Autorización. Una vez autenticado el usuario/a, se determina a qué recursos o datos puede acceder. Por ejemplo, después de ingresar a su cuenta bancaria en línea, la autorización decide si puede transferir dinero o solo ver el saldo de su cuenta. Los detalles del proceso varían según la implementación, pero básicamente consiste en realizar una consulta a un servicio de autorización enviando el identificador del usuario/a, y se obtiene una respuesta indicando si el user cuenta o no con permisos para realizar esa operación.

OpenID Connect (OIDC)

OpenID Connect (OIDC) es un protocolo de autenticación construido como extensión del protocolo OAuth 2.0, permitiendo a los desarrolladores/as verificar la identidad de los usuarios/as y obtener información básica de perfil de una manera sencilla y estandarizada. Una vez autenticado un user, OIDC devuelve tokens de ID en formato JWT (JSON Web Tokens) que contienen información sobre la persona autenticada.

Un ejemplo básico sería el registro en una aplicación web mediante una cuenta de Google. OpenID Connect permite utilizar la cuenta existente para registrarse sin necesidad de crear y recordar una nueva contraseña específica para esta aplicación. Google actúa como proveedor de identidad, enviando la información del user a la aplicación.

OAuth 2.0

Se trata de un protocolo de autorización que permite a las aplicaciones obtener acceso limitado a recursos en un servidor en nombre del usuario/a, sin compartir sus credenciales directamente. Este protocolo es ampliamente utilizado para permitir que terceros accedan a recursos protegidos, como cuentas de usuario, sin comprometer la seguridad.

OAuth 2.0 utiliza tokens de acceso para encapsular la información de autorización. En muchos casos se utiliza JWT como estándar para simplificar la integración de flujos de autenticación y autorización.

Componentes:

  • Resource owner (propietario del recurso). Es el usuario/a que tiene control sobre los datos o recursos protegidos.
  • Client (cliente). Es la aplicación que solicita acceso a los recursos del usuario/a. Puede ser una aplicación web, móvil o de escritorio.
  • Authorization server (servidor de autorización). Comprueba los permisos del usuario/a autenticado/a y devuelve un token de acceso.
  • Resource server (servidor de recursos). Es el servidor que contiene los recursos protegidos. Acepta tokens de acceso para conceder acceso a usuarios/as autorizados/as.

Otro aspecto importante de OAuth 2.0 es que el resource owner puede definir un alcance (scope) para limitar el acceso de cada cliente a los recursos. Esto permite, por ejemplo, limitar la información que un tercero puede obtener de una cuenta de Google: únicamente la dirección de correo electrónico y el nombre de usuario/a.

JSON web token (JWT)

Estándar abierto para la creación de tokens de acceso que permiten la transferencia segura de información entre las partes mediante un objeto en formato JSON. Los JWT son compactos, seguros y se pueden firmar digitalmente (usando HMAC o RSA), lo que garantiza la integridad y la autenticidad del token.

Modelos de autorización

Existen varios modelos de autorización que determinan cómo se conceden los permisos a los usuarios/as. Entre los más comunes se encuentran GBAC, RBAC, ABAC y ReBAC.

GBAC (Control de Acceso Basado en Grupos)

El Control de Acceso Basado en Grupos (GBAC) asigna permisos a los user en función de su pertenencia a grupos dentro de una organización. Los grupos se definen según departamentos, equipos, o cualquier otra clasificación relevante, y cada grupo tiene permisos específicos asociados.

Por ejemplo, en una empresa:

  • El grupo “Administradores” puede tener asociados permisos para agregar y eliminar usuarios/as, así como modificar cualquier registro.
  • El grupo “Empleados” puede tener asociados permisos para ver y editar únicamente sus propios registros.
  • Los miembros del grupo heredan los permisos del grupo. Un cambio en los permisos del grupo afecta a todos los miembros.

GBAC permite administrar permisos de forma colectiva a través de los grupos en lugar de asignar permisos individuales a cada user. Además, cuando un user cambia de equipo o departamento, basta con cambiar su grupo para que automáticamente adquiera los nuevos permisos y pierda los anteriores, facilitando así la gestión de accesos de manera eficiente y segura.

RBAC (Control de Acceso Basado en Roles)

El Control de Acceso Basado en Roles (RBAC) asigna permisos a los usuarios/as en función de sus roles dentro de una organización. Los roles son definidos según las responsabilidades y funciones de los usuarios/as, y cada rol tiene permisos específicos asociados.

Por ejemplo, en una empresa:

  • Un user con el rol "Administrador/a" puede tener permisos para agregar y eliminar usuarios/as, o de modificar cualquier registro.
  • Un user con el rol "Empleado/a" puede tener permisos para ver y editar únicamente sus propios registros y no puede agregar o eliminar usuarios/as.
  • Los roles son asociados a cada user de forma individual, y un user puede tener X roles asociados.

Este modelo simplifica la administración de permisos, ya que se pueden manejar de forma colectiva a través de los roles en lugar de asignar permisos individuales a cada user. En sistemas modernos, es posible asignar roles de forma dinámica, por un periodo de tiempo específico o únicamente si se cumplen algunas condiciones.

ABAC (Control de Acceso Basado en Atributos)

El Control de Acceso Basado en Atributos (ABAC) utiliza atributos de los usuarios/as, recursos y entorno para tomar decisiones de autorización. Los atributos pueden incluir información como el departamento, la clasificación de un documento o la hora del día.

Por ejemplo, una política ABAC podría especificar:

  • Los empleados/as del departamento de ventas pueden acceder a los informes de ventas durante las horas laborales.
  • Los documentos clasificados como "confidenciales" solo pueden ser accedidos por usuarios/as con el atributo de "nivel de seguridad alto".

ABAC ofrece una mayor flexibilidad y granularidad en el control de acceso, permitiendo políticas muy específicas y dinámicas.

ReBAC (Control de Acceso Basado en Relaciones)

El Control de Acceso Basado en Relaciones (ReBAC) permite tomar decisiones de autorización en función de las relaciones entre los usuarios/as y los recursos. Este modelo es particularmente útil en entornos donde las relaciones entre las entidades son complejas y dinámicas.

En este tipo de modelos se identifican los siguientes componentes:

  • Usuarios/as: users del sistema identificados de forma única.
  • Recursos: cualquier objeto que deba ser protegido, como por ejemplo: ficheros, directorios, registros, etc.
  • Relaciones: una asociación directa o indirecta entre users, roles o grupos y uno o más recursos.

Por ejemplo, en una empresa:

  • Un user que tiene la relación de “Propietario/a” con un “Proyecto” puede tener permisos para ver y modificar todos los registros relacionados con ese proyecto.
  • Un user que tiene la relación de “Colaborador/a” con un “Proyecto” puede tener permisos para ver y editar únicamente los registros que ellos mismos crearon dentro de ese proyecto.

Este modelo ofrece una gran flexibilidad y granularidad en la administración de permisos, ya que los accesos se pueden definir de manera muy específica en función de las relaciones dinámicas y contextuales entre los usuarios/as y los recursos. Esto permite adaptar los permisos de manera precisa a la estructura organizativa y a los cambios en las relaciones, como cuando un usuario/a asume una nueva posición o responsabilidad dentro de un proyecto.

Keycloak y OpenFGA

En el ámbito de la gestión de autenticación y autorización, existen distintas herramientas que facilitan la implementación, administración e integración de estos procesos en aplicaciones y servicios. En esta entrada, utilizaremos Keycloak y OpenFGA.

Keycloak

Es una solución de código abierto para la gestión de identidad y acceso (IAM). Proporciona autenticación y autorización a aplicaciones y servicios, eliminando la necesidad de gestionar manualmente users y permisos.

Características principales de Keycloak:

  1. Autenticación: Keycloak soporta múltiples métodos de autenticación, incluyendo contraseñas, autenticación de dos factores (2FA), y proveedores de identidad externos como Google, Facebook y más.
  2. Single Sign-On (SSO): permite a los usuarios/as autenticarse una sola vez para acceder a múltiples aplicaciones, mejorando la experiencia de usuario y la seguridad.
  3. Gestión de usuarios: ofrece una interfaz administrativa para gestionar users, roles, y permisos, así como funciones de auto-registro y recuperación de contraseña.
  4. Autorización: soporta RBAC, GBAC y políticas de autorización basadas en atributos (ABAC), permitiendo una gestión detallada de los permisos.
  5. Integración: se integra fácilmente con aplicaciones a través de adaptadores para diversas plataformas y protocolos como OAuth2, OpenID Connect y SAML.

OpenFGA

OpenFGA (Open Fine-Grained Authorization) es una plataforma de autorización de código abierto diseñada para manejar permisos granulares y complejos. Su desarrollo se ha inspirado en Zanzibar, el sistema de autorización interno de Google. Es especialmente adecuada para implementar modelos como ReBAC, permitiendo una gestión detallada y dinámica de las relaciones y permisos.

Características principales de OpenFGA:

  1. Modelo relacional de autorización: facilita la implementación de ReBAC, permitiendo definir permisos basados en las relaciones entre users y recursos.
  2. Flexibilidad y escalabilidad: diseñado para manejar casos de uso complejos y escalables, adecuado para aplicaciones con necesidades de autorización sofisticadas.
  3. Lenguaje de políticas: utiliza un lenguaje de políticas expresivo que permite definir reglas de acceso detalladas y dinámicas.
  4. Integración con IAM: puede integrarse con sistemas de gestión de identidad y acceso existentes, complementando su funcionalidad.
  5. API REST y gRPC: proporciona una API REST y gRPC que facilita la integración con diversas aplicaciones y servicios.

Conceptos básicos

Es necesario entender ciertos conceptos básicos de OpenFGA para una mejor comprensión del escenario propuesto en este ejemplo.

  • Store (almacén): entidad que permite agrupar modelos de autorización y tuplas de relación.
  • Authorization model (modelo de autorización): es la estructura básica que permite definir permisos, combina usuarios, objetos y relaciones.
  • User (usuario): una entidad en el sistema que puede tener una o más relaciones con un objeto.
  • Object (objeto): representa un recurso protegido por el modelo de autorización.
  • Relation (relación): un componente que permite definir la posibilidad de una relación entre un objeto y un user.
  • Relationship tuple (tupla de relación): una representación de un permiso, contiene un user, una relación y un objeto definidos en el modelo de autorización. Opcionalmente, pueden incluir una condición.
  • Condition (condición): función compuesta por uno o más parámetros y una expresión. Para su definición se utiliza el lenguaje CEL desarrollado por Google.
  • Check request (petición de comprobación): una llamada a la API de OpenFGA para comprobar si un user mantiene cierta relación con un objeto.

En la documentación oficial existen varios ejemplos de modelos de autorización posibles.

Conclusiones

En este post hemos cubierto conceptos básicos para entender los procesos de autenticación y autorización, así como una descripción de las herramientas Keycloak y OpenFGA. En el siguiente veremos un ejemplo de implementación del modelo ReBAC.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.