OpenWAF Egress es una pasarela entre tus agentes de IA y los proveedores de modelos a los que llaman. El agente tiene un token de marcador (OWE_TOKEN_…) en lugar de la clave del proveedor. La pasarela revisa cada petición y solo entonces lee la clave real de OpenBao o HashiCorp Vault, la pone en la petición de salida y la reenvía, sin romper el streaming.
Es código abierto con licencia Apache 2.0: github.com/openwaf-dev/egress (enlace externo). La imagen ghcr.io/openwaf-dev/egress se publica para linux/amd64 y linux/arm64, y cada versión trae además binarios para Linux y macOS con sus SHA256SUMS.
En tu equipo o alojada
La misma pasarela funciona de dos formas:
- En tu equipo: arrancas el contenedor junto a tus agentes, con tu propio fichero de configuración y tu propio OpenBao o Vault. El inicio rápido y las páginas que lo siguen describen este modo.
- Alojada en OpenWAF Cloud: tus agentes llaman a
https://egress.openwaf.dev; gestionas los agentes, las claves de los proveedores y las peticiones bloqueadas desde el panel, la API o el servidor MCP, y OpenWAF guarda las claves. Está en acceso anticipado. Mira empezar con el egress alojado.
Por qué una pasarela
Un agente que tiene la clave de un proveedor puede filtrarla: por una inyección de prompt que le pide imprimir su entorno, por una llamada a una herramienta que saca datos o por una dependencia comprometida en su contenedor. Con OpenWAF Egress la clave nunca entra en el proceso del agente. Un marcador robado solo sirve a través de la pasarela, para los destinos que ese agente tiene permitidos y para peticiones que pasen las comprobaciones.
El recorrido de una petición
El agente sigue con su SDK. Solo cambian la URL base y la clave:
baseURL = http://127.0.0.1:8070/v1/agent/<agente>/proxy/<destino>
apiKey = OWE_TOKEN_…Cada petición pasa por cinco pasos, en este orden. El primero que falla responde con un error y no se envía nada al proveedor.
| Paso | Comprobación | Si falla |
|---|---|---|
| 1 | Token del agente: Authorization: Bearer <marcador> tiene que coincidir con el token del agente | 401 |
| 2 | Destinos permitidos: el destino tiene que estar en los allowed_targets del agente | 403 egress_blocked |
| 3 | SSRF: el host del destino solo puede resolver a direcciones públicas | 403 ssrf_blocked |
| 4 | Inspección del cuerpo: detectores de inyección de prompt (enforce_injection) y patrones de fuga de datos (block_dlp) | 403 injection_detected, 403 data_leak_blocked, 413 body_too_large |
| 5 | Clave desde OpenBao: se lee de KV v2 y se pone en la auth_header del destino | 502 credential_resolution_failed |
Después la pasarela reenvía la petición a la base_url del destino y devuelve la respuesta en streaming. Nunca sigue una redirección del proveedor: el 3xx vuelve al agente tal cual.
Rutas
/v1/agent/<agente>/proxy/<destino>/<ruta>: el agente va en la URL. Es la ruta que conviene usar./v1/proxy/<destino>/<ruta>: el agente es aquel cuyotokencoincide con la cabeceraAuthorization, o el que nombra la cabeceraX-OpenWAF-Agent(la pasarela la quita antes de reenviar)./healthy/v1/health: estado de la pasarela y de su conexión con OpenBao, en JSON.
<ruta> y la cadena de consulta se añaden a la base_url del destino. Con la base_url https://openrouter.ai/api/v1, una petición a /v1/agent/my-support-agent/proxy/openrouter/chat/completions va a https://openrouter.ai/api/v1/chat/completions.
Qué detecta
- Inyección de prompt: 27 detectores deterministas en inglés y español, 21 de patrones y 6 de texto oculto o codificado. Sin llamar a ningún modelo. La lista completa está en la página del producto (enlace externo).
- Fugas de datos: números de tarjeta válidos por Luhn, claves privadas PEM, identificadores de clave de AWS, claves
sk-al estilo de OpenAI y tokens de GitHub. - SSRF: loopback, RFC 1918, CGNAT, enlace local (169.254.169.254 incluida), multidifusión, rangos reservados y sus equivalentes IPv6.
La detección es por patrones: frena formas conocidas de inyección y de exfiltración, no demuestra que una petición sea segura. El modelo de seguridad cuenta qué cubre y qué no.
Rendimiento
Medido con go test -bench . ./pkg/aiagents/ en un Mac con Apple Silicon (darwin/arm64):
| Cuerpo | Tiempo de detección por petición |
|---|---|
| Petición de chat de 4 KB | 84 µs |
| Petición de chat de 64 KB | 1,3 ms |
| 64 KB preparados para activar todos los detectores (el peor caso) | 97 ms |
Cada detector solo se ejecuta si aparece alguna de sus palabras clave, así que el tráfico normal se salta casi todos. El binario estático ocupa unos 7 MB.
Siguientes pasos
Escrito a partir de github.com/openwaf-dev/[email protected] (enlace externo).