Diseño de autorización adaptada a la configuración regional en Webflow

Cómo creamos el acceso por idioma para que los equipos puedan editar contenido regional de forma segura.

Diseño de autorización adaptada a la configuración regional en Webflow

Alastair Purvis
Ingeniero de software principal
Ver perfil del autor
Alastair Purvis
Ingeniero de software principal
Ver perfil del autor
Índice de contenidos

La mayoría de los sistemas de autorización se reducen a una pregunta: ¿puede este usuario realizar esta acción en este recurso? Eso funciona hasta que surge un nuevo eje de restricción que debe integrarse con todas las políticas existentes. Para nosotros, ese eje fue el idioma.

Cuando lanzamos el acceso por idioma, el objetivo del producto era claro: permitir que un administrador asigne un traductor de español a contenido regional sin arriesgar cambios en el sitio en inglés. Nuestro modelo de autorización existente manejaba bien las páginas y las colecciones del CMS, pero el idioma no podía modelarse como un recurso más. Implementarlo requirió cuatro cambios de diseño.

De recursos a dimensiones

La mayoría de los sistemas de autorización deniegan el acceso por defecto y lo conceden explícitamente. El de Webflow funciona al revés: el acceso es abierto por defecto y los administradores establecen las restricciones. El idioma fue más difícil de encajar en ese modelo porque, en un sistema abierto por defecto, la falta de contexto omite la restricción sin avisar.

El control de acceso basado en recursos funciona bien porque se aplica a un objeto concreto: una página, una colección, un sitio. Ese objeto tiene un ID, puede enumerarse y puede llevar consigo un dato permanente como «este usuario tiene restringido el acceso a la página XYZ». Cuando verificas el acceso, el objeto que se autoriza es también el objeto que se restringe.

Una dimensión se sitúa junto al recurso y califica el acceso al mismo. Los sistemas basados en atributos pueden expresar esto, pero la mayoría trata los atributos que no son recursos como filtros generales en lugar de restricciones que se integran con la política del recurso. Cuando un diseñador edita la variante en español de una página, la página sigue siendo el objeto que se edita, mientras que el idioma proporciona el contexto para esa acción. El idioma puede aparecer como un objeto de primer nivel en otras partes del sistema, como al listar a qué idiomas puede acceder un usuario, pero la mayoría de las comprobaciones de autorización lo tratan como contexto de la solicitud.

A side-by-side comparison of the resource model (one allow/deny fact per page) versus the dimension model (a matrix of allow/deny cells for each page × locale combination).
El modelo de recursos almacena un dato por recurso. El modelo de dimensiones crea una matriz: el mismo recurso, al que se accede a través de diferentes contextos.

Esa distinción cambia la forma del sistema. Afecta a cómo almacenas los datos de autorización, cómo compones las comprobaciones y cómo manejas las operaciones que abarcan toda la dimensión.

Cambio 1: Es mejor calcular el contexto que persistirlo

Lo primero que cambia es la persistencia. En un modelo de recursos, almacenas un dato de restricción directamente en el elemento restringido: una página, un dato. Una vez que el idioma entra en juego, la versión más simple es una relación para cada par de página-idioma en cada sitio.

Un sitio con 200 páginas y 15 idiomas requeriría 3000 datos de relación solo para representar el estado actual. Cada página nueva significa 15 datos nuevos, y cada idioma nuevo significa 200 datos nuevos. El coste de almacenamiento crece de forma multiplicativa.

La distinción crucial fue esta: los datos de recursos y los datos de dimensiones son tipos de información diferentes. Los datos de recursos deben ser permanentes porque describen el sistema, pero los datos de idioma describen la solicitud, lo que los hace seguros para calcular en lugar de almacenar.

Lo solucionamos haciendo que el contexto del idioma fuera efímero: inyectarlo en el momento de la solicitud, evaluarlo durante el proceso y luego descartarlo.

The naive approach stores 3,000 facts for 200 pages × 15 locales. The context-fact approach reduces this to a single ephemeral fact injected per request.
Almacenar N×M datos crece con cada página e idioma. Los datos de contexto reducen esto a exactamente un dato efímero por solicitud.

Cambio 2: Dos ejes de restricción deben integrarse en una sola comprobación

Con los recursos, la autorización es unidimensional: ¿puede este usuario acceder a esta página? Si añades una dimensión, la pregunta se vuelve compuesta: ¿puede este usuario acceder a esta página en este idioma?

Eso introduce una relación de anulación que el modelo de recursos nunca tuvo que manejar. Un usuario que puede editar una página pero tiene restringido el español, aun así debe ser bloqueado para que no edite la variante en español.

El enfoque directo consiste en dos llamadas de política separadas: una para la página y otra para el idioma. Pero eso falla en cuanto la política depende de cómo interactúan ambas. Un rol que otorga acceso a todo el idioma podría anular una restricción de página. Dividida en dos llamadas, esa lógica no tiene dónde residir. Para preservar esa semántica, ambos ejes deben evaluarse en una única decisión de política.

Implementamos esto con una regla de política componible en Oso Cloud, nuestro motor de autorización, que se aplica a todos los tipos de recursos.

Flowchart of a single authorize() call evaluating page access and locale access in sequence. Either axis can deny the request; when no locale context is present, the locale check is skipped.
Dos ejes de restricción evaluados en una sola llamada. Si la comprobación de la página es correcta pero la de la configuración regional falla, se deniega el acceso al usuario. Cuando no hay un contexto de configuración regional, esta comprobación se omite silenciosamente.

