Ya hemos hablado en otras ocasiones de Istio y de todo lo que nos puede ofrecer en el desarrollo de nuestras arquitecturas distribuidas. En Paradigma estamos apostando fuerte por el producto y hoy nos centraremos en una de las funcionalidades “clave” que nos ofrece este service mesh: la seguridad.

El token JWT

JWT (JSON Web Token) es un estándar abierto cuyo objetivo es facilitar el intercambio de claims (datos que representan a usuarios finales) entre las partes de un sistema de manera segura.

Fue publicado por el grupo de trabajo JOSE (Javascript Object Signing and Encryption) en 2015. Hasta ese momento existía un vacío dentro del mundo de las APIS y los microservicios a la hora de transferir tokens de usuario.

En el pasado, muchas compañías optaron por definir sus tokens propietarios, aunque en la actualidad JWT es el que se ha impuesto.

Veamos qué ventajas ofrece el uso de JWT:

JWT no es perfecto, también existen desventajas en su uso. Por poner un ejemplo, los tokens no son fáciles de revocar ya que su validación, al ser offline, no depende de un punto único como en el caso de OAuth2.

La representación de un token JWT se compone de tres partes diferenciadas separadas por un punto (.). Cada parte tiene una codificación base 64 que al decodificar nos da un JSON para las dos primeras partes y los datos criptográficos para la tercera parte.

La cabecera contiene el tipo de token y algoritmos criptográficos para su verificación y/o descifrado. El payload son los datos del usuario (claims) y la tercera parte contiene la firma o cifrado de los datos que aseguran su integridad y/o confidencialidad.

Seguridad en las arquitecturas de microservicios

Con la proliferación del API management, el patrón gateway y las arquitecturas de microservicios, cada vez se está extendiendo más una “arquitectura tipo” en la que se usa una autenticación “fuerte” (OAuth 2.0/openid connect) entre el dispositivo del usuario final y el gateway y una autenticación “menos fuerte” entre el gateway y backend/microservicios.

Este tipo de autenticación más liviana es la que se suele implementar mediante JSON Web Token.

En estas arquitecturas el API Gateway, o Edge Service, es el encargado de validar el token OAuth contactando con el Identity Provider (IdP) y, una vez validado, genera un token JWT basado en las credenciales OAuth.

Por su parte, los microservicios reciben el token JWT generado por el gateway, normalmente en la cabecera de seguridad estándar “Authorization”. Los microservicios son los encargados de validar el token y propagarlo al resto de microservicios del sistema, si fuera necesario.

Hay que tener especial atención en el proceso de propagación, ya que si el token le llega a un sistema externo podríamos estar ante un problema grave de seguridad.

NOTA**:** Existen Idp’s que implementan su token OAuth (access_token) mediante JWT. Esta aproximación tiene una ventaja y es que el token puede ser validado de manera online, contactando con el IdP, o de manera offline validando la firma del JWT. Este tipo de tokens abre la posibilidad de usar el token JWT generado por el IdP en todo el sistema, haciendo innecesaria la traslación de tokens en el gateway.

Seguridad con Istio

Istio tiene varias características que nos ayudan a gestionar la seguridad de nuestros sistemas distribuidos.

Por un lado permite definir la seguridad entre componentes, esto lo consigue mediante el uso de SSL con autenticación mutua en las conexiones.

Para este cometido, Istio despliega un componente llamado “istio-auth”, que no es más que una autoridad de certificación (CA) encargada de emitir certificados destinados a ser instalados en los componentes proxy de nuestro plano de datos. La documentación de Istio denomina a este tipo de seguridad “Service-to-service authorization”.

Por otro lado, tenemos la autorización de usuario final o “endUser-to-Service authorization” que se encarga de autenticar y autorizar a los usuarios finales del sistema. En esta parte de la seguridad nos adentraremos en los siguientes apartados.

Seguridad endUser con Istio

La seguridad de usuario final ha sido implementada por Istio según los estándares definidos por el grupo de trabajo JOSE, entre los que se incluye el mencionado JWT o JWK (Json Web Key). Esta funcionalidad se añadió de manera estable en la versión 0.7.x del producto, Istio sacó su primera release (1.0.0) en Julio de este año.

Cuando un proxy envoy reciba una petición, pasará a validar el JWT con la clave pública configurada. Si el token es válido, pasará el control al microservicio añadiendo una cabecera con la información del contexto de seguridad que contiene el token JWT (“sec-istio-auth-userinfo”).

En esta cabecera encontraremos el “payload” del JWT original que contiene los datos del usuario, Istio obvia el resto del JWT.

¿Por qué hace esto Istio? Una vez el proxy ha validado el token, no tiene sentido que el microservicio lo vuelva a validar, así que el proxy envoy transfiere el contexto de seguridad al microservicio por si tiene que hacer alguna acción adicional como una autorización avanzada, generar trazas de monitorización, etc.

Para obtener el comportamiento descrito arriba, Istio disponibiliza, dentro del cluster Kubernetes, una serie de definiciones de objetos (object types). En la versión 0.7, que es la que hemos usado para el post, tendremos que trabajar con los siguientes objetos:

* A fecha de publicación de este post Istio solo permite la obtención del fichero de claves públicas por protocolos http o https.

Despliegue de ejemplo en Kubernetes

Para la prueba de concepto usaremos uno de los ejemplos de arquitectura que venimos usando en nuestra serie de posts dedicados a service mesh. Como una imagen vale más que mil palabras, os dejamos aquí el diseño de arquitectura:

Lo primero que tenemos que hacer es instalar en nuestro cluster kubernetes el software de Istio. No vamos a entrar en el detalle de su instalación ya que se ha abordado en posts anteriores.

Instalaremos el software en un cluster que hayamos creado anteriormente, nosotros hemos usado GKE, aunque Istio se puede instalar en otros sabores de Kubernetes.

Una vez instalado Istio podremos validar que el plano de control ha sido desplegado:

Ahora instalaremos nuestra arquitectura de microservicios. Para aplicar el plano de datos a nuestros ficheros descriptores de Kubernetes debemos ejecutar, en local, el comando istioctl que viene con la instalación de Istio sobre nuestros descriptores del sistema.

Este comando se encargará de modificar los ficheros descriptores insertando todo lo necesario para que los componente proxy intercepten las comunicaciones.

kubectl apply -f 

Cuéntanos qué te parece.

Enviar.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.