Saltearse al contenido

Seguridad y multi-tenancy

El aislamiento entre tenants es no negociable (Ley 1581 de Colombia). Se aplica defensa en profundidad con dos capas independientes.

El api-gateway valida el JWT (HS256, AUTH_JWT_SECRET), extrae y valida el workspace_id (UUID) y lo inyecta en el contexto. Sin token válido: 401/403.

Las tablas tenant-scoped tienen políticas RLS (workspace_id = auth.workspace_id()). Pero hay un detalle crítico: la imagen oficial de Postgres crea al usuario de la app como superusuario, y los superusuarios ignoran RLS aun con FORCE.

Por eso, para cada request con contexto de tenant, el pool de conexiones:

  1. Hace SET ROLE bongga_app — un rol no-superusuario (migración 0029).
  2. Fija bongga.current_workspace_id (GUC) que auth.workspace_id() lee.

Bajo ese rol las políticas sí aplican, aunque la app olvide filtrar. Las rutas de sistema / pre-auth (boot, login, OTP, resolución de webhook) hacen RESET ROLE y corren con el rol privilegiado. Es un cambio monótono: sin contexto de workspace se comporta como antes; con contexto la RLS se aplica de verdad.

El cliente trae su propia API key de IA (OpenAI/Anthropic) y paga su WhatsApp/Meta directo. Bongga no absorbe costos de IA ni de conversaciones Meta. Las keys se guardan cifradas en reposo (AES-256-GCM) y se inyectan en runtime.

  • Headers seguros (X-Content-Type-Options, X-Frame-Options, CSP, HSTS).
  • CORS con allowlist explícita (no * en producción).
  • Rate limit por IP y por workspace_id; límite de tamaño de body.
  • Webhooks firmados (HMAC) — WhatsApp y Mercado Pago.
  • Secrets solo por variables de entorno (nunca en código); gitleaks en pre-commit.
  • Logging estructurado con request_id y workspace_id.