Demesne

El motor de autorización sobre el que funciona Fóir. Las reglas de acceso se escriben una vez, en un único archivo de especificación, y Demesne las compila a row-level security de Postgres, de modo que la base de datos las aplica a cada consulta. Lo construimos para Fóir y lo publicamos bajo la licencia Apache 2.0.

Qué hace

Una especificación de Demesne describe cuatro cosas: la forma de tu tenencia, los tipos de usuario y de credencial que actúan, las tablas sobre las que actúan y las relaciones que los conectan, como la propiedad, los roles, el uso compartido y la pertenencia a grupos.

A partir de ese archivo el compilador genera las políticas de row-level security y las funciones de base de datos que esas políticas invocan. También genera un mapa de permisos para Go y TypeScript, para las preguntas que no tratan de filas ("¿puede este usuario publicar?"), y los claims que debe llevar una sesión. Cambia la especificación y regenera, y la base de datos y el código de la aplicación se mueven juntos.

Por qué las reglas viven en la base de datos

La autorización suele estar en el código de la aplicación: un servicio al que llamas, o comprobaciones repartidas entre los controladores de solicitudes. De cualquier forma, solo protege las rutas que se acuerdan de preguntar. Un trabajo en segundo plano, un endpoint nuevo o una consulta escrita en una consola de base de datos la esquivan.

Demesne pone la decisión en los datos. La misma política filtra cada consulta, sea cual sea el código que la envió, así que una ruta que olvida comprobar recibe solo las filas que su autor estaba autorizado a ver.

Por qué escribimos un compilador

La row-level security es el lugar adecuado para una regla y una cosa incómoda de escribir a mano. Un producto multitenant necesita propiedad, roles, grupos anidados y uso compartido, repetidos en cada tabla, y esos patrones son fáciles de equivocar en detalles sutiles.

Los motores que comparten el modelo de Demesne, Zanzibar de Google y los proyectos de código abierto que lo siguen, funcionan como un servicio aparte. Tu aplicación tiene que llamar a ese servicio en cada decisión y mantener su copia de las relaciones sincronizada con tus datos. Queríamos el modelo sin el servicio, así que las reglas de Demesne leen tus tablas existentes en la misma transacción que la consulta.

Cómo se comprueba su salida

La compilación de Demesne compara cada archivo generado byte a byte con una copia confirmada en el repositorio. Cada comprobación de permisos del lado de la aplicación lleva literalmente la condición de la política correspondiente, de modo que el código no puede desviarse de la base de datos sin que falle la compilación. Ejecutada contra un Postgres real, la suite de pruebas instala las funciones generadas y confirma que el SQL coincide con las versiones en Go y TypeScript caso por caso.

Para una base de datos que ya está desplegada, demesne diff informa de cualquier diferencia entre la especificación y las políticas que están activas.

Por qué es de código abierto

El componente que decide quién puede leer tus datos es el que deberías poder inspeccionar. Cualquier plataforma puede decir que sus tenants están aislados. Con Demesne puedes leer el compilador que escribe nuestras políticas, las pruebas que tiene que superar y el SQL que produce, y puedes ejecutarlo todo tú mismo.

Nada en Demesne es específico de Fóir. Funciona con cualquier base de datos Postgres y lee la sesión que emite tu propio proveedor de inicio de sesión, y la guía del repositorio explica cómo adoptarlo sobre un esquema existente. Un equipo sin ningún interés en nuestra plataforma puede usarlo, que es la mejor comprobación que conocemos de si el modelo se sostiene.

Qué significa en Fóir

El modelo de acceso de Fóir es una sola especificación de Demesne, que en el momento de escribir esto gobierna unas cien tablas. Una prueba enumera todas las tablas de nuestro esquema y falla ante cualquiera que se haya añadido sin una decisión registrada sobre cómo está protegida.

Las reglas que defines para tu propio proyecto, como quién es propietario de un registro y qué roles pueden leer un modelo, son datos que esas políticas leen, así que también surten efecto dentro de la base de datos. Aplicado en la base de datos describe cómo se generan, se fuerzan y se prueban las políticas.

Se va contigo

Una exportación de Postgres de tu proyecto incluye políticas de row-level security que reproducen qué filas podía leer cada uno de tus usuarios, listas para que las apliques a la base de datos que ahora es tuya. Si quieres todo el modelo en tu propia infraestructura, el motor está ahí para usarlo bajo una licencia que lo permite.

Dónde es la herramienta equivocada

Demesne es solo para Postgres. Es una biblioteca y una herramienta de línea de comandos, sin ningún servicio alojado al que llamar. Toda regla tiene que poder expresarse como una condición SQL, y las preguntas que van en sentido contrario ("¿quién puede ver este registro?") se responden de forma conservadora. El repositorio incluye una comparación con Zanzibar, Ory Keto, OpenFGA, Cerbos y Oso que indica en qué casos cada uno de ellos es la mejor opción.

Léelo por ti mismo

El lenguaje de la especificación, el SQL generado y la suite de pruebas están en el repositorio.