Seguridad · Korpex Copiloto
Doc público. Última actualización: 2026-09-04 (incluye ADR-042 hardening + ADR-043 notificaciones personalizables).
Korpex Copiloto maneja información sensible de negocios locales (finanzas, contactos, empleados, documentos, tokens OAuth de plataformas externas). Este documento describe qué medidas concretas tomamos para protegerla — no como marketing sino como referencia técnica auditable por vos, tu contador, tu equipo IT o quien necesite validarlo.
1. Autenticación
Login
- Contraseñas hasheadas con bcrypt (Supabase Auth managed). Nunca
guardamos el texto plano.
- Política de contraseñas: mínimo 12 caracteres, con mayúscula,
minúscula, número y símbolo. Rechazamos passwords débiles en creación y cambio.
- Rate limit anti-brute-force: 10 intentos fallidos por email cada
15 minutos → lockout automático. 30 fallos por IP cada 15 min → IP bloqueada.
- Sin user enumeration: el mensaje "correo o contraseña incorrectos"
es idéntico si el email existe o no. No damos pistas al atacante.
MFA (segundo factor)
- TOTP (Time-based One-Time Password) compatible con Google
Authenticator, Authy, 1Password, Microsoft Authenticator y demás.
- Obligatorio para administradores de la plataforma. **Opcional pero
recomendado** para dueños de negocio.
- Setup en
/app/[tenant]/config/seguridad.
Sesiones
- Cookies HttpOnly + SameSite=Lax (bloquea CSRF cross-site).
- Refresh automático server-side (Supabase SSR).
- Cambio de contraseña invalida sesiones activas en otros dispositivos.
2. Autorización y aislamiento
Row-Level Security (RLS)
- 100% de las tablas de datos del tenant tienen RLS habilitado en
PostgreSQL.
- Cada request lleva un header
x-tenant-idque la política de RLS usa
para filtrar filas — un tenant no puede leer datos de otro incluso si hubiera un bug en la capa app.
- Los admins de tenant se autorizan por
tenant_members(tabla ligada
a auth.uid()), no por email compartido.
Empleados con permisos granulares
- Cada empleado que use el bot tiene una lista blanca de qué
sub-agentes puede invocar (ej: "solo tareas y jornadas, nada de finanzas").
- El sub-agente que le queda fuera de scope literalmente no aparece en
el prompt del LLM del empleado — no puede pedírselo ni por accidente.
Historial aislado
- Cada usuario de Telegram (dueño, empleado A, empleado B) tiene su
propio hilo de conversación filtrado por telegram_user_id. Nadie ve el chat de nadie más.
3. Cifrado
En tránsito
- HTTPS forzado (HSTS con `max-age=63072000; includeSubDomains;
preload`). Un browser que ya nos visitó rechaza descargas por HTTP.
- Conexión a Supabase por TLS. Conexión a Telegram, Notion, Canva,
Google APIs por HTTPS.
En reposo
- Tokens OAuth de Notion, Canva, Google Calendar/Drive/Gmail se
guardan cifrados con AES-256-GCM en Supabase. Un dump de base de datos comprometido no expone los tokens sin la master key (que vive en Vercel envs como sensitive).
- Contraseñas nunca se guardan cifradas ni en claro — solo hash bcrypt.
4. Perímetro
Rate limiting
Dos capas:
- Vercel Firewall (edge): límites por path + geo-block admin +
deny scans automáticos + Bot Protection + AI Bots.
- App layer (Upstash Redis): límites por acción (login, webhook
Telegram, uploads, búsquedas, OAuth start).
Security headers
Aplicados en toda respuesta:
Content-Security-Policy(whitelist estricta de dominios permitidos).Strict-Transport-Security(2 años + preload).X-Frame-Options: DENY(previene clickjacking).X-Content-Type-Options: nosniff.Referrer-Policy: strict-origin-when-cross-origin.Permissions-Policy(bloquea camera/microphone/USB/magnetometer/etc).Cross-Origin-Opener-PolicyyCross-Origin-Resource-Policy.
CSRF
- Verificación de
Originheader en cada request POST/PATCH/DELETE. - Solo dominios en whitelist (app.korpex.co, korpex.co) pueden mandar
writes. Excepciones documentadas para webhooks OAuth de terceros.
Body size + timeouts
- Payload máximo 512KB en webhooks públicos.
maxDurationde 60s (webhook Telegram, IA) evita que un attacker
cuelgue funciones para siempre.
5. Audit trail
Cada evento de seguridad relevante queda registrado:
- Logins exitosos y fallidos (con hash del email + IP + user agent).
- Cambios de contraseña.
- MFA enroll / unenroll.
- OAuth connect / revoke.
- Acciones de admin (crear cliente, borrar, editar).
- Bindings de Telegram creados / revocados.
- Lockouts por rate limit.
- Alertas de seguridad detectadas.
Retención: 180 días (borrado automático nightly).
Los admins ven todo el audit en /app/admin/security. Los dueños de tenant ven solo lo que aplica a su negocio (por RLS).
6. Retention de datos
| Tipo de dato | Retención |
|---|---|
| Datos del negocio (tareas, contactos, finanzas) | Indefinido, hasta borrar por el dueño |
Conversaciones con el bot (ai_activity_log) | 90 días |
| Audit log de seguridad | 180 días |
| Intentos de vinculación Telegram | 30 días |
| Registro de envíos de notificaciones (dedup diario) | 60 días |
| CSRF states OAuth (temporales) | 10 min |
7. Terceros y datos que compartimos
Datos del tenant NUNCA se comparten con nadie fuera del tenant. Los terceros a los que llamamos son proveedores de infraestructura, no consumidores de tus datos:
- Supabase (Postgres managed) — hosting de BD, con RLS y cifrado.
- Vercel (hosting Next.js) — logs de request agregados 30 días.
- Vercel AI Gateway (LLMs) — cada mensaje al bot pasa por
OpenAI/Google/Anthropic. Ninguno guarda tus mensajes bajo "zero data retention" que aplicamos.
- Upstash Redis — contadores de rate limit (no data de negocio).
- Notion / Canva / Google — solo cuando el dueño conecta la
integración voluntariamente. Los tokens viven cifrados con vos.
- Sentry (opcional, si activado) — errores del sistema sin
payloads sensibles.
Ningún dato de un tenant se usa para entrenar modelos de IA de terceros. La política del AI Gateway prohíbe explícitamente ese uso.
8. Rotación de secrets
Rotamos periódicamente:
- Tokens de bot Telegram y webhook secret: cada 90 días.
- Service role keys de Supabase: cada 90 días.
- Cron secret: cada 90 días.
- Master key de cifrado: solo bajo sospecha de compromiso (requiere
re-cifrar tokens de todos los tenants — proceso documentado).
Ver docs/security-secret-rotation.md (interno) para el proceso.
9. Contacto de seguridad
Si encontrás una vulnerabilidad, reportala directamente a: davidcuervo399@gmail.com con "SECURITY" en el asunto. Respondemos en < 48 h.
No divulgues públicamente hasta que tengamos un fix aplicado. Te mencionamos en el changelog si querés.
10. Compliance y estándares que seguimos
- OWASP ASVS 4.0 — Application Security Verification Standard.
- OWASP Top 10 — cubierto para todos los ítems relevantes a nuestro
stack (Broken Access Control, Cryptographic Failures, Injection, Insecure Design, Security Misconfiguration, Vulnerable Components, Auth Failures, Software Integrity, Logging Failures, SSRF).
- NIST SP 800-63B — política de passwords sin rotación forzada.
- RFC 7591 (Dynamic Client Registration) + PKCE para OAuth 2.1
contra los MCPs.
No aplicamos ni buscamos SOC 2 / ISO 27001 / HIPAA / PCI todavía — somos una startup pequeña sin obligación regulatoria hoy. Cuando manejemos datos de pagos directos o salud, subimos el nivel.