Una API externa suele darte una sola credencial: un client ID con su secreto, o un token. En cuanto varias
personas o servicios necesitan esa API, la credencial se copia en cada uno. Rotarla obliga a encontrar todas las
copias. Quitarle el acceso a una persona obliga a rotarla para todos.
La idea
Separar dos cosas que suelen ir juntas: tener una credencial y tener permiso para usarla. Gatekeeper guarda las
credenciales de los proveedores. Los usuarios solo tienen una sesión de Gatekeeper, y un administrador decide a
qué proveedores puede llamar cada uno. La app consumidora nunca ve el secreto del proveedor.
Puedes probarlo en la demo en vivo: entras como un worker con un
proveedor de prueba. Si lo llamas recibes sus datos; si pides cualquier otro, Gatekeeper responde 403. El token
del proveedor nunca llega a la página.
Cómo fluye una llamada
El usuario inicia sesión en Gatekeeper y recibe un token de sesión. La sesión se registra en Redis.
La app envía a Gatekeeper el nombre del proveedor, el método, la ruta y el cuerpo de la llamada que quiere hacer.
Gatekeeper verifica la sesión, carga al usuario desde la base de datos y comprueba que ese proveedor esté en su
lista. Si no está, responde 403.
Carga el registro del proveedor y descifra su secreto, guardado con AES-256-GCM, en el momento de usarlo.
Se autentica como ese proveedor espera (OAuth client credentials, bearer token o basic auth), reenvía la
llamada y devuelve la respuesta.
Los permisos se leen de la base de datos en cada llamada, no van dentro del token. Revocar un proveedor tiene
efecto en la siguiente petición, no cuando caduca el token.
Administración
Los administradores crean y eliminan usuarios, cambian roles entre admin y worker, y conceden o revocan el acceso
a cada proveedor por usuario. Toda operación de administración pasa por un rate limiter, una verificación de
sesión, una de rol y un código TOTP.
Como las sesiones viven en Redis y no solo dentro del token, cerrar sesión invalida de una vez todas las sesiones
activas del usuario.
Los tres flujos tal como los dibujé al diseñar Gatekeeper: alta, administración y la llamada a través del proxy. El diagrama está en inglés.
Sobre qué está construido
TypeScript y Express, MongoDB para usuarios y proveedores, Redis para sesiones. El cifrado, las sesiones, el
cliente HTTP y el acceso a datos vienen de tslib, mi librería compartida de TypeScript, así que las mismas piezas
se reutilizan en mis otros servicios.
La consola web es una app SvelteKit pequeña que funciona como backend for frontend: el navegador nunca habla con
la API, el token de sesión vive en una cookie httpOnly y los secretos de los proveedores son de solo escritura en
las pantallas de administración. Corre en el mismo servidor que la API, así que los límites de peticiones siguen
contando a cada visitante y no a la consola.
Compromisos
Cada llamada que pasa por el proxy depende ahora de Gatekeeper: si cae, esas integraciones caen también, y añade
un salto de red. Centralizar los secretos es el objetivo, y también convierte al servidor de Gatekeeper en la
máquina que más hay que proteger.
Es pequeño a propósito. Autentica, autoriza y reenvía; no es una plataforma de gestión de APIs.