Autorización Descentralizada: Sidecars, Edge y Multi-Cloud
Dónde se ejecuta de verdad el PDP: el patrón sidecar (Envoy ext_authz, OPA-Envoy, las políticas de autorización de Istio y Linkerd), las políticas en el borde de la CDN antes de que la petición llegue a tu infraestructura, WASM como la capa de portabilidad que permite ejecutar la misma política en todos esos sitios y qué cambia en la distribución de políticas y en el problema del nuevo enemigo cuando el motor de decisión se reparte entre regiones y nubes en lugar de vivir en un solo lugar.
Revocada en Fráncfort, permitida en Virginia
La empresa de cashback abre una filial en la UE y Sara pasa del equipo de finanzas de Estados Unidos al nuevo equipo de Fráncfort. En su último día en el puesto anterior, un administrador de Fráncfort la saca del grupo de informes de Estados Unidos. Diez segundos después, por costumbre, Sara abre un informe trimestral de Estados Unidos desde un marcador. La petición cae en la región de Estados Unidos, la más cercana al enlace que siguió, y el motor de autorización de esa región lee su copia local de los datos de relaciones. La retirada todavía está cruzando el Atlántico. El informe se abre.
En esa historia no hay ningún fallo en la política ni en el modelo. La regla es correcta, la tupla se borró y el motor evaluó bien con lo que podía ver. Lo que falló es dónde se tomó la decisión y lo que ese sitio podía saber en ese momento. Hace tres artículos, al describir dónde puede vivir un PDP, el artículo de XACML decía que puede ser una librería compilada dentro de la aplicación, un sidecar junto a cada servicio o un servicio central al que todas las aplicaciones llaman por la red, y lo presentaba como una elección con consecuencias reales en latencia, frescura y radio de impacto. Todos los artículos desde entonces han tratado “dónde se ejecuta la decisión” como un detalle para más adelante. Este lo resuelve.
La razón corta por la que esto merece un artículo propio: la ubicación no es solo una decisión de infraestructura; cambia lo que el motor de decisión puede prometer. Un PDP a un salto de red puede ser más coherente, pero es un punto único de fallo y latencia extra en cada petición. Un PDP en un sidecar es rápido y aguanta particiones de red, pero ahora existe en cientos de copias que necesitan la misma política. Un PDP en el borde de una CDN, quizá a miles de kilómetros de tu base de datos, no puede ver físicamente datos que solo viven en tu región de origen. Nada de eso son fallos que se puedan quitar con ingeniería. Es la forma real del equilibrio, y una arquitectura en producción tiene que elegir entre ellas a propósito, muchas veces usando varias a la vez.
El resto del artículo recorre ese boceto capa a capa: primero los sidecars, luego el borde, luego la capa WASM que permite ejecutar una misma política en ambos, después cómo llegan la política y los datos a cada copia y, al final, qué pasa cuando los propios datos viven en más de una región, que es donde vuelve a aparecer el informe de Sara.
El patrón sidecar
La forma más habitual de descentralizar hoy un PDP es el sidecar: un segundo proceso desplegado junto a cada instancia de tu aplicación, en Kubernetes un segundo contenedor en el mismo pod, al que tu aplicación, o más a menudo un proxy delante de ella, llama por localhost en lugar de por la red.
La forma concreta más común es Envoy con OPA. Envoy, el proxy sobre el que se construyen casi todos los service mesh, tiene un filtro ext_authz que intercepta cada petición y pide una decisión a un autorizador externo antes de pasarla a la aplicación. Si apuntas ese filtro a un OPA local (el opa-envoy-plugin empaqueta OPA para que hable el protocolo gRPC de ext_authz), obtienes autorización aplicada delante de cada servicio sin que el código de la aplicación llame nunca a una librería de autorización. El PEP vive en el proxy, no en la aplicación.
sequenceDiagram accTitle: Un flujo de autorización con sidecar usando el filtro ext_authz de Envoy y una instancia local de OPA accDescr: El diagrama muestra una petición que llega a Envoy, el proxy que corre como contenedor sidecar en el mismo pod que la aplicación. Envoy llama al filtro ext_authz, que envía la petición por localhost a un segundo contenedor sidecar del mismo pod donde corre OPA, sin que ningún salto de red salga del pod. OPA evalúa la petición contra la política que ya tiene cargada en memoria y devuelve a Envoy una decisión de permitir o denegar en microsegundos. Si se permite, Envoy pasa la petición original al contenedor de la aplicación del mismo pod. Si se deniega, Envoy devuelve un error a quien llamó sin que la aplicación llegue a ver la petición. Client->>Envoy: petición entrante Envoy->>OPA: comprobación ext_authz (localhost) OPA->>OPA: evalúa la política (en memoria) OPA-->>Envoy: permite / deniega Envoy->>App: reenvía (si se permite) Envoy-->>Client: rechaza (si se deniega)
Es la pregunta de librería, sidecar o servicio central llevada a algo concreto. Un sidecar conserva casi toda la ventaja de latencia de una librería, porque una llamada a localhost no es un salto de red de verdad, y a la vez mantiene la política fuera del proceso y del lenguaje de la aplicación. No necesitas un SDK de OPA para cada lenguaje en el que estén escritos tus servicios; necesitas Envoy delante de cada uno, y eso normalmente ya lo tienes si usas un service mesh.
Istio y Linkerd, los dos mesh más extendidos, llevan la autorización dentro del propio mesh en lugar de pedir a cada equipo que configure ext_authz a mano. El recurso AuthorizationPolicy de Istio permite a los equipos de plataforma declarar reglas gruesas, qué servicios pueden llamar a qué otros servicios y por qué rutas y métodos, que aplican los mismos sidecars de Envoy que el mesh ya inyecta para mTLS y enrutado. Es el extremo grueso del espectro de granularidad, a propósito: decisiones de servicio a servicio y con forma de rol, no por recurso. Una política del mesh que responde “¿puede el servicio de facturación llamar al endpoint /write del libro contable?” y un sidecar de OPA que responde “¿puede esta petición escribir en esta entrada concreta del libro?” son dos capas, las dos descentralizadas, las dos sobre la misma infraestructura de sidecars. El mesh suele encargarse de la capa gruesa, y OPA o algo equivalente se conecta por ext_authz para todo lo que sea más fino.
Fíjate en lo que el sidecar resolvió y en lo que no. Quitó el salto de red hasta un PDP central, pero no quitó la necesidad de que todas las copias estén de acuerdo. Has cambiado un decisor que podía ser lento o inalcanzable por muchos decisores locales idénticos que pueden desincronizarse si nadie se ocupa de distribuir la política. Mantener miles de sidecars con la misma política es el problema operativo central de cualquier despliegue descentralizado, y tiene su propia sección más abajo.
Autorización en el borde
Lleva la idea del sidecar un paso más allá, fuera de tu propia infraestructura, y tienes la autorización en el borde: una decisión tomada dentro del entorno que atiende las peticiones de una CDN, Cloudflare Workers, AWS CloudFront Functions o Lambda@Edge, Fastly Compute, antes de que la petición vaya más lejos del punto de presencia más cercano al usuario.
Lo atractivo es una latencia a una escala que los sidecars no alcanzan. Una usuaria en Singapur que llega a un punto de presencia en Singapur recibe un rechazo en pocos milisegundos, sin que su petición cruce un océano hasta tu origen, para tráfico que nunca iba a permitirse: un token caducado, una petición mal formada, un rango de IP bloqueado. Eso importa sobre todo en la capa de perímetro, la que debe rechazar barato y rápido, y no hay sitio más rápido para rechazar que antes de que la petición salga del continente del usuario.
Los límites son igual de reales, y son de estructura, no una falta de madurez que el tiempo vaya a arreglar. Estos entornos están limitados a propósito: poco tiempo de CPU, porque se cobran y se planifican para miles de invocaciones diminutas y no para una cara; poco o ningún acceso directo a tus bases de datos internas, y ninguna forma razonable de mantener una copia caliente y sincronizada de un grafo de relaciones grande. Un worker del borde puede verificar la firma de un JWT y comprobar sus claims, que es trabajo de perímetro autocontenido y rápido. En general no puede ejecutar un Check al estilo Zanzibar que tenga que recorrer un grafo guardado en tu región de origen, porque ir a buscar esos datos borraría la ventaja de latencia que justificaba usar el borde.
Así que, cuando tengas el borde disponible, no lo trates como una copia más rápida de toda tu autorización, por la misma razón por la que el artículo de granularidad desaconsejaba recurrir al grano fino por defecto. El borde es la capa más gruesa y más rápida de un diseño por capas. Rechaza lo que puede y deja pasar todo lo demás a la capa que tiene los datos para decidir bien. Un worker del borde que intenta sustituir al PDP fino de tu origen o no puede, por falta de datos, o acaba guardando en caché una copia vieja y desconectada del estado de autorización que se aleja de la fuente de verdad. Eso trae de vuelta justo el riesgo de datos viejos del problema del nuevo enemigo, en la capa con menos visibilidad sobre él.
WASM por debajo de todo
Un sidecar, un worker del borde y el proceso de una aplicación que embebe una librería de políticas son tres entornos que no tienen casi nada en común: lenguajes distintos, límites de CPU y memoria distintos, formas de desplegar distintas. Lo que permite que la misma política se ejecute bien en los tres sin reescribirla tres veces es WebAssembly (WASM), un formato de bytecode portable y aislado que todos esos entornos saben ejecutar.
OPA compila una política Rego a un módulo .wasm con opa build -t wasm, y ese único artefacto es lo que se carga en el OPA de un sidecar, se embebe en una aplicación con los SDK de WASM de OPA para Go, JavaScript y otros lenguajes, o se ejecuta dentro de un worker del borde. Cloudflare Workers en concreto trata WASM como ciudadano de primera, porque su entorno ya necesitaba una forma rápida y aislada de ejecutar código no confiable con la CPU medida, y una política compilada encaja bien en esa forma. Cedar ha ido en la misma dirección, con una implementación de referencia pensada para embeberse. La tendencia en todos los motores de este módulo es la misma: compila la política una vez y ejecuta el artefacto compilado en cualquier sitio, en lugar de llevar un entorno de lenguaje completo, un intérprete de Rego por ejemplo, a cada lugar que necesite una decisión.
Para la descentralización esto importa porque convierte “ejecuta políticas en el borde” de “porta tu motor de políticas a un entorno nuevo y limitado” en “carga el mismo artefacto que ya construyes para tus sidecars en un host WASM que la CDN ya te da”. Esa portabilidad es lo que hace práctica la autorización en el borde para algo más que comprobaciones de tokens escritas a mano.
Distribuir la política sin un decisor central
Todos los patrones vistos comparten el problema que planteaba la sección del sidecar: si ningún proceso toma todas las decisiones, ¿cómo se ponen de acuerdo miles de decisores independientes, sidecars por toda una flota y workers en decenas de puntos de presencia, sobre cuál es la política vigente?
La respuesta a la que llegan las arquitecturas descentralizadas es separar la escritura de la evaluación, que en el fondo es la separación entre PAP y PDP del artículo de XACML estirada sobre muchas más copias del PDP. Un Policy Administration Point sigue siendo la única fuente de verdad, el sitio donde la política se escribe, se revisa, se prueba y se versiona. Pero en lugar de llamarlo en cada decisión, publica paquetes inmutables y versionados, y cada sidecar y cada worker del borde descarga el último cada cierto tiempo, o lo recibe por push para desplegar más rápido, y evalúa solo contra su copia local.
flowchart LR accTitle: Distribución de paquetes de políticas desde un PAP central hacia una flota descentralizada de sidecars y workers del borde accDescr: El diagrama muestra a una autora de políticas que confirma un cambio, que pasa por la CI y que el punto de administración de políticas publica como un nuevo paquete firmado en un registro de paquetes. Desde el registro, dos grupos distintos descargan el paquete por su cuenta y de forma asíncrona, fuera de la ruta de la petición. El primero es una flota de sidecars, cada uno consultando el registro a su intervalo y cargando el nuevo paquete en memoria. El segundo es un conjunto de workers del borde en distintos puntos de presencia, que también descargan y cargan el paquete por su cuenta. La evaluación en cada sidecar y cada worker usa solo el paquete cargado en local, sin llamar nunca en vivo al registro ni al punto de administración de políticas. Author[Autora de políticas] --> CI[CI: prueba y firma] CI --> PAP[El PAP publica el paquete] PAP --> Registry[(Registro de paquetes)] Registry -.descarga.-> S1[Flota de sidecars<br/>consulta cada intervalo] Registry -.descarga.-> S2[Workers del borde<br/>consultan cada intervalo] S1 --> Local1[paquete local,<br/>evaluado sin conexión] S2 --> Local2[paquete local,<br/>evaluado sin conexión]
El intercambio es deliberado. La evaluación ya no depende de que el registro o el PAP estén accesibles: un sidecar o un worker con un paquete cargado sigue tomando decisiones correctas con esa versión de la política incluso durante una partición de red, y eso es una ganancia real de resiliencia. Lo que se pierde es la coherencia instantánea. Ahora hay una ventana de propagación entre “la política cambió en el PAP” y “todos los decisores la usan”, limitada por el intervalo de cada consulta o por la latencia del push, durante la cual distintos decisores pueden estar evaluando correctamente dos versiones distintas de la política a la vez.
Lo que también se pierde, si no haces nada, es el sitio único donde mirar. Un PDP central ve todas las decisiones; una flota de sidecars ve cada uno lo de su pod. La mayoría de los despliegues lo recuperan con registros de decisiones: cada sidecar y cada worker envía sus decisiones a un almacén central aunque cada decisión se haya tomado en local. La decisión está descentralizada; el rastro de auditoría, a propósito, no.
Varias regiones y varias nubes
Distribuir paquetes hace coherentes las reglas. No hace coherentes los datos que esas reglas leen, y ese problema se complica mucho cuando los datos de relaciones o de atributos se replican entre regiones o nubes en lugar de vivir en una sola base de datos. Aquí vuelve el informe de Sara.
Mira otra vez el problema del nuevo enemigo del artículo de autorización de grano fino con esto en la cabeza. Un despliegue al estilo Zanzibar en una sola región puede atar un Check a un zookie porque la escritura que revocó el acceso y la comprobación que lee los datos comparten, en la práctica, un único almacén coherente. Cuando esos datos se replican entre una región de Estados Unidos y otra de la UE, por latencia, para atender a los usuarios europeos desde infraestructura europea, o por residencia de datos, la obligación derivada del RGPD de mantener en la UE los datos personales europeos, que es lo que suelen ser las tuplas de relación de usuarios europeos, una revocación escrita en una región tiene que viajar a la otra antes de que una comprobación allí pueda verla. Ese viaje tiene un mínimo que marcan la velocidad de la luz y la topología de la red, no la calidad del software, y ninguna ingeniería lo hace instantáneo.
sequenceDiagram accTitle: El problema del nuevo enemigo entre regiones, donde la revocación tiene que propagarse físicamente por un enlace más largo accDescr: El diagrama muestra a un administrador que revoca el acceso de Sara en el almacén de datos de la región de la UE en el momento T. Ese cambio empieza a replicarse hacia el almacén de la región de EE. UU. por un enlace entre regiones, lo que lleva un tiempo medible limitado por la topología de red. Poco después de T, llega a la región de EE. UU., la más cercana a quien pide, una comprobación del acceso de Sara, que lee la réplica de EE. UU. Como la revocación de la UE aún no ha llegado por el enlace, la réplica de EE. UU. sigue mostrando que Sara tiene acceso y la comprobación devuelve Permite por error, lo que ilustra que el problema del nuevo enemigo persiste entre regiones con un retraso que marca la distancia física y no el retardo de replicación dentro de un mismo centro de datos. Admin->>EU_DB: revoca el acceso de Sara (T) EU_DB-->>US_DB: replicación en curso Client->>US_Engine: Check(sara, viewer, doc) US_Engine->>US_DB: lee la réplica local US_DB-->>US_Engine: aún tiene acceso (dato viejo) US_Engine-->>Client: Permite (error)
Ningún truco hace que esto desaparezca. Lo que queda es una elección, por región y por tipo de decisión, sobre qué lado del equilibrio aceptas, y hay tres opciones reales. Puedes pagar la latencia de escritura entre regiones en cada cambio sensible, exigiendo que una revocación se confirme en todas las regiones antes de que termine la petición que la hizo: la coherencia más fuerte y las escrituras más lentas. Puedes aceptar una ventana acotada de datos viejos y dejarla por escrito como un SLA explícito, la elección entre at_least_as_fresh y minimize_latency de SpiceDB que vimos en el artículo de grano fino, tomada ahora por región y no por petición. O puedes particionar los datos para que las relaciones sensibles nunca necesiten una lectura entre regiones: el acceso de un usuario europeo a recursos alojados en la UE se decide entero dentro de la región europea y el caso entre regiones nunca se da para esos datos. La mayoría de los despliegues reales en varias regiones combinan las dos últimas: particionan lo que se puede particionar y aceptan para el resto una ventana pequeña, vigilada y documentada.
Para el caso de Sara, la empresa eligió la tercera opción para casi todos los datos y la primera para un caso concreto. Los informes de Estados Unidos viven en el almacén de Estados Unidos y se deciden allí, los datos europeos se quedan en la UE, y sacar a alguien de un grupo de informes, como es raro y sensible, espera la confirmación de las dos regiones antes de que la consola de administración diga “hecho”. El administrador ve ahora un indicador de carga durante un segundo más o menos. El marcador de Sara recibe un 403.
Todo lo anterior sobre regiones vale también entre nubes, a menudo con más fuerza. Un registro de paquetes, un almacén de relaciones y un destino para los registros de decisiones necesitan cada uno su forma de desplegarse en AWS, GCP y Azure si tu organización tiene cargas en las tres, y las rutas de red entre nubes suelen ser más lentas y menos predecibles que entre regiones de la red troncal de un mismo proveedor. El equilibrio técnico es el mismo. Lo que añade trabajar con varias nubes es que cada una suele llevarla un equipo distinto, así que “elige una política de coherencia por región” pasa a ser tanto una negociación entre equipos como una decisión técnica, y es mejor tener esa conversación antes de un incidente que durante uno.
Una app de cashback desplegada en todo el mundo
Con la filial europea en marcha, la empresa tiene que decidir, de forma concreta, dónde se ejecuta cada una de sus decisiones de autorización.
Las comprobaciones de perímetro, si el token de una petición es válido siquiera, se ejecutan en el borde, en Cloudflare Workers, compiladas a partir del mismo paquete WASM de OPA que la empresa ya construye para sus sidecars. Un token inválido o caducado se rechaza en el punto de presencia más cercano al usuario, en milisegundos, y nunca llega a ninguna de las dos regiones.
Las comprobaciones de módulo, si el rol de un usuario le permite abrir el panel de comercios, se ejecutan como reglas AuthorizationPolicy de Istio que aplican los propios sidecars de Envoy del mesh. Son de servicio a servicio y con forma de rol, e idénticas en todos los pods de las dos regiones, porque la configuración del mesh se distribuye igual que los paquetes de OPA.
Las comprobaciones de recurso, si un comercio concreto puede editar una transacción concreta, se ejecutan en un sidecar de OPA por servicio, contra datos de atributos replicados por región. Los datos de comercios europeos están particionados para no salir de la UE, así que este tipo de decisión nunca necesita leer de otra región.
Las comprobaciones de relación, si un compañero de un comercio puede ver un informe de cashback compartido con su equipo, se ejecutan contra un despliegue de OpenFGA que tiene en cuenta la región. Las tuplas de los equipos europeos viven en el almacén de la UE y las de los equipos estadounidenses, en el de Estados Unidos. El caso raro entre regiones, una cuenta de administración global por ejemplo, acepta explícitamente la latencia de at_least_as_fresh en lugar del coste de fully_consistent, y eso queda escrito como una excepción conocida y acotada, no como un hueco silencioso.
Son las cuatro capas de granularidad del artículo anterior, cada una colocada a propósito en la parte de la topología que le encaja: el borde para el perímetro, los sidecars del mesh para el módulo, los sidecars de cada servicio para el recurso y un almacén de relaciones consciente de la región para la relación. Es la idea hacia la que iba todo el artículo: la granularidad y la ubicación son dos decisiones distintas, y una arquitectura madura toma las dos para cada funcionalidad en lugar de suponer que una sola ubicación sirve para todas las capas.
Probar y operar un despliegue descentralizado
Probar un sistema descentralizado necesita algo que la historia de un solo PDP no necesitaba: verificar el despliegue de los paquetes. Un paquete nuevo va primero a un grupo canario de sidecars o de ubicaciones del borde, allí se comprueban sus decisiones y solo después llega a toda la flota. Un paquete malo enviado a todas partes a la vez no tiene ningún punto en el que pudieras haberlo parado antes de que surtiera efecto. Los registros de decisiones que envían todos los sidecars y workers son lo que te permite comparar el grupo canario con el resto.
En producción, el dato que hay que vigilar es lo atrasados que van los paquetes: cuánto se aleja de la última versión publicada lo que está ejecutando ahora mismo cada sidecar y cada worker de la flota. Ese desfase es justo la ventana en la que distintos decisores pueden estar evaluando versiones distintas de la política. Una flota en la que se mantiene pequeño y vigilado es un sistema descentralizado funcionando como se diseñó. Una flota en la que crece sin que nadie lo vea, una consulta atascada o un push que falla en una región de la CDN, es un sistema que se está desincronizando consigo mismo, que es el modo de fallo que esta arquitectura tiene que vigilar y que un PDP central nunca tuvo.
Resumen
La ubicación está por encima de todas las demás decisiones de autorización de este módulo. Dónde se ejecuta el PDP cambia lo que puede prometer, no solo lo rápido que responde, porque la librería, el sidecar, el servicio central, el borde y el despliegue en varias regiones equilibran latencia, coherencia y radio de impacto de formas distintas. Los sidecars llevan la evaluación a cada instancia de un servicio, normalmente con el ext_authz de Envoy llamando a un OPA local, y conservan casi toda la velocidad de una librería sin atar la política al código, a cambio de un problema de distribución entre todas las copias. El borde acerca la capa de perímetro al usuario tanto como lo permite la física, pero solo puede decidir lo que decide un entorno limitado y con pocos datos; es un filtro delante de tu autorización real, no un sustituto. WASM es la capa que permite que una misma política compilada se ejecute en un sidecar, en un worker del borde y en una librería embebida sin reescribirla. Los paquetes versionados mantienen coherentes las reglas, cambiando la propagación instantánea por disponibilidad, que es la separación entre PAP y PDP de XACML estirada sobre miles de copias. Y cuando los datos ocupan varias regiones o nubes, el problema del nuevo enemigo pasa a ser una cuestión de distancia física, que se resuelve con una política de coherencia por región deliberada y documentada, como mostró el marcador de Sara.
Tres preguntas para ponerte a prueba
- Explica por qué la latencia de un sidecar se parece a la de una librería aunque implique un segundo proceso. ¿Qué hace exactamente distinta una llamada por
localhosta un sidecarext_authzde una llamada por la red a un PDP central? - Un equipo quiere ejecutar su Check completo de relaciones al estilo Zanzibar dentro de un worker del borde para conseguir la menor latencia posible. Con lo que dice este artículo sobre esos entornos, explica por qué en general no funciona y qué debería ejecutarse en el borde en su lugar.
- Describe con tus palabras por qué distribuir paquetes de políticas es en realidad la separación entre PAP y PDP del artículo de XACML y no una idea nueva, y qué se pierde, frente a un único PDP central, para ganar la resiliencia de una flota descentralizada.
Ejercicios prácticos
- Diseña un despliegue con sidecar. Para un servicio que conozcas, o uno inventado, esboza un despliegue con sidecar de Envoy y OPA: qué comprueba la llamada
ext_authz, qué política necesita cargada el OPA local y qué le pasa a una petición si el propio sidecar deja de estar disponible un momento. - Coloca una ruta de petición en la topología. Toma una acción de usuario en una aplicación que conozcas (hacer un pedido, ver un panel, editar un documento compartido) y asigna cada decisión de autorización de su ruta a uno de los cuatro sitios de este artículo, el borde, el sidecar del mesh, el sidecar del servicio o el almacén de datos consciente de la región, explicando por qué en cada caso.
- Diseña una política de coherencia para un caso entre regiones. Elige una decisión sensible que pueda necesitar funcionar bien entre dos regiones (una cuenta revocada, un rol de administración entre regiones). Escoge una de las tres opciones de arriba, pagar la latencia de escritura entre regiones, aceptar y documentar una ventana acotada de datos viejos o particionar los datos para que el caso no se dé, y justifícala según lo sensible que sea de verdad la decisión.
Preguntas frecuentes
¿Qué significa aquí 'autorización descentralizada' y en qué se diferencia de lo que el artículo de XACML llamaba un 'PDP distribuido'?
El artículo de XACML nombraba tres ubicaciones para el PDP, librería, sidecar y servicio central, como un equilibrio que dejaba abierto. Este artículo desarrolla ese equilibrio por completo y añade dos ubicaciones que en la época de XACML apenas existían: el borde de la red y el despliegue en varias regiones o nubes. 'Descentralizada' significa aquí que ninguna instancia del PDP ve todas las peticiones; las decisiones se toman cerca de donde ya está la petición, por muchas instancias que comparten la política y a veces los datos, y no por un único decisor central al que tenga que llegar cada petición.
¿Qué es el patrón sidecar de autorización y por qué poner OPA junto a cada instancia de un servicio en lugar de llamar a un servicio central?
Un sidecar es un segundo proceso que se despliega junto a cada instancia de tu aplicación, normalmente en el mismo pod de Kubernetes. En autorización suele ser una instancia de OPA a la que un proxy Envoy llama por localhost a través del filtro ext_authz. Se hace así en lugar de llamar a un servicio central por latencia y por radio de impacto: una llamada a localhost no tiene salto de red ni depende de que un servicio remoto esté disponible, así que la autorización sigue funcionando aunque el resto del clúster tenga un mal día. El coste es que ahora tienes un OPA por pod en lugar de un servicio, lo que es un problema de distribución de políticas, no de evaluación.
¿Cómo funciona la autorización en el borde (CDN) y cuáles son sus límites?
La autorización en el borde ejecuta una decisión dentro del entorno de una CDN que atiende las peticiones (Cloudflare Workers, AWS CloudFront Functions o Lambda@Edge, Fastly Compute) antes de que la petición llegue a tu origen. En la práctica eso significa verificar tokens y hacer comprobaciones gruesas de rol o de claims, porque estos entornos están limitados a propósito: poco tiempo de CPU y poco o ningún acceso a tus bases de datos internas o almacenes de relaciones. El borde es la capa de perímetro del espectro de granularidad, ejecutándose lo más cerca posible del usuario. No puede hacer una comprobación fina sobre un grafo de relaciones y no debería intentarlo; existe para rechazar el tráfico que nunca tuvo por qué llegar a tu origen.
¿Por qué importa WASM en la autorización descentralizada?
WebAssembly es lo que permite que la misma política compilada se ejecute sin cambios en un sidecar, dentro de un worker de una CDN y embebida en el proceso de una aplicación, tres entornos con limitaciones muy distintas que comparten un único formato de bytecode portable. OPA compila Rego a un módulo WASM para que 'escribe la política una vez' no se convierta en 'reescribe la política para cada sitio donde tenga que ejecutarse', que sería si no el mayor obstáculo para descentralizar un motor de autorización de forma coherente.
¿Cómo se mantiene coherente la política entre muchos sidecars y ubicaciones del borde si no hay un decisor central?
Separando a quien escribe la política de quien la evalúa. Sigue existiendo un Policy Administration Point central, que sigue siendo la única fuente de verdad, pero en lugar de llamarlo en cada petición, publica paquetes de políticas versionados que cada sidecar y cada worker del borde descargan (o reciben por push) a su ritmo y evalúan en local. Eso cambia la coherencia instantánea, que todos los decisores vean cada cambio a la vez, por disponibilidad y latencia: los decisores siguen funcionando bien con el último paquete que descargaron aunque la red hasta el PAP esté caída. Es el mismo tipo de equilibrio que el artículo de grano fino planteaba con los datos, aplicado ahora a la política.
¿Qué cambia en el problema del nuevo enemigo cuando la autorización se reparte entre regiones?
Se vuelve más difícil por estructura, no solo más lento. En un despliegue al estilo Zanzibar en una sola región, un zookie ata una comprobación a una instantánea no más antigua que una escritura concreta, y la escritura y la comprobación pueden compartir una vista coherente de un único almacén. Cuando los datos de relaciones se replican entre regiones, propagar una revocación con la misma garantía de frescura obliga a pagar latencia de escritura entre regiones en cada cambio sensible o a aceptar que una comprobación atendida en otra región tiene una ventana real, limitada por la distancia física, en la que puede leer datos viejos. Una ingeniería mejor no hace desaparecer ese equilibrio; se convierte en una política de coherencia por región que eliges y documentas.