Cuando no hay una configuración regional en la solicitud, la regla se aprueba incondicionalmente, por lo que la autorización existente no cambia. Una única llamada a authorize() evalúa ambos ejes y, dado que el contexto de la configuración regional se inyecta en lugar de almacenarse, la comprobación se mantiene en tiempo constante.

Cambio 3: Las operaciones que abarcan todas las configuraciones regionales requieren un tipo de comprobación diferente

Las operaciones de una sola configuración regional son sencillas: se comprueba la configuración regional y luego se permite o se deniega. Pero algunas operaciones abarcan todas las configuraciones regionales. Eliminar una página borra todas sus variantes regionales. Si a un usuario se le restringe el acceso al español, permitirle eliminar la página incumple esa promesa.

Aquí es donde la autorización basada en relaciones empieza a flaquear bajo un modelo basado en restricciones. Los sistemas de este tipo suelen estar optimizados para comprobaciones de existencia: ¿existe esta relación? Pero las operaciones que abarcan todas las configuraciones regionales requieren lo contrario: verificar que no exista ninguna configuración regional restringida en el conjunto. Se trata de un tipo de consulta diferente que escala con el tamaño del conjunto en lugar de resolverse en tiempo constante.

Cada enfoque obvio tenía un coste. Las consultas directas de hechos omiten la evaluación de políticas, por lo que las concesiones basadas en roles desaparecen. Los hechos agregados derivados crean riesgos de sincronización. La negación en el lenguaje de políticas requiere enumerar todo el conjunto de configuraciones regionales de antemano, lo que traslada la complejidad a subconsultas correlacionadas y rincones indocumentados del lenguaje de políticas.

Decidimos invertir la pregunta: en lugar de preguntar si el usuario tiene alguna restricción, preguntamos qué configuraciones regionales puede editar mediante una consulta evaluada por políticas, y luego comprobamos si ese conjunto está completo. Esto preserva la semántica de autorización, evita la negación y limita la lógica del lado de la aplicación a la aritmética de conjuntos.

A three-row table comparing approaches to cross-locale authorization. Direct fact queries, policy negation, and derived aggregate facts each introduce a distinct failure mode; inverting the question avoids all three.
Cada alternativa a invertir la pregunta conlleva al menos uno de estos compromisos. El enfoque invertido evita los tres.

Cambio 4: La autorización debe ser implícita, no opcional

En Webflow, tenemos miles de puntos finales y componentes. Cuando la autorización depende del contexto de la solicitud, como la configuración regional, cada llamador debe pasar ese contexto correctamente. Hacerlo manualmente es lento, frágil y fácil de pasar por alto. Tanto en el frontend como en el backend, la respuesta fue la misma: hacer que la aplicación sea estructural, no opcional.

En el frontend, eso significó reutilizar lo que ya teníamos. Nuestro sistema de restricción de páginas y colecciones ya componía capacidades de alto nivel como "puede editar el contenido de la página" y "puede eliminar la colección". Integramos las comprobaciones de configuración regional en esas mismas capacidades, de modo que los componentes secundarios heredaron las restricciones regionales automáticamente, sin cambios en el código.

El resultado es que los consumidores no necesitan saber nada sobre la configuración regional para aplicarla correctamente.

Two new locale abilities compose into existing high-level abilities (canEditStaticPageContent, canDeletePage, canMergeBranch), which already gate downstream UI components No code changes required in those components.
Las nuevas capacidades de configuración regional se integran en las existentes. Los componentes secundarios heredan las restricciones sin necesidad de cambiar el código.

En el backend, teníamos un problema similar: los hechos de contexto debían generarse de forma fiable en cada punto de entrada. En lugar de dispersar la lógica de resolución de la configuración regional en cientos de puntos finales, la centralizamos en un registro de resolución de relaciones.

Cada resolvedor declara una relación y cómo extraer hechos del contexto de la solicitud; un generador de hechos recorre el gráfico y produce los hechos que necesita el servicio de autorización.

The FactGenerator walks a relationship graph starting from the authorized resource (SitePage), following edges to SiteLocale, Site, and Workspace to produce has_relation context facts for the authorization service.
El FactGenerator recorre el gráfico de relaciones comenzando desde el recurso autorizado. Cada borde es resuelto por un resolvedor registrado, produciendo hechos has_relation para el servicio de autorización.

Esto también cerró un modo de fallo sutil: si un punto final llama al autorizador sin contexto de configuración regional, la comprobación de la configuración regional se omite y la restricción se elude. Al hacer que la generación de contexto sea automática, el registro elimina ese paso manual por completo.

Más allá de la configuración regional

Aunque los sistemas de Control de Acceso Basado en Atributos (ABAC) pueden expresar composición dimensional, la mayoría de las implementaciones no facilitan su aplicación en todas las superficies, especialmente en un sistema abierto por defecto. Creamos el acceso específico por configuración regional para resolver eso, pero lo que más nos sorprendió fue cuánto se generalizó la solución. Las piezas que construimos para la configuración regional, como la composición ortogonal y la generación automática de hechos, no dependen de la configuración regional en sí. La siguiente dimensión puede conectarse al mismo registro, a la misma estructura de políticas y al mismo modelo de composición.

Si te encuentras con problemas similares, la verdadera prueba no es si tu lenguaje de políticas puede expresar el nuevo eje, sino si un nuevo punto final puede equivocarse silenciosamente.

¡Estamos contratando!

Buscamos talento en producto e ingeniería para que se una a nuestra misión de poner superpoderes de desarrollo al alcance de todos.

→
↗
►
↓
←
↑
Leer ahora

Última actualización
April 16, 2026
Categoría

Artículos relacionados


verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo
verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo

Empieza gratis

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.

Empieza, es gratis
Ver demostración

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.