Docs

Seguridad de Red

Modelo de seguridad por capas: Cloudflare Edge, Worker proxy, Zero Trust Access, y autenticación aplicativa

v1.1PublicadoMarzo 2026Equipo de desarrollo, arquitectos, stakeholders

1. Visión General — Modelo de 4 Capas

Nvito implementa un modelo de seguridad en profundidad (defense-in-depth) con 4 capas independientes. Cada capa actúa como un filtro: si una falla, las siguientes continúan protegiendo el sistema.

CapaQué protegeAplica a
1. Cloudflare EdgeTráfico de red (DDoS, bots, exploits conocidos)Todos los subdominios
2. Worker ProxyIP del origin, autenticación API-a-APISolo api.nvito.mx en producción
3. Zero Trust AccessAcceso no autorizado al panel y docsSolo admin.nvito.mx y docs.nvito.mx
4. Auth AplicativaAcceso a datos, RBAC, token theft, CSRF, XSSCada aplicación con su mecanismo

2. Capa 1: Cloudflare Edge

Todo el tráfico hacia nvito.mx y sus subdominios pasa por la red edge de Cloudflare antes de llegar a cualquier origin server. Esta capa es transparente para la aplicación y opera a nivel de red/transporte.

2.1 DDoS Mitigation

Cloudflare provee mitigación automática de DDoS en 3 niveles:

NivelTipo de ataqueMitigación
L3/L4SYN flood, UDP flood, amplificationFiltrado automático en el edge, sin configuración
L7HTTP flood, slowloris, request burstsAnálisis de patrones + challenge automático
DNSDNS amplification, query floodAnycast absorbe el volumen

La mitigación L3/L4 está siempre activa en todos los planes de Cloudflare (incluido Free). La mitigación L7 se beneficia del plan Pro para reglas WAF gestionadas adicionales.

2.2 WAF (Web Application Firewall)

FuncionalidadPlan FreePlan Pro
Cloudflare Managed RulesetSi (reglas criticas)Si (completo: SQLi, XSS, RCE, etc.)
OWASP Core RulesetParcial (solo reglas criticas)Completo
Custom Rules5 reglas20+ reglas
Rate Limiting Rules1 regla5+ reglas
Security LevelConfigurableConfigurable

Nvito actualmente opera en el plan Free con el Cloudflare Managed Ruleset desplegado. Este ruleset incluye reglas criticas de protección pero el OWASP Core Ruleset completo requiere el plan Pro ($20/mes). La protección actual se complementa con:

  • Custom rules para bloquear User-Agents sospechosos
  • Rate limiting configurado: 100 req/min por IP para DEV/TEST
  • Bot Fight Mode habilitado
  • Cache Rules: bypass de cache para subdominios dev-* y test-*

Plan Pro para producción

Se recomienda activar el plan Pro de Cloudflare ($20/mes) al lanzar a producción para obtener las managed rules WAF. Mientras tanto, la aplicación implementa sus propias validaciones contra SQLi y XSS a nivel de código (Zod validation, DOMPurify, CSP).

2.3 SSL/TLS

ConfiguraciónValor
ModoFull (Strict)
TLS mínimo1.2
HSTSmax-age=31536000; includeSubDomains
HTTPS RedirectAutomático (Always Use HTTPS)
Certificate TransparencyHabilitado

El modo Full (Strict) significa que Cloudflare verifica que el certificado del origin sea válido y no este expirado. Esto previene ataques man-in-the-middle entre Cloudflare y el origin.

2.4 Rate Limiting (3 capas)

Nvito implementa rate limiting en 3 capas independientes que se complementan:

CapaReglaAplica aThresholdAcción
CloudflareAPI Rate Limitapi.nvito.mx/*100 req/min por IPBlock (429)
nvito-apiUserThrottlerGuardTodos los endpoints autenticadosConfigurable por endpoint429 por usuario
nvito-invitationsRate limiter in-memory/api/revalidate10 req/IP/60s429 con Retry-After

2.5 Bot Fight Mode

Bot Fight Mode está habilitado en Cloudflare. Analiza patrones de comportamiento (fingerprinting JS, headless browser detection, TLS fingerprint) y desafía automáticamente a bots sospechosos sin afectar a usuarios legítimos.

3. Capa 2: Cloudflare Worker (API Proxy)

En producción, api.nvito.mx no apunta directamente a Railway. En su lugar, un Cloudflare Worker intercepta todas las requests y las redirige al origin después de inyectar un token de autenticación API-a-API.

3.1 Arquitectura del Worker

3.2 Beneficios del Worker Proxy

BeneficioDetalle
IP del origin ocultaLa URL pública de Railway (*.up.railway.app) nunca se expone. El tráfico solo llega vía Cloudflare.
Autenticación API-a-APIEl header X-CF-API-Token garantiza que solo requests que pasen por Cloudflare llegan al backend. Requests directas a Railway son rechazadas con 403.
Edge computingEl Worker corre en 300+ data centers de Cloudflare. La latencia de inyección del header es de menos de 1ms.
Rate limiting dobleCloudflare rate-limita en el edge; el backend puede aplicar su propio rate limiting adicional.

3.3 Límites del Free Tier

RecursoLímite Free
Requests/dia100,000
CPU time/request10ms
Script size1 MB
Subrequests/request50

Con el tráfico esperado en las primeras fases de Nvito, el free tier es más que suficiente. El Worker es extremadamente ligero (solo inyecta un header y hace un fetch al origin).

3.3 CloudflareTokenGuard (nvito-api)

En el lado del backend, nvito-api implementa un guard global llamado CloudflareTokenGuard que valida el header X-CF-API-Token inyectado por el Worker.

AspectoDetalle
Archivosrc/common/guards/cloudflare-token.guard.ts
PosiciónPrimer guard global (antes de ClerkAuthGuard)
ComparaciónTiming-safe (crypto.timingSafeEqual) para prevenir timing attacks
BypassEn desarrollo/test, si CF_API_TOKEN no está configurado, el guard permite el paso
Tests9 tests unitarios cubriendo token válido, inválido, ausente y bypass

Cadena de guards actualizada para cada request:

3.4 Configuración del Worker

VariableValorTipo
CF_API_TOKENToken secreto compartidoSecret (Cloudflare Worker + Railway)
RAILWAY_API_URLhttps://nvito-api-production.up.railway.appVariable de entorno

El Worker es extremadamente ligero: solo inyecta el header y hace un fetch al origin. Latencia agregada inferior a 1ms.

Solo en producción

El Worker proxy solo se usa en producción (api.nvito.mx). En DEV y TEST, los subdominios dev-api.nvito.mx y test-api.nvito.mx apuntan directamente al VPS via registro A. El CloudflareTokenGuard detecta automáticamente la ausencia de CF_API_TOKEN y permite el paso en estos ambientes.

4. Capa 3: Cloudflare Access (Zero Trust)

Cloudflare Access protege subdominios seleccionados con autenticación Zero Trust antes de que el request llegue al origin. Actúa como un reverse proxy de identidad.

4.1 Subdominios Protegidos

SubdominioProtegido por CF AccessRazón
admin.nvito.mxSiPanel administrativo con datos sensibles
dev-admin.nvito.mxSiMismo contenido que producción, datos de desarrollo
test-admin.nvito.mxSiMismo contenido que producción, datos de QA
docs.nvito.mxSiDocumentación técnica confidencial
api.nvito.mxNoAPI pública consumida por clientes programáticos
app.nvito.mxNoPWA pública para invitados (auth propia via BFF)
inv.nvito.mxNoInvitaciones públicas para invitados finales

4.2 Flujo de Autenticación

4.3 Configuración de Access

ParámetroValor
Organización Zero TrustCreada en Cloudflare
Identity ProviderOne-time PIN (email OTP)
Método de autenticaciónEmail OTP (One-Time Pin)
Emails permitidosLista explícita de emails autorizados
Duración de sesión24 horas
ReautenticaciónCada 24 horas o al cerrar el browser
Usuarios incluidos en FreeHasta 50 usuarios

Doble autenticación en admin

Para acceder a admin.nvito.mx, un usuario debe pasar dos capas de autenticación independientes: primero Cloudflare Access (email OTP) y luego Clerk (email + password). Esto es intencional: CF Access protege a nivel de red, Clerk protege a nivel de aplicación con RBAC granular.

4.4 Aplicaciones Access

Se han configurado 2 aplicaciones en Cloudflare Access, una para cada ambiente no productivo:

AplicaciónSubdominios protegidos
Nvito DEV Environmentdev-api.nvito.mx, dev-admin.nvito.mx, dev-app.nvito.mx, dev-inv.nvito.mx, dev-landing.nvito.mx
Nvito TEST Environmenttest-api.nvito.mx, test-admin.nvito.mx, test-app.nvito.mx, test-inv.nvito.mx, test-landing.nvito.mx

En producción, solo admin.nvito.mx y docs.nvito.mx están protegidos por CF Access. Los demás subdominios de producción son públicos (la autenticación se maneja en la capa 4).

4.5 Políticas de Access

Las políticas definen quién puede acceder a cada aplicación protegida:

Politicas de Cloudflare Access

Aplicacion: Nvito DEV Environment/
├── Policy: Allow Team Members/
├── Include: Emails ending in @nvito.mx
└── Include: Specific emails (founders, devs)
└── Policy: Deny Everyone Else/
└── Default deny all
Aplicacion: Nvito TEST Environment/
├── Policy: Allow Team Members/
├── Include: Emails ending in @nvito.mx
└── Include: Specific emails (founders, devs, QA)
└── Policy: Deny Everyone Else/
└── Default deny all
Aplicacion: nvito-admin (PROD)/
├── Policy: Allow Team Members/
├── Include: Emails ending in @nvito.mx
└── Include: Specific emails (founders, devs)
└── Policy: Deny Everyone Else/
└── Default deny all
Aplicacion: nvito-docs (PROD)/
├── Policy: Allow Development Team/
├── Include: Emails ending in @nvito.mx
└── Include: Specific emails (stakeholders)
└── Policy: Deny Everyone Else/
└── Default deny all

5. Capa 4: Autenticación Aplicativa

Cada aplicación de Nvito implementa su propio mecanismo de autenticación adaptado a su caso de uso.

5.1 nvito-admin — Clerk SSO + RBAC

AspectoDetalle
ProviderClerk 6 (Next.js SDK)
MétodoEmail + password, con opción de OTP
TokenJWT firmado por Clerk, verificado en backend
RBAC8 roles, 40+ permisos granulares
Guards (backend)ClerkAuthGuard + RoleGuard + AdminPanelGuard
Multi-orgHeader X-Organization-Id para Super/Platform Admin

Cadena de guards para cada request del admin:

5.2 nvito-pwa — BFF con Cookies HttpOnly

AspectoDetalle
PatrónBackend-For-Frontend (BFF)
TokensJWT almacenados en cookies HttpOnly encriptadas (AES-256-GCM)
Cookies__Host-nvito-at (access, 15min), __Host-nvito-rt (refresh, 30d)
CSRFDouble-submit: cookie __Host-nvito-csrf + firma HMAC-SHA256 en __Host-nvito-csrf-sig
ProxyTodo pasa por /api/proxy/* → descifra JWT → forward a nvito-api
CSPconnect-src 'self' bloquea llamadas directas al API desde JS

5.3 nvito-client — JWT Independiente

AspectoDetalle
AuthJWT propio (independiente de Clerk)
Storageexpo-secure-store (encriptado en dispositivo)
Guard (backend)MobileAuthGuard (verifica JWT mobile)
Login HostCódigo de evento + PIN
Login GuestAccess token via deep link / QR
Auto-refreshProactivo antes de expiración

5.4 nvito-invitations — Sin Autenticación

AspectoDetalle
AuthNinguna (contenido público)
ProtecciónValidación de slug (regex + longitud), DOMPurify, CSP strict
SSRF preventionvalidateCdnUrl() contra whitelist de hosts CDN
XSS preventionescapeJsString() + escapeHtmlAttr() context-aware
Frame protectionX-Frame-Options: DENY en rutas públicas

5.5 Tabla Comparativa

Featurenvito-adminnvito-pwanvito-clientnvito-invitations
Autenticación externaClerk SSOJWT vía BFFJWT propioNinguna
Tokens en browser JSNoNoNo
CSRF protectionClerk built-inDouble-submit HMACN/A (nativo)N/A (read-only)
Rate limitingUserThrottlerGuardBFF + APIAPI guardCloudflare edge
RBAC8 roles, 40+ permsHOST/GUESTHOST/GUESTN/A
Multi-orgNoNoNo
CF AccessNoNoNo
CSP headersNo

6. Headers de Seguridad por Proyecto

Cada proyecto configura sus propios headers de seguridad HTTP, adaptados a su caso de uso.

6.1 Headers Comunes

HeaderValorPropósito
Strict-Transport-Securitymax-age=31536000; includeSubDomainsForzar HTTPS durante 1 año
X-Content-Type-OptionsnosniffPrevenir MIME type sniffing
Referrer-Policystrict-origin-when-cross-originLimitar info en header Referer
Permissions-Policycamera=(), microphone=(), geolocation=()Deshabilitar APIs sensibles

6.2 Content-Security-Policy por Proyecto

nvito-admin (next.config.ts):

default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.clerk.accounts.dev;
connect-src 'self' https://api.nvito.mx https://*.clerk.accounts.dev;
img-src 'self' https://cdn.nvito.mx https://img.clerk.com data:;
frame-src https://*.clerk.accounts.dev;

nvito-pwa (next.config.ts):

default-src 'self';
script-src 'self' 'unsafe-inline';
connect-src 'self';  /* Solo BFF local, bloquea API directa */
img-src 'self' https://cdn.nvito.mx data:;

nvito-invitations (next.config.mjs):

/* Rutas públicas /i/* */
default-src 'self';
script-src 'self' 'unsafe-inline';
frame-ancestors 'none';  /* No permitir embeds */

/* Rutas preview /preview/* */
frame-ancestors 'self' https://admin.nvito.mx https://dev-admin.nvito.mx;

6.3 X-Frame-Options

ProyectoValorRazón
nvito-adminSAMEORIGINPermite iframes internos (preview de invitaciones)
nvito-invitations (público)DENYLas invitaciones no deben embeberse en sitios externos
nvito-invitations (preview)SAMEORIGINPermite preview iframe desde el admin
nvito-pwaDENYLa PWA no debe embeberse

7. Ataques Mitigados

La siguiente tabla resume los vectores de ataque más relevantes y cómo cada capa los mitiga.

Vector de AtaqueCapaMecanismo de Mitigación
DDoS volumétrico (L3/L4)1 - CF EdgeAnycast absorbe volumen, filtrado automático
DDoS aplicativo (L7)1 - CF EdgeRate limiting, JS Challenge, Bot Fight Mode
Brute force login1 + 3 + 4Rate limiting CF + CF Access OTP + Clerk lockout
SQL Injection4 - AppPrisma ORM (parametrizado), Zod validation
XSS reflejado1 + 4WAF (Pro), CSP headers, React auto-escape, DOMPurify
XSS almacenado4 - AppDOMPurify en invitaciones, escapeJsString(), CSP
CSRF4 - AppClerk built-in (admin), double-submit HMAC (PWA)
Token theft (XSS)4 - AppCookies HttpOnly AES-256-GCM (PWA), SecureStore (mobile)
SSRF4 - AppvalidateCdnUrl() whitelist en invitaciones
Direct origin access2 - WorkerHeader X-CF-API-Token requerido en producción
Man-in-the-middle1 - CF EdgeTLS 1.2+, HSTS, Full (Strict) SSL
Session hijacking3 + 4CF Access session 24h, Clerk session management
Credential stuffing1 + 3Rate limiting + CF Access email whitelist
Clickjacking4 - AppX-Frame-Options: DENY, frame-ancestors 'none'
MIME confusion4 - AppX-Content-Type-Options: nosniff
Timing attacks4 - Appcrypto.timingSafeEqual() en invitaciones

Defense in depth

Ningún mecanismo individual es infalible. La fortaleza del modelo radica en que cada capa compensa las debilidades de las otras. Un atacante debe evadir todas las capas simultáneamente para comprometer el sistema.

Esta pagina fue util?