Skip to main content

Cómo Snyk está unificando las estrategias de autenticación con Gloo Edge

Escrito por
Headshot of Joakim Bajoul Kakaei

Joakim Bajoul Kakaei

Jack Schofield

Headshot of David Harrigan

David Harrigan

Headshot of Gareth Visagie

Gareth Visagie

Headshot of James Bowes

James Bowes

20 de julio de 2021

0 minutos de lectura

Snyk admite varias estrategias de autenticación (authN) en sus API. Históricamente, las claves de API han sido la forma principal de authN, pero más recientemente incorporamos la autenticación con JWT firmados, generados mediante una integración con OAuth. Actualmente, esto se usa en nuestras integraciones con AWS CodePipeline y Bitbucket.

Al principio, Snyk tenía una arquitectura de concentrador y radios, con un monolito central que tomaba las decisiones de authN. Esto funcionó muy bien mientras Snyk encontraba su encaje en el mercado e iteraba rápidamente. Pero, a medida que crecían la organización y su base de clientes, también aumentaba la demanda de adoptar una arquitectura orientada a servicios (SOA). Sin embargo, este cambio arquitectónico requeriría que cada servicio tomara decisiones de authN. Es decir, cada servicio tendría que conocer varias estrategias de autenticación, lo que con el tiempo se volvería complejo y difícil de escalar.

Para avanzar hacia la adopción de una SOA, concluimos que el enfoque más seguro y práctico era tener una única autoridad que unificara las estrategias de authN en un token de identidad protegido criptográficamente. Después, los servicios podrían consumir y validar este token sin tener que lidiar con la complejidad de admitir varias estrategias de authN. En pocas palabras, una única autoridad tomaría la decisión de authN y luego enviaría un JWT firmado para que el resto del sistema lo consumiera.

Para lograrlo, necesitábamos introducir una nueva capa en nuestro sistema que pudiera autenticar las solicitudes y generar el token unificado. Aquí entra Gloo Edge, una forma de API Gateway.

¡Conectando todo con Gloo!

¿Qué son los API Gateway?

Aunque no somos expertos en API Gateway, podemos darte una lista básica de lo que pueden hacer:

  • Validación de solicitudes

  • Limitación de velocidad

  • Autenticación (¡o se pueden ampliar para incluirla!)

  • ¡Mucho, mucho más! (Te dijimos que no somos expertos…)

Y aquí viene lo mejor... ¡todo ocurre en el edge! Si alguna de tus aplicaciones hace una de las cosas que mencionamos, probablemente puedas delegarla a tu API Gateway. Eso significa que puedes eliminar líneas de código, ¡algo que a cualquier ingeniero le encanta hacer! ?

Analizamos varias opciones de API Gateway y decidimos usar Gloo Edge (en este artículo, simplemente Gloo) para acompañarnos en nuestro recorrido como plataforma. Esta publicación no explicará cómo ni por qué elegimos Gloo. ¡Ese será el tema de una próxima publicación!

¿Qué es Gloo Edge?

Gloo Edge es un API Gateway desarrollado por Solo.io. Funciona como una abstracción sobre Envoy y permite usar definiciones de recursos personalizados (CRD) de Kubernetes para generar la configuración de Envoy, lo que reduce mucho la barrera de entrada. Si sabes escribir configuraciones de Kubernetes, es muy probable que puedas escribir configuraciones de Envoy con los CRD propios de Gloo.

Para conocer más sobre Gloo, qué es y cómo aprovecha Envoy, consulta la documentación de Gloo Edge (¡de verdad es muy buena!).

Implementación de Gloo Edge en Snyk

En las siguientes secciones describiremos parte del trabajo que hicimos para que Gloo quedara delante de la API y pudiera ser utilizado por algunas integraciones de socios realmente interesantes.

Definir una ruta de migración (si ya usan tu API)

La API de Snyk recibe tráfico constantemente, así que poner Gloo delante no era una opción viable. Como mencionamos antes, históricamente la API para clientes usaba exclusivamente claves de API para autenticar solicitudes. Pero el cambio para permitir JWT y claves de API en el API Gateway creó una división entre lo antiguo y lo nuevo.

Por suerte, al equipo ya le entusiasmaba cambiar nuestro dominio de API de https://snyk.io/api/ a https://api.snyk.io. Pero no queríamos redirigir todas las solicitudes de nuestro DNS original al nuevo si íbamos a poner delante el nuevo API Gateway. En cambio, estamos implementando una versión canary del API Gateway, con tráfico distribuido por porcentajes, en nuestro dominio de API anterior.

En otras palabras, actualmente estamos enviando parte del tráfico de nuestro DNS original al API Gateway. El resto se envía al monolito para que tome las decisiones de authN.

Gloo admite versiones canary de forma predeterminada. Pero como todavía no hemos puesto el Gateway delante de todo el tráfico de la API, estamos usando el patrón de cambio de tráfico de Envoy Proxy. La siguiente figura muestra un ejemplo general de cómo funciona y cómo podría aplicarse en tu caso.

Diagrama que muestra al proxy Envoy enrutando el tráfico de API entre una API Gateway y un monolito, con flujos de tráfico de x % y 100-x % hacia una API compartida.

Trasladar la validación de JWT al edge

Aunque la prueba de concepto de OAuth mencionada anteriormente implementaba OAuth, estaba demasiado acoplada a nuestro concentrador de identidad (y se había implementado en nuestro monolito). Esta nueva biblioteca de authN debía validar el JWT enviado desde el concentrador de identidad, de una forma similar a esta:

  • Validar el contenido del JWT (sub, iat, aud)

  • Validar la firma del JWT mediante endpoints de JWKs (JSON Web Key Sets)

Aunque técnicamente es un desafío sencillo, normalmente requiere bastante código (menos de 100 líneas), sin contar las pruebas. Lo mismo puede lograrse agregando menos de 20 líneas de código a tu VirtualService en Gloo:

jwtStaged:
 beforeExtAuth:
   providers:
     snyk:
       issuer: <a valid jwt issuer> # where did the token come from?
       audiences:
         - <a valid jwt audience> # what service expects the token?
       tokenSource:
         headers: # Regex currently not supported
           - header: Authorization
             prefix: "Bearer"
           - header: Authorization
             prefix: "bearer"
       jwks:
         remote:
           upstreamRef:
             name: <upstream name>
             namespace: <upstream namespace>
           url: <a valid jwks endpoint>

Esta configuración extrae el JWT del encabezado y realiza algunos pasos básicos de validación antes de enviarlo a un complemento de autorización externa (ExtAuth). ¡Más sobre esto después!:

  • Validar que la hora actual esté dentro de los límites de las declaraciones iat (fecha de emisión) y exp (fecha de vencimiento) del JWT

  • Validar la audiencia

  • Validar el emisor

  • Validar la firma mediante un endpoint de JWK externo (upstream)

¡Pudimos trasladar gran parte de la validación del monolito al edge! Genial, ¿no? ??

Unificar las estrategias de authN

Aunque validemos los JWT en el edge, solo ayudamos a nuestro sistema al quitarle esa carga al monolito. Como quizá dedujiste por el título y la introducción de este artículo, simplemente validar los JWT en el edge no es suficiente. También queremos trasladar al edge todas las decisiones de authN, para que Gloo pueda tomarlas según el material de claves que proporcione el usuario.

Para hacerlo posible, incorporamos un complemento de autorización externa (ExtAuth), un tipo de complemento exclusivo creado por Gloo (disponible solo en su paquete Enterprise), escrito en Go y compilado en un filtro de autorización externa de Envoy. El complemento primero identifica el tipo de material de claves que proporcionó el usuario y establece su identidad. Una vez establecida, firma el token criptográficamente y lo envía a la API downstream, que valida la firma del token y realiza la operación solicitada en nombre del usuario. La siguiente figura muestra un ejemplo sencillo de cómo podría verse.

Diagrama de flujo que muestra claves de API, JWT y futuras estrategias de autenticación que ingresan a una puerta de enlace de API y un complemento ExtAuth, que envían tokens firmados a tres servicios.

En otras palabras, en este punto creamos un token interno que podría usar cualquier servicio de nuestro clúster y que contiene información del usuario que puede asociarse con un usuario de nuestra base de datos. Los servicios a los que Gloo dirige el tráfico se aseguran de que Gloo haya firmado el JWT. Quizá no parezca mucho, pero antes teníamos que solicitar explícitamente los datos del usuario a nuestro monolito para obtener información sobre su identidad desde cada servicio.

Además, Gloo permite que nuestros servicios administren un solo método de authN, mientras Gloo se encarga de la complejidad de gestionar varias estrategias de authN en el edge.

Todo esto se logra con relativamente poco esfuerzo y con pocas líneas de código (la mayoría es código repetitivo creado por Solo), en comparación con implementar estrategias de authN personalizadas en cada servicio.

Próximos pasos

En los próximos sprints, el equipo de Extensibilidad se enfocará en dos áreas clave relacionadas con nuestro API Gateway:

  • Permitir poco a poco que Gloo gestione todo nuestro tráfico de API (es decir, ¡una versión canary!).Queremos empezar a dirigir el tráfico «normal», que no es específico de socios, a través de nuestro API Gateway. Esto implica implementar la observabilidad y las alertas necesarias, y asegurarnos de que nuestros ingenieros de guardia puedan dar soporte a la nueva infraestructura. También implica hacer el trabajo complejo de dirigir a Envoy Proxy de Gloo cierto porcentaje del tráfico que recibe actualmente el punto de entrada de la API.

  • Ampliar Gloo para que valide solicitudes en el edge.Actualmente, Gloo no admite esta función de forma predeterminada.

Esperamos que esta publicación te haya resultado útil si estás pensando en usar Gloo en tu entorno. En próximas publicaciones, veremos cómo Gloo ha proporcionado a nuestros equipos de Ingeniería y Producto una excelente base de observabilidad y cómo nos impulsó a mejorar nuestras prácticas de CI/CD en Snyk.

¿Quieres formar parte de un equipo de ingeniería de vanguardia? Tenemos vacantes en todo el mundo.

Leer más

blog feature snyk container custom base recommendations
Blog

Presentamos Evo Agentic AppSec: seguridad que sigue el ritmo del desarrollo con IA

El desarrollo impulsado por IA avanza más rápido que los flujos de trabajo de seguridad tradicionales. Agentic AppSec de Snyk usa agentes de seguridad para encontrar, corregir y verificar vulnerabilidades de forma continua, mientras las personas establecen el nivel.

feature insights context
Blog

Los ataques autónomos ya están aquí. La defensa debe estar a su altura.

Los atacantes autónomos están reduciendo el tiempo disponible para defenderse. Descubre cómo el descubrimiento, la corrección, la validación y la prevención continuos pueden ayudar a los equipos de seguridad a seguirles el ritmo.

Blog

Por qué los agentes de programación con IA siguen generando fallas de control de acceso

Los agentes de programación con IA pueden generar lógica de autorización que compila y supera la revisión, pero expone los datos de un inquilino a otro. Descubre por qué es difícil detectar el control de acceso roto y cómo prevenirlo.