Control de Acceso Basado en Relaciones (ReBAC): la autorización como grafo
El control de acceso basado en relaciones explicado: derivar los permisos de un grafo de relaciones entre entidades en lugar de roles o atributos sueltos. Cómo responde el ReBAC a '¿estás conectado con este recurso de la forma adecuada?', la tupla de relación y las reescrituras de usersets en el corazón de Google Zanzibar, cómo una comprobación de permiso se convierte en un recorrido de grafo, los problemas de coherencia y rendimiento que tuvo que resolver Zanzibar y el ecosistema que generó: OpenFGA, SpiceDB, Permify y Ory Keto.
“Personas con acceso”
Sara abre el diálogo de compartir de roadmap.md y pulsa “Personas con acceso”. El panel no muestra una lista plana de nombres. Dice que a dos personas se les compartió el documento directamente, que los doce miembros del grupo de Ingeniería pueden editarlo porque Ingeniería edita la carpeta /research en la que está, y que todo el equipo de Producto puede verlo porque Producto puede ver el espacio de trabajo entero que hay por encima. Luego arrastra el documento a otra carpeta y el panel cambia al instante: otras personas, otros motivos, nada copiado. Nadie tocó ningún permiso del propio documento.
Todos los modelos anteriores respondían a la autorización con una propiedad del sujeto o del recurso. El RBAC preguntaba qué rol tienes. El ABAC preguntaba qué atributos tenéis tú y el recurso. El PBAC preguntaba qué dice la política sobre esos atributos. Pero buena parte de las decisiones de acceso que toma el software real no tratan de roles ni de atributos; tratan de relaciones. Puedes editar este documento porque perteneces al equipo dueño de la carpeta en la que está. Puedes ver esta foto porque quien la publicó es tu amigo. Puedes aprobar este gasto porque eres el responsable de quien lo presentó. Ninguna de esas frases nombra un rol ni comprueba un atributo. Cada una traza una conexión desde el sujeto, pasando por otras entidades, hasta el recurso.
El control de acceso basado en relaciones (ReBAC) toma esa observación y la convierte en todo el modelo. El acceso se concede cuando el sujeto está conectado con el recurso a través de una cadena de relaciones permitida. Representa cada relación como una arista de un grafo, Sara es miembro de Ingeniería, Ingeniería es editora de /research, /research es la carpeta padre de roadmap.md, y una pregunta de autorización se convierte en una pregunta de alcanzabilidad: ¿hay un camino permitido desde este sujeto hasta este recurso? Si lo hay, se permite; si no, se deniega. Ese es todo el núcleo conceptual, y su elegancia explica que hoy sostenga la autorización de algunas de las mayores empresas de software del mundo. Es también justo lo que le está enseñando a Sara su diálogo de compartir.
El problema de autorización de Google
La idea es anterior a su fama. El trabajo académico sobre el control de acceso basado en relaciones se remonta a finales de los 2000, pensado para las redes sociales, donde “amigo de un amigo” es literalmente un camino en un grafo. El modelo se convirtió en una fuerza del sector en 2019, cuando Google publicó un artículo que describía Zanzibar, su sistema interno de autorización global. Google tenía un problema concreto: decenas de productos, Drive, Docs, Calendar, YouTube, Photos, Cloud, tenían que responder a “¿puede este usuario hacer esto con este objeto?”, los objetos se contaban por billones, las comprobaciones llegaban a millones por segundo y una respuesta equivocada significaba o una funcionalidad rota o una brecha de privacidad en los titulares. Habían empezado con un sistema de autorización por producto, y eso no escalaba, ni en lo organizativo ni en lo técnico.
La idea de Zanzibar fue convertir la autorización en un único servicio uniforme, basado en relaciones, que todos los productos pudieran compartir. Modelar cada permiso como una tupla de relación, guardarlas en una base de datos a escala planetaria y exponer una API pequeña, sobre todo una llamada Check que pregunta si se cumple una relación, a la que cualquier producto pudiera llamar. El artículo demostró que el ReBAC funciona a una escala extrema y publicó las respuestas de ingeniería a los problemas difíciles que crea esa escala, la coherencia y el rendimiento, a los que llegaremos. En pocos años había inspirado a toda una generación de motores de código abierto y comerciales que llevaron el mismo modelo a todos los demás.
La unidad básica: la tupla de relación
Todo en el ReBAC se construye a partir de un hecho diminuto y uniforme, la tupla de relación. Su forma es mínima a propósito:
⟨objeto⟩#⟨relación⟩@⟨sujeto⟩Léela de derecha a izquierda como una frase: este sujeto tiene esta relación con este objeto. Unas cuantas tuplas describen la situación de Sara:
document:roadmap#editor@user:sara // Sara es editora del documento roadmap
folder:research#parent@document:roadmap // roadmap está en la carpeta research
folder:research#editor@user:sara // Sara es editora de la carpeta research
group:eng#member@user:daniel // Daniel es miembro del grupo de ingenieríaCada tupla es una arista independiente del grafo de autorización. No hay un modelo de objetos pesado ni una tabla de permisos por aplicación, solo un flujo uniforme de pequeños hechos. Esa uniformidad es la clave: como todos los permisos de todos los productos son el mismo tipo de tupla, un solo motor puede guardar y evaluar la autorización de todos ellos. Conceder acceso es escribir una tupla; revocarlo es borrar una. El conjunto completo de tuplas es el grafo que recorre el motor para responder cualquier pregunta.
Conviene separar dos cosas. Las tuplas son los datos en tiempo de ejecución, quién está relacionado con qué, y cambian sin parar a medida que la gente comparte, entra en equipos y mueve ficheros. El modelo de autorización, que Zanzibar llamaba configuración de espacio de nombres y OpenFGA llama modelo de autorización, es el esquema. Declara los tipos de objeto, las relaciones de cada tipo y las reglas de reescritura que calculan unas relaciones a partir de otras. Los datos dicen que Sara es editora de este documento. El modelo dice que cualquiera que sea editor es también lector, y que cualquiera que pueda ver la carpeta padre puede ver el documento. El poder de verdad del ReBAC vive en esa segunda parte.
Usersets y reescrituras: donde está el poder
Si las tuplas solo pudieran decir objeto#relación@user:alguien, el ReBAC sería poco más que una lista de control de acceso distribuida, expresiva pero plana. El salto llega con dos funciones que permiten calcular las relaciones y no solo guardarlas.
La primera es el userset: el sujeto de una tupla puede ser a su vez un conjunto de usuarios definido por otra relación, no solo un usuario. Escribir folder:research#editor@group:eng#member dice que los editores de la carpeta research incluyen a todos los miembros del grupo de ingeniería. Añadir a Daniel a group:eng#member lo convierte entonces, sin ruido, en editor de la carpeta, sin tocar las tuplas de la carpeta. Es la indirección de grupos que nos dio el RBAC, generalizada: cualquier relación puede apuntar al conjunto de sujetos de otra, así que grupos, equipos y pertenencias anidadas salen todos de la misma pieza.
La segunda es la regla de reescritura, declarada en el modelo y no en los datos, que define una relación a partir de otras. Dominan dos patrones. Una unión, “un lector es cualquiera que sea lector directo o editor”, expresa jerarquías de permisos, porque un editor evidentemente puede leer, sin duplicar tuplas. El tuple-to-userset, la joya de la corona, “los lectores de un documento incluyen a los lectores de su carpeta padre”, expresa la herencia: defines la lectura una vez en las carpetas y cada documento de dentro la hereda a través de la arista parent. Ese único mecanismo es como el ReBAC expresa la herencia del árbol de carpetas que necesita cualquier producto para compartir ficheros y que el RBAC y el ABAC manejan con torpeza.
Juntos, un modelo compacto y un puñado de tuplas expresan reglas que en otros modelos necesitarían enormes tablas de roles o políticas ABAC enrevesadas. Sara puede ver roadmap.md porque es editora de la carpeta, los editores son lectores y el documento hereda sus lectores de esa carpeta. Ninguna tupla dijo nunca “Sara puede ver roadmap.md”; el motor lo dedujo siguiendo aristas. Esa deducción es la esencia del ReBAC.
Una comprobación es un recorrido del grafo
Como los permisos son aristas y los permisos derivados son reglas de reescritura, responder a la pregunta central, Check(document:roadmap, viewer, user:sara), “¿puede Sara ver la hoja de ruta?”, es una búsqueda en el grafo. El motor empieza en la pareja de objeto y relación pedida y la expande según el modelo hasta encontrar al sujeto o quedarse sin grafo alcanzable:
Check(document:roadmap, viewer, sara)?
viewer(roadmap) = lectores directos de roadmap
∪ editores de roadmap (unión: editor implica lector)
∪ lectores del padre de roadmap (tuple-to-userset: hereda de la carpeta)
→ sigue la arista parent: folder:research
→ viewer(research) ⊇ editor(research) ∋ sara (Sara es editora de la carpeta)
→ PERMITIRflowchart TD accTitle: Resolver una comprobación de permiso ReBAC como un recorrido recursivo del grafo accDescr: La evaluación empieza en un nodo que pregunta si Sara es lectora del documento roadmap. Se expande en tres ramas según el modelo de autorización. La primera rama comprueba los lectores directos del documento y no encuentra ninguno. La segunda es una reescritura de unión que incluye a los editores del documento, tampoco ninguno directamente. La tercera es una reescritura tuple-to-userset que sigue la arista padre del documento hasta la carpeta research y pregunta si Sara es lectora de esa carpeta. Eso se expande a si Sara es editora de la carpeta, lo que confirma una tupla guardada. Como se encuentra un camino hasta Sara, el resultado global es permitir. Si ninguna rama hubiera llegado a Sara, el resultado sería denegar. Q["Check: ¿viewer de document:roadmap = user:sara?"] --> D["Lectores directos de roadmap"] Q --> E["Unión: editores de roadmap<br/>(editor implica lector)"] Q --> P["Tuple-to-userset:<br/>sigue la arista parent"] D --> DN["ninguno"] E --> EN["ninguno directo"] P --> F["¿lectora de folder:research?"] F --> FE["¿editora de folder:research?"] FE --> T["tupla:<br/>folder:research<br/>#editor @user:sara ✓"] T --> Y["PERMITIR, hay camino hasta Sara"] DN -.-> Y EN -.-> Y
Este recorrido es lo que permite al ReBAC responder a una pregunta que a los otros modelos les resulta realmente difícil: ¿quién tiene acceso a este objeto concreto? En RBAC enumerarías todos los roles que conceden el permiso y todos los usuarios de esos roles; en ABAC evaluarías la política contra cada usuario, el problema de la consulta inversa. En ReBAC, “¿quién puede ver roadmap.md?” es el recorrido hecho al revés: expandir la relación viewer del objeto y recoger todos los sujetos a los que llega el grafo. Esa búsqueda inversa, que Zanzibar llama Expand y otros llaman consulta de “listar objetos” o “listar usuarios”, es una operación de primera clase, y por eso los motores ReBAC son el respaldo natural de los diálogos de compartir y de los paneles de “personas con acceso” como el de Sara.
Cómo se compara el ReBAC con los modelos anteriores
Los modelos se complementan, y cada uno responde mejor a una pregunta distinta.
| Modelo | Pregunta central | De dónde salen los permisos | Encaja con | Punto débil |
|---|---|---|---|---|
| RBAC | ¿Qué rol tienes? | Asignaciones de roles | Funciones de puesto estables | Compartir por objeto, herencia |
| ABAC | ¿Qué atributos aplican? | Atributos de sujeto, recurso y entorno | Reglas de contexto y de grano fino | Consultas de “¿quién accede a X?” |
| PBAC | ¿Qué dice la política? | Política formal externalizada | Coherencia entre muchas apps | (Un vehículo, no una base de decisión) |
| ReBAC | ¿Cómo estás conectado? | Aristas de un grafo de relaciones | Colaboración, jerarquía, compartir | Condiciones de hora, riesgo, importe |
Lo que mejor encaja con el ReBAC, la colaboración, la jerarquía y compartir, es justo donde el RBAC y el ABAC son más débiles, porque esos casos tratan de objetos concretos relacionados con sujetos concretos, no de roles amplios ni de atributos propios. Y su punto débil, las condiciones de hora, riesgo o importe, es el terreno natural del ABAC. Esa simetría explica que la frontera de la autorización no sea “elige uno”, sino “combina el grafo con condiciones”.
Los dos problemas difíciles que tuvo que resolver Zanzibar
La idea del ReBAC es sencilla. Hacerla funcionar a la escala de Google sacó a la luz dos problemas de fondo a los que cualquier motor de relaciones serio tiene que enfrentarse, y entenderlos separa un juguete de un sistema de producción.
La coherencia y el problema del “nuevo enemigo”
Los datos de autorización cambian sin parar y a menudo se replican entre regiones para ganar velocidad. Eso abre una ventana peligrosa: si una comprobación puede leer datos replicados desactualizados, puede conceder un acceso que se acaba de revocar, o respetar una concesión antigua junto a un objeto nuevo. Zanzibar llamó a su forma más afilada el problema del nuevo enemigo. Imagina que Sara quita a Daniel, que se ha ido a otro equipo, de un documento, y después añade cifras sensibles. Si una comprobación posterior para Daniel lee una réplica a la que todavía no ha llegado la retirada, él ve contenido del que le habían apartado antes incluso de que existiera. Sara hizo las cosas en el orden correcto; la lectura desactualizada las reordenó y produjo una brecha real.
La respuesta de Zanzibar es el zookie, un pequeño token opaco de instantánea que se devuelve al escribir los datos. Cuando la aplicación hace después una comprobación, puede pasar el zookie para decir “evalúa esto al menos tan reciente como esa escritura”, y el motor garantiza que la decisión refleja una instantánea no más antigua que el token. Es la versión del ReBAC del equilibrio entre frescura y latencia que ya viste con las sesiones, la revocación de tokens, la caché de atributos y la carga de datos del PBAC, resuelta aquí con un token que deja a quien llama exigir la frescura que necesita cada decisión.
El problema es sutil porque no había nada mal configurado. La revocación ocurrió antes de la edición sensible, como se quería; la brecha sale solo de una réplica que decide con datos más antiguos que una escritura que fue primero. Cualquier sistema de autorización distribuido que replique datos de permisos tiene este riesgo, y el arreglo siempre es alguna forma de “decide en una instantánea no más antigua que la escritura que importa”. Cuando evalúes un motor ReBAC, pregunta en concreto cómo resuelve la coherencia. Un motor que siempre lee los datos más frescos es sencillo pero lento, y uno que lee cualquier réplica es rápido pero inseguro; la ingeniería interesante está en dejar que quien llama elija en cada comprobación.
Grafos profundos, presupuestos de latencia cortos
El segundo problema es la velocidad. Un solo Check puede, en el peor caso, abrirse por un grafo profundo y ancho, grupos dentro de grupos y carpetas dentro de carpetas, y aun así tiene que responder en milisegundos, y el sistema tiene que aguantar millones de comprobaciones por segundo en todo el mundo. Un recorrido recursivo ingenuo que vuelve a recorrer los mismos grupos en cada petición no cumple ese presupuesto. Las respuestas de Zanzibar incluían una caché agresiva de resultados intermedios, un índice especializado apodado Leopard que precalcula las pertenencias a grupos aplanadas para que un “¿es X miembro de Y?” muy anidado sea una consulta rápida y no un recorrido profundo, y peticiones duplicadas (hedging) para domar la latencia de cola entre réplicas. No necesitas estos detalles para usar el ReBAC, pero explican por qué los motores de relaciones son bases de datos hechas a propósito y no una tabla en el Postgres de tu app: responder a la alcanzabilidad sobre un grafo enorme y cambiante en un presupuesto de milisegundos es realmente difícil, y es casi toda la ingeniería de un sistema al estilo Zanzibar.
El ecosistema que generó Zanzibar
Zanzibar es interno de Google, pero el artículo tenía el detalle suficiente para sembrar un ecosistema de código abierto y comercial muy activo. La forma es siempre la misma, guardar tuplas, declarar un modelo con reglas de reescritura y exponer una API al estilo Check y Expand, pero los proyectos varían en lenguaje, gobierno y énfasis.
| Motor | Origen | Notas |
|---|---|---|
| OpenFGA | Auth0 / Okta, hoy en la CNCF | Estándar abierto; lenguaje de modelado y SDK amables; las “condiciones” añaden atributos al estilo ABAC |
| SpiceDB | AuthZed | Implementación fiel de Zanzibar; controles explícitos de coherencia (“zedtokens”, el equivalente del zookie) |
| Permify | Permify | Motor tipo Zanzibar pensado para desarrolladores, con herramientas de esquema |
| Ory Keto | Ory | Uno de los primeros servidores de permisos de código abierto inspirados en Zanzibar |
| Warrant y otros | varios | Servicios de autorización alojados construidos sobre el mismo modelo |
Dos destacan. OpenFGA, nacido en Auth0 y donado a la Cloud Native Computing Foundation, se ha convertido en una especie de estándar de la comunidad, con un lenguaje de modelado accesible y, lo que es importante, condiciones que permiten que una relación lleve una comprobación de atributos, mezclando ReBAC con ABAC. SpiceDB, de AuthZed, es una reimplementación cercana del diseño de Zanzibar, centrada en el rendimiento, que expone controles de coherencia para que quien llama pueda cambiar frescura por latencia en cada petición.
Este es el espacio de trabajo de Sara como un modelo al estilo OpenFGA. Declara los tipos, sus relaciones y las reescrituras, el esquema, separado de los datos de las tuplas:
model
type user
type group
relations
define member: [user, group#member] // los grupos pueden anidarse
type folder
relations
define editor: [user, group#member]
define viewer: [user, group#member] or editor // editor implica lector
type document
relations
define parent: [folder]
define editor: [user, group#member] or editor from parent
define viewer: [user, group#member] or editor or viewer from parenteditor from parent y viewer from parent son la herencia tuple-to-userset, y or editor es la unión. Diez líneas de modelo más un flujo de tuplas expresan la herencia del árbol de carpetas, los grupos anidados y las jerarquías de permisos, un conjunto de reglas que en los otros modelos se extendería por decenas de roles o una política ABAC gruesa.
Dónde brilla el ReBAC y dónde le cuesta
Con el modelo en la cabeza, el terreno del ReBAC está claro. El software colaborativo, documentos, carpetas, repositorios, tableros, wikis, está hecho de relaciones: dueños, editores, lectores, compartir y contener. Las jerarquías, organizaciones, árboles de carpetas, grupos de recursos, estructuras de clientes multiinquilino, son justo las aristas de padre e hijo que el tuple-to-userset se diseñó para recorrer, así que un permiso fijado una vez arriba baja gratis. Las plataformas sociales y de contenido, donde la visibilidad sigue a la amistad, al seguimiento o a la propiedad, son grafos de relaciones por naturaleza. Y cualquier producto que tenga que enseñar quién tiene acceso a algo, o a qué puede llegar un usuario, obtiene esas consultas como recorridos nativos en lugar de exploraciones costosas. Si tus frases de autorización llevan de forma natural la palabra “porque” seguida de una cadena de propiedad o pertenencia, es muy probable que el ReBAC sea el modelo adecuado.
Le cuesta cuando el acceso depende de cosas que no son relaciones: solo en horario laboral, solo si el dispositivo está gestionado, solo para operaciones de menos de 10.000, solo si el riesgo es bajo. Son condiciones del entorno o calculadas, la especialidad del ABAC, y un grafo de relaciones puro no tiene un sitio natural para ellas. La respuesta antigua era poner una comprobación ABAC delante de la comprobación ReBAC en el código de la aplicación, lo que funciona pero parte en dos la lógica de autorización. La respuesta moderna son las relaciones condicionales: motores como OpenFGA permiten que una tupla lleve una condición, una pequeña expresión sobre atributos que tiene que cumplirse para que la arista cuente, así que “editor mientras la hora actual esté dentro del horario laboral” se convierte en una sola arista condicionada. Esa convergencia, un grafo de relaciones con condiciones de atributos en sus aristas, es hacia donde va la autorización de grano fino.
El ReBAC traslada además toda la superficie de riesgo a los datos de las tuplas. Una tupla que falta es una funcionalidad rota, alguien no llega adonde debería. Una tupla que sobra es una brecha de privacidad, alguien llega adonde no debería. Como los permisos se deducen recorriendo el grafo, una sola arista equivocada a alto nivel, un usuario añadido por error a un grupo poderoso, un documento archivado en la carpeta equivocada, puede conceder en silencio acceso a miles de objetos por debajo. El poder expresivo del grafo es justo lo que hace que sus errores de datos lleguen tan lejos. Trata la escritura de tuplas como un evento sensible para la seguridad: regístrala, revisa las reglas de reescritura más poderosas del modelo y comprueba que “¿quién puede llegar a esto?” devuelve lo que esperas. La consulta inversa es tu mejor herramienta de auditoría.
La hoja de ruta de Sara como relaciones
Hemos resuelto el acceso de Sara a /research/roadmap.md con todos los modelos de esta parte del dominio; el ReBAC lo resuelve como un grafo. Las tuplas solo dicen hechos simples: Sara es miembro de group:eng, group:eng#member es editor de folder:research y document:roadmap tiene a folder:research como carpeta padre. Ninguna tupla menciona a Sara y la hoja de ruta juntas. Cuando la app pregunta Check(document:roadmap, viewer, user:sara), el motor deduce la respuesta: los lectores del documento incluyen a los de su carpeta padre, la carpeta padre es folder:research, los lectores de la carpeta incluyen a sus editores, sus editores incluyen a group:eng#member y Sara es miembro. Permitir. Cada salto era una relación guardada; el permiso se calculó.
Fíjate en con qué naturalidad se propagan los cambios, el superpoder discreto del ReBAC y la razón de que el diálogo de compartir de Sara se actualizara en cuanto movió el fichero. Mueve el documento a otra carpeta escribiendo una sola tupla parent nueva y todo su conjunto de permisos pasa a ser el de esa carpeta, porque el acceso siempre se heredó, nunca se copió. Añade a Daniel a group:eng con una tupla y se convierte al instante en editor de la carpeta y de todos sus documentos, sin tocar esos objetos. Revoca borrando la tupla de pertenencia y el acceso derivado desaparece en la siguiente comprobación. En RBAC, mover un documento obliga a decidir de nuevo qué roles deberían concederlo; en ABAC, volverías a evaluar una política por usuario. En ReBAC el grafo es el modelo de permisos, así que editar el grafo es editar los permisos, de forma directa y local, con toda la estructura heredada intacta.
Incluso aquí hay un límite. Supón que vuelve la regla de soporte: un agente puede editar una cuenta solo en horario laboral y solo si hay un ticket abierto. “Asignado al agente” y “pertenece a la cuenta” son relaciones que el ReBAC expresa de maravilla, pero “en horario laboral” y “hay un ticket abierto” son condiciones, no conexiones. Un grafo puro no puede contenerlas; necesitas aristas condicionadas o una comprobación ABAC de acompañamiento. Ese hueco entre conexión y condición es la razón de que los modelos rara vez aparezcan solos en producción, y de que el siguiente modelo se propusiera unificarlos en una única abstracción más general.
Resumen
El control de acceso basado en relaciones deriva los permisos de un grafo de conexiones entre entidades. El acceso se concede cuando el sujeto está conectado con el recurso a través de una cadena de relaciones permitida, así que la pregunta de autorización se convierte en si existe un camino permitido, un recorrido del grafo. La tupla es la unidad básica: cada permiso es un hecho uniforme objeto#relación@sujeto, los usersets permiten que una tupla apunte a un conjunto de sujetos y las reglas de reescritura, la unión y el tuple-to-userset, calculan relaciones, de modo que grupos, jerarquías de permisos y herencia salen de una sola pieza diminuta. Zanzibar lo hizo realidad a gran escala y tuvo que resolver la coherencia, con el problema del nuevo enemigo resuelto con los zookies de instantánea, y el rendimiento, con caché y un índice de pertenencias precalculado para recorrer grafos profundos en milisegundos. Le siguió un ecosistema rico, OpenFGA, SpiceDB, Permify y Ory Keto, que guardan tuplas, declaran un modelo y exponen Check y Expand. Y el ReBAC brilla en la colaboración, la jerarquía y el compartir, responde de forma nativa a “¿quién puede acceder a esto?” y solo sufre con condiciones como la hora o el riesgo, y por eso los motores modernos añaden condiciones de atributos a las aristas y acercan el ReBAC al ABAC.
Tres preguntas para ponerte a prueba
- Expresa “puedes editar este documento porque eres miembro del equipo dueño de su carpeta” como un conjunto de tuplas ReBAC más las reglas de reescritura necesarias para deducir el permiso de edición. Identifica qué regla hace la herencia y cuál hace la indirección de grupos.
- Explica con tus palabras el problema del nuevo enemigo, incluido por qué las dos escrituras implicadas estaban en el orden correcto, y describe cómo un token de instantánea evita la brecha sin obligar a que cada comprobación lea los datos más frescos posibles.
- Un equipo quiere imponer que “un editor solo puede editar una cuenta en horario laboral”. Explica por qué un grafo de relaciones puro no puede expresar la condición horaria y describe dos formas de resolverlo, una comprobación ABAC de acompañamiento o una arista condicionada. ¿Cuál mantiene la lógica de autorización en un solo sitio?
Ejercicios prácticos
- Modela un árbol de carpetas en OpenFGA. En el playground de OpenFGA, declara los tipos
user,folderydocumentcon las relacionesvieweryeditor, la herencia porparent(viewer from parent) y que editor implique lector. Añade tuplas que hagan a un usuario editor de una carpeta de arriba y ejecuta unCheckque demuestre que puede ver un documento tres niveles más abajo. Borra una tupla y mira cómo desaparece el acceso. - Escribe la consulta inversa. Con el mismo modelo, usa la operación de listar objetos para responder “¿qué documentos puede ver este usuario?” y “¿quién puede ver este documento?”. Fíjate en que estas consultas, exploraciones costosas en RBAC o ABAC, son aquí recorridos nativos.
- Encuentra la costura. Coge una regla de autorización de un sistema que conozcas y sepárala en su parte de relación (“porque es dueño, pertenece o gestiona…”) y su parte de condición (“pero solo si la hora, el importe o el riesgo…”). Decide qué va en un grafo de relaciones y qué necesita una condición de atributos, y esboza cómo una arista condicionada permitiría que un solo motor ReBAC llevara las dos cosas.
Preguntas frecuentes
¿Qué es el control de acceso basado en relaciones (ReBAC)?
El control de acceso basado en relaciones es un modelo en el que los permisos salen de las relaciones entre entidades y no de roles ni de atributos sueltos. El acceso se concede cuando un sujeto está conectado con un recurso a través de una cadena de relaciones permitida; por ejemplo, puedes editar un documento porque eres miembro del equipo dueño de la carpeta en la que está. El ReBAC representa esas relaciones como un grafo y responde a una petición de autorización comprobando si existe un camino válido entre sujeto y recurso. Es el modelo que hay detrás de Google Zanzibar y sus sucesores, y el que mejor encaja con el software colaborativo, donde compartir y anidar definen quién puede hacer qué.
¿Qué es una tupla de relación en ReBAC?
Una tupla de relación es la unidad básica de datos del ReBAC: un pequeño hecho de la forma objeto#relación@sujeto, que se lee 'este sujeto tiene esta relación con este objeto'. Por ejemplo, document:roadmap#editor@user:sara significa que Sara es editora del documento roadmap, y folder:research#parent@document:roadmap significa que la hoja de ruta está en la carpeta research. Las tuplas pueden apuntar a conjuntos de usuarios en lugar de a uno solo: group:eng#member@user:sara junto con folder:research#editor@group:eng#member dicen que todos los miembros del grupo de ingeniería son editores de la carpeta research. El conjunto completo de tuplas es el grafo que recorre el motor para responder una comprobación.
¿Qué es Google Zanzibar?
Zanzibar es el sistema de autorización global de Google, descrito en un artículo de 2019. Guarda los permisos como tuplas de relación y responde miles de millones de comprobaciones de autorización por segundo en productos como Drive, YouTube, Calendar o Cloud. Popularizó el ReBAC e introdujo el modelo, hoy estándar, de tuplas más reescrituras de usersets, junto con respuestas de ingeniería a la coherencia a gran escala, sobre todo los 'zookies', tokens de instantánea que permiten exigir una decisión al menos tan reciente como una escritura anterior para evitar el problema del 'nuevo enemigo'. Es el antepasado directo de motores de código abierto como OpenFGA, SpiceDB o Permify.
¿Qué diferencia hay entre RBAC, ABAC y ReBAC?
El RBAC decide por los roles del sujeto ('¿eres editor?'), el ABAC por atributos del sujeto, el recurso, la acción y el entorno ('¿coincide tu región con la del recurso?') y el ReBAC por las relaciones entre entidades ('¿estás conectado con este recurso por un camino permitido, como miembro del grupo dueño de su carpeta?'). El RBAC es fuerte para funciones de puesto estables, el ABAC para reglas de contexto y de grano fino, y el ReBAC para permisos jerárquicos, compartidos y por objeto como los de las apps colaborativas. Se complementan, y los sistemas modernos combinan cada vez más grafos de relaciones con condiciones de atributos.
¿Cuándo conviene usar ReBAC?
El ReBAC encaja cuando el acceso se define por cómo están conectadas las entidades y no por roles fijos: documentos y carpetas colaborativos que se comparten y heredan permisos, jerarquías multiinquilino en las que los permisos bajan por el árbol de una organización, plataformas sociales y de contenido donde la visibilidad sigue a la amistad o la propiedad, y cualquier sistema que tenga que responder con eficacia '¿quién tiene acceso a este objeto?'. Por sí solo encaja peor con reglas que dependen de condiciones del entorno o calculadas, como la hora, el riesgo del dispositivo o el importe de una operación; esa es la fuerza del ABAC, y por eso a menudo se combinan.