Skip to content
Ingeniería

Arquitectura BYOK: Cómo JieGou Enruta Llamadas LLM Sin Ver Sus Datos

Un recorrido técnico de nuestro sistema Bring Your Own Key — cifrado AES-256-GCM, enrutamiento de proveedores por llamada, circuit breakers, control de concurrencia y la filosofía de diseño fail-open.

JT
JieGou Team
· · 6 min de lectura

Cuando diseñamos la capa de LLM de JieGou, teníamos una restricción que la mayoría de las plataformas no tienen: los clientes deberían poder usar sus propias claves API, y nosotros nunca deberíamos ver las claves en texto plano en reposo. Este artículo cubre cómo funciona nuestro sistema Bring Your Own Key (BYOK), el esquema de cifrado, la arquitectura de enrutamiento de proveedores y las protecciones que mantienen todo funcionando de manera confiable.

Por Qué Importa BYOK

La mayoría de las plataformas de IA reenvían sus llamadas a través de sus propias claves API. Eso significa que sus datos fluyen a través de sus cuentas, su uso está sujeto a sus límites de velocidad, y usted no tiene control sobre qué modelos o endpoints se usan.

Con BYOK, cada cliente conecta sus propias claves API de Anthropic, OpenAI o Google. Las llamadas van directamente al proveedor usando las credenciales del cliente. JieGou orquesta el workflow pero no ve la carga útil de la solicitud o respuesta cuando las claves BYOK están en uso.

Cifrado de Claves: AES-256-GCM

Las claves API se cifran en reposo usando AES-256-GCM con un vector de inicialización de 12 bytes y un tag de autenticación de 16 bytes. La clave de cifrado es un valor de 256 bits derivado de una cadena hexadecimal de 64 caracteres almacenada como variable de entorno — nunca toca la base de datos.

El formato de almacenamiento es una concatenación codificada en Base64 de IV + authTag + ciphertext. Almacenamos un prefijo seguro de 8 caracteres junto con ella para fines de visualización (“sk-proj…”) para que los usuarios puedan identificar qué clave está almacenada sin descifrarla.

Las claves se almacenan en una colección de Firestore account_api_keys con campos para el ID de cuenta, nombre del proveedor, blob de clave cifrada y un indicador de validez.

Flujo de Resolución de Claves

Cuando un paso de workflow necesita llamar a un LLM, el resolutor de claves ejecuta esta secuencia:

  1. Control de plan — Verificar si la suscripción de la cuenta permite BYOK (en caché en Redis con un TTL de 10 minutos).
  2. Búsqueda en caché de Redis — Las claves descifradas se almacenan en caché durante 5 minutos. Un valor centinela (__none__) indica que una clave fue buscada previamente y no existe, evitando lecturas repetidas de Firestore.
  3. Búsqueda en Firestore — Si el caché falla, obtener de account_api_keys.
  4. Verificación de validez — Omitir claves que han sido marcadas como inválidas por el sistema de auto-invalidación.
  5. Descifrado — El descifrado AES-256-GCM ocurre al vuelo, en memoria.
  6. Fail-open — Si algo sale mal en cualquier paso, recurrir a la clave API propia de la plataforma. Nunca degradar la experiencia del usuario.

El diseño fail-open es deliberado. Si Redis está caído, si el descifrado falla, si la lectura de Firestore da error — el workflow aún se ejecuta, solo usando claves de la plataforma. Los usuarios ven su trabajo completado en lugar de recibir un error críptico.

Enrutamiento de Proveedores

La capa de LLM está construida sobre el SDK de IA de Vercel con una abstracción de proveedor que soporta Anthropic, OpenAI y Google. Cada proveedor tiene dos rutas de instanciación:

Clave de plataforma (singleton) — Una instancia compartida creada al inicio, usada para cuentas del plan gratuito o como respaldo BYOK.

BYOK (efímera) — Una nueva instancia de proveedor creada por llamada con la clave descifrada del cliente. Esta instancia no se almacena en caché — se usa para una solicitud y se descarta, para que las claves descifradas no permanezcan en memoria.

Los workflows pueden especificar diferentes modelos por paso. Un pipeline de contenido podría usar Claude para escritura con matices en el paso 1 y GPT para extracción de datos estructurados en el paso 2. El enrutamiento de proveedores maneja esto de forma transparente.

Auto-Invalidación

Cuando una llamada LLM devuelve un error de autenticación (HTTP 401, 402 o 403, o cuerpos de respuesta que coinciden con patrones como “invalid api key” o “unauthorized”), el sistema automáticamente marca esa clave como inválida en Firestore y la elimina del caché de Redis.

El usuario recibe un mensaje claro: “Su clave API de {Provider} es inválida o ha sido revocada. Por favor actualice su clave API en Configuración de Cuenta.” Las llamadas subsiguientes recurren a claves de la plataforma hasta que el usuario proporcione una nueva clave.

Verificamos contra 11 patrones de error conocidos entre proveedores. Esto captura claves rotadas, claves revocadas y claves que han excedido sus límites de gasto.

Circuit Breaker

Cada proveedor de LLM tiene un circuit breaker por proveedor (no por cuenta — un solo proveedor caído afecta a todos).

El breaker se dispara después de 5 errores dentro de una ventana de 60 segundos. Una vez abierto, permanece abierto durante 30 segundos antes de permitir una sola solicitud de prueba (estado half-open). Si la prueba tiene éxito, el circuito se cierra.

Solo los fallos del lado del servidor cuentan: respuestas 5xx, timeouts y errores de conexión. Los errores del cliente (4xx) como clave API inválida no disparan el breaker — esos son manejados por la auto-invalidación.

El circuit breaker en sí es fail-open. Si Redis no está disponible para el rastreo de estado, todas las solicitudes se dejan pasar. Esto es consistente con nuestra filosofía general: cuando la infraestructura está degradada, deje que el trabajo del usuario proceda.

Control de Concurrencia

Cada cuenta está limitada a 10 llamadas LLM concurrentes mediante un semáforo basado en Redis. Esto previene que una gran ejecución por lotes de una sola cuenta consuma todas las conexiones disponibles a un proveedor.

El semáforo usa INCR/DECR con una red de seguridad de TTL de 5 minutos (si un proceso se cae sin decrementar, el contador expira automáticamente). Al exceder la capacidad, el contador se decrementa inmediatamente para evitar una fuga. Como todo lo demás, es fail-open en errores de Redis.

Lecciones Aprendidas

Fail-open es el valor predeterminado correcto para funciones opcionales. BYOK es una mejora, no un requisito. Si el pipeline de cifrado, la capa de caché o la resolución de claves falla, el usuario aún debería poder ejecutar su workflow. Registramos el fallo para investigación pero nunca bloqueamos la ejecución.

Los valores centinela de caché previenen la estampida. Sin el centinela __none__, una cuenta sin claves BYOK consultaría Firestore en cada llamada LLM. Cachear el resultado negativo durante 5 minutos mantiene las lecturas de Firestore predecibles.

Las instancias efímeras de proveedor previenen la fuga de claves. Al crear una nueva instancia de proveedor por llamada y dejar que sea recolectada por el garbage collector, minimizamos la ventana donde una clave descifrada existe en memoria. No es tan fuerte como un módulo de seguridad de hardware, pero es una reducción significativa en la superficie de ataque para una aplicación SaaS.

Circuit breakers por proveedor con concurrencia por cuenta es la granularidad correcta. Las caídas de proveedores son eventos globales; la concurrencia es una preocupación por inquilino. Mezclarlos sería demasiado agresivo (romper una cuenta rompe el breaker para todos) o demasiado permisivo (sin protección contra fallos a nivel de proveedor).

security byok architecture privacy encryption
Compartir este artículo

¿Le gustó este artículo?

Reciba consejos sobre flujos de trabajo, actualizaciones de producto y guías de automatización en su bandeja de entrada.

No spam. Unsubscribe anytime.