La autenticación y la autorización son grandes partes del rompecabezas de seguridad que deben resolverse por arquitectos de la nube y ingenieros de DevOps. En este blog, nos centraremos específicamente en cómo lograr la autorización/control de acceso; es decir, qué acciones puede realizar la entidad autenticada en la malla de servicios Istio. Ayuda a proteger la infraestructura evitando acciones de intenciones maliciosas.
La autorización en una malla de servicios puede definirse usando políticas de OPA. OPA es un mecanismo que ayuda a los tipos de DevOps a definir y aplicar políticas de autorización para las cargas de trabajo de Kubernetes. En este artículo, veremos:
- Qué es OPA
- Por qué deberías integrar OPA con la malla de servicios Istio
- Cómo Istio y OPA autorizan solicitudes
- Los pasos exactos que puedes seguir para integrar OPA con Istio
¿Qué es OPA?
OPA (abreviatura de “Open Policy Agent”) es un motor de aplicación de políticas de código abierto, de propósito general, que permite a los tipos de DevOps definir las políticas como código usando un lenguaje declarativo de alto nivel llamado Rego. OPA ayuda a definir y aplicar políticas de forma centralizada a través de toda la pila, aliviando a los desarrolladores de la necesidad de escribir políticas de autorización en el código de la aplicación. Aquí es cómo funciona OPA (revisa el Diagrama 1):
- El aplicativo/servicio recibe una solicitud.
- El servicio envía una solicitud de autorización en JSON a OPA.
- OPA verifica la solicitud contra las políticas de autorización definidas.
- OPA toma la decisión y devuelve la respuesta de autorización (ALLOW/DENY) en formato JSON al servicio.
Figura 1: Flujo de solicitud de autorización con OPA
Tenga en cuenta que no necesita ser una aplicación escrita por un desarrollador la que envía la solicitud de autorización: puede ser Argo CD, recurso de Kubernetes Gateway API, Terraform, Prometheus, o cualquier otra cosa ya que OPA es de uso general. (He mencionado y he dibujado una aplicación en un clúster de Kubernetes aquí por comodidad y mejor comprensión.)
¿Por qué integrar OPA con Istio?
Istio tiene un mecanismo de autorización robusto. Sin embargo, tener una motor de aplicación de políticas dedicado como OPA junto a la malla de servicios Istio tiene sus propias ventajas:
- Sistema de gestión centralizado para definir y aplicar políticas: OPA hace más fácil para los DevOps gestionar centralmente las políticas de autorización para toda la pila. Esto incluye cargas de trabajo enmascaradas, pilas no enmascaradas y, además, chequeos de autorización (una política que evita el despliegue los viernes, por ejemplo).
- Más flexibilidad y granularidad en la definición de políticas: Si mira la tabla de abajo (Figura 2), es claro que la autorización de Istio puede hacer mucho y coincidir una solicitud basada en una variedad de campos de diferentes fuentes de datos. Sin embargo, la CRD de AuthorizationPolicy de Istio puede tener limitaciones en la configuración del cuerpo de solicitud HTTP o cualquier datos contextuales en los campos, para los que se puede utilizar OPA. A diferencia de Istio, OPA puede utilizar cualquier tipo de datos para la evaluación de políticas.
- Configuración simplificada de AuthZ: Puede ser tedioso para los DevOps configurar reglas de autorización complejas en Istio. OPA se configura usando Rego, que es más parecido a un lenguaje de programación. Es relativamente más fácil establecer reglas de política básicas o complejas usando Rego.
Figura 2: Comparación tabular entre la autorización de Istio y OPA (fuente)
Cómo Istio y OPA autorizan solicitudes
Los DevOps pueden desplegar OPA como un servicio separado o como un contenedor sidecar junto con el proxy Envoy y el contenedor de aplicación en un pod. El enfoque del contenedor sidecar es mejor para reducir la latencia.
Los contenedores sidecar de OPA deben ser inyectados en el pod de aplicación, justo como los contenedores sidecar del proxy Envoy de Istio. Podemos configurar los contenedores OPA inyectados para montar ConfigMaps que contienen las reglas de autorización; cada contenedor sidecar OPA en el namespace entonces montará la misma configuración y reglas AuthZ definidas en el ConfigMap.
Una vez que se inyecta el sidecar OPA, el proxy Envoy enviará solicitudes de autorización a OPA para tomar decisiones de autorización cuando el servicio recibe una solicitud:
Figura 3: Flujo de trabajo de autorización Istio-OPA
Supongamos que los DevOps no quieren que cada contenedor OPA inyectado en el mismo namespace siga las mismas configuraciones y desean aplicar reglas diferentes. En ese caso, tendrán que hacer cualquiera de los siguientes:
- Quitar el código fuente que permite a la política de inyección actual usar un ConfigMap particular
- Configurar un webhook mutador y deshabilitar la inyección sidecar a nivel de pod.
- Servir paquetes de políticas de un servidor HTTP remoto
- Desplegar la aplicación y los sidecars en un namespace diferente con un ConfigMap diferente
Pasos para integrar OPA con Istio: Demostración
La idea aquí es hacer de OPA el autorizador externo en lugar de los sidecars del proxy Envoy — para tomar decisiones de control de acceso.
Utilizaré la clásica aplicación Bookinfo de la documentación de Istio para la demostración. Configuraré OPA con Istio para el control de acceso y comprobaré si es enforcing disparando solicitudes a bookinfo/productpage:
Figura 4: Diagrama de tutorial de integración de Istio-OPA
Tenga en cuenta que /productpage es la interfaz de usuario, que hace llamadas internas a otros servicios, como los servicios de reseñas y calificaciones (diagrama). Inyectaré OPA en cada pod del namespace bookinfo
; todos los contenedores de OPA montan el mismo ConfigMap y tienen las mismas políticas de autorización debido a esto. El comportamiento predeterminado de la aplicación Bookinfo
no forwarda ninguna autenticación HTTP, por lo que las llamadas internas fallarán la autenticación y, por lo tanto, la autorización.
Seguiremos los pasos dados en orden:
- Configurar la inyección de sidecar OPA
- Permitir comunicación entre el proxy de Istio y OPA
- Desplegar la configuración de OPA
- Aplicar la configuración de Istio
- Desplegar la aplicación y probar la configuración de autorización Istio-OPA
El requisito previo para la demostración es tener instalado Istio v1.19+ en tu clúster. Aquí utilizo Istio v1.21.0.
OPA proporciona un quickstart.yaml para una instalación fácil. He dividido el yaml en tres partes para una mejor comprensión: IMESH GitHub repo.
Paso 1: Configurar la Inyección de Sidecar OPA
Aplicar el opa_controller.yaml:
kubectl apply -f opa_controller.yaml
El opa_controller.yaml
despliega todo – certificados TLS, ConfigMap que contiene la política de inyección, deploy del controlador de admisión y configuración del webhook mutante – en el namespace opa-istio
(revisa la Figura 5):
- El controlador de webhook mutante (
opa-istio-admission-controller
) escuchará entonces una etiqueta particular (opa-istio-injection
) con un valor establecido en enabled. - El controlador de webhook llama al
admission-controller
, que tiene la política de inyección. - La política de inyección le dice al
admission-controller
cómo inyectar el contenedor sidecar de OPA en el pod.
Figura 5: Configuración de inyección de sidecar de OPA
Ahora, antes de desplegar la aplicación Bookinfo, creamos el namespace bookinfo
y seguimos los siguientes pasos:
Cree el namespace bookinfo
aplicando bookinfo-ns.yaml:
kubectl apply -f bookinfo-ns.yaml
opa-istio-injection: enabled
, to auto-inject OPA sidecars.
Paso 2: Habilitar la Comunicación Entre el Proxy de Istio y OPA
Edite el ConfigMap de Istio en el namespace istio-system
y agregue extensionProviders
(opa-ext-authz-grpc
), para que habilite la autorización externa en la malla:
- Copie
extensionProviders
de la comentación en opa_controller.yaml. - Edite el ConfigMap de Istio y agregue
extensionProviders
en el campo de la malla. - Asegúrese de que la sangría sea correcta.
- Guarde la configuración.
Este paso hace posible que el istio-proxy
se comunique con el contenedor opa-istio
en el pod para solicitudes de autorización.
Si mira los extensionProviders
, es un filtro de tipo ExtAuthzGrpc
en Envoy con un servicio especificado y un puerto:
...
extensionProviders:
- name: opa-ext-authz-grpc
envoyExtAuthzGrpc:
service: opa-ext-authz-grpc.local
port: "9191"
...
El nombre, dirección del servicio y puerto de los extensionProviders
deben ser los mismos en el opa_authz.yaml y el opa_config.yaml.
Paso 3: Implementar Configuración de OPA
El opa_config.yaml define configuraciones relacionadas con las políticas abiertas. Tiene opa-istio-config
y opa-policy ConfigMaps
— que definen la implementación del servicio gRPC (envoy_ext_authz_grpc
) y las políticas de autorización reales, respectivamente.
Las políticas de autorización pueden dividirse en dos partes: la primera parte define las condiciones bajo las cuales se permite o se niega la autorización; la segunda parte define los roles de usuario y las permisos para cada rol.
Las políticas de autorización pueden tardar un poco en familiarizarse, ya que Rego no utiliza muchas palabras clave aquí. Activa una versión más nueva de Rego para obtener palabras clave (por ejemplo, la palabra clave allow if condition).
Aplica la configuración de OPA en el namespace bookinfo
, ya que va junto con la aplicación:
kubectl apply -f opa_config.yaml -n bookinfo
Paso 4: Aplicar Configuración de Istio
El archivo opa_authz.yaml contiene configuraciones de Istio. Tiene una AuthorizationPolicy
y un ServiceEntry
. Tenga en cuenta que el proveedor de la Política de Autorización es opa-ext-authz-grpc
, que es el extensionProvider
que configuramos en el ConfigMap en el paso 2.
De forma similar, el hostname definido en el ServiceEntry
es el mismo que la dirección del servicio proporcionada en el extensionProvider
(opa-ext-authz-grpc.local
). El servicio gRPC se ejecutará en el puerto 9191 en localhost 127.0.0.1, lo que el ServiceEntry
hace que los sidecars de opa-istio
sean accesibles dentro del pod por el contenedor istio-proxy
.
Deploy the configuration:
kubectl apply -f opa_authz.yaml -n bookinfo
Step 5: Deploy the Application and Test the Istio-OPA Authorization Setup
Deploy the Bookinfo application and the gateway:
kubectl apply -f /your_Istio_directory/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
kubectl apply -f /your_Istio_directory/samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo
Check the pods in the bookinfo
namespace:
kubectl get pods -n bookinfo
You can see that each pod has 3 containers running in them: the application, Envoy proxy (istio-proxy
), and OPA (opa-istio
) containers.
Get the IP of the Istio gateway to access the service:
kubectl get svc -n istio-system

Now everything is set, and we are ready to test the authorization policies. The policies we defined in opa_config.yaml are the following:
...
user_roles = {
"alice": ["guest"],
"bob": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
...
Alice is a guest user who can only access the /productpage
; Bob is an admin who can access the paths /productpage
and /api/v1/products
. Let us verify the policies.
Trying to access /api/v1/products
from Alice:
curl -vvv your_istio_gateway_ip/api/v1/products -u alice:password
Puedes ver que la respuesta 403 Prohibido
desde que Alice no tiene acceso al path. Vamos a intentar el mismo path como Bob:
curl -vvv your_istio_gateway_ip/api/v1/products -u bob:password
Muestra el estado HTTP 200 OK
y el contenido de la página al final de la respuesta.
Ejemplo de Escenario para Control de Acceso con OPA
Puedes usar la CRD AuthorizationPolicy de Istio para aplicar la política mostrada en la demostración anterior. No necesitas OPA. Sin embargo, hay casos en los que el control de acceso de Istio puede ser limitado, como se menciona en la tabla al comienzo. Déjame dar un ejemplo simple.
Supongamos que hay una aplicación de BookReviews, que es un servicio de GraphQL, donde los revisores envían reseñas, los editores editan y publican esas reseñas y los usuarios leen las reseñas publicadas.
Cuando un revisor agrega una reseña de libro al servicio, la solicitud incluiría el JWT del revisor, que contiene los grupos y roles (revisor o editor) a los que pertenece el revisor. El cuerpo de la solicitud también contiene una consulta de mutación GraphQL con los datos de la reseña recién creada.
Vamos a decir que deseas asegurar las siguientes condiciones:
- Sólo los revisores pueden enviar reseñas.
- Un editor solo puede editar una reseña si fue escrita por un revisor que pertenece al mismo grupo dirigido por ellos.
- Sólo los editores pueden marcar una reseña como “lista para publicar”.
Aquí está el diagrama que incluye las políticas mencionadas arriba:
La AuthorizationPolicy de Istio luchará para aplicar las condiciones mencionadas. La razón es que Istio no puede usar el cuerpo de solicitud GraphQL para las comprobaciones de autorización, que es un objeto JSON junto con el JWT necesario para la evaluación de las políticas.
OPA no presenta tales limitaciones. Puede cargar cualquier información para las comprobaciones de políticas y DevOps puede escribir estas reglas de manera más ergonomica utilizando Rego.
Vídeo: Demo en acción
Si prefiere ver el demo en acción, por favor revise el vídeo de abajo:S
Apoyo Empresarial para Integrar Istio
La mayoría de las empresas utiliza OPA para definir y aplicar políticas de autorización para toda su infraestructura. Tener un mecanismo central de control de acceso mejora la seguridad general y la agilidad de los equipos de TI. De otra forma, los desarrolladores gastarán tiempo en desarrollar políticas de autorización en su código de aplicación escrito en un lenguaje particular, lo que impide la escalabilidad y el lanzamiento más rápido de la lógica de negocio.
Source:
https://dzone.com/articles/5-steps-to-integrate-istio-with-opa