Volver al Blog
Seguridad · 14 min lectura

Seguridad, GDPR y Compliance: Cómo Protegemos Cada Byte

Turnstile, Content Security Policy, OAuth PKCE, aislamiento por tenant, cookie consent, derecho al olvido y premium feature guards — la seguridad multi-capa de Cadences explicada pieza a pieza.

Gonzalo Monzón

Gonzalo Monzón

· Fundador & CTO

Seguridad digital y protección de datos
Todas las capas de seguridad activas

La seguridad no es una feature que se añade después. En Cadences, es una decisión arquitectónica que afecta cada capa del stack: desde cómo se aíslan los datos de cada organización hasta cómo se valida un clic en un botón de registro. Este artículo explica el modelo de seguridad completo.

🛡️ Modelo de Defensa en Profundidad

Cadences implementa 7 capas de seguridad independientes. Si una falla, las demás siguen protegiendo. No hay un single point of failure en la cadena de seguridad.

Visión General

Mapa de Seguridad Multi-Capa

Cada petición que llega a Cadences atraviesa múltiples capas de verificación antes de tocar un solo dato:

Capa Mecanismo Protección
1. EdgeCloudflare WAF + DDoSAtaques volumétricos, SQL injection a nivel HTTP
2. Bot ProtectionTurnstile (invisible)Bots, scraping, registros falsos
3. AutenticaciónOAuth 2.0 + PKCE + JWTAcceso no autorizado, session hijacking
4. AutorizaciónRBAC + Feature GuardsEscalación de privilegios, acceso a features premium
5. AislamientoD1 per tenant + V8 isolatesCross-tenant data leak
6. TransporteTLS 1.3 + HSTS + CSPMITM, XSS, clickjacking
7. SecretosCloudflare Secrets + env varsExposición de API keys, tokens
Capa 2

Turnstile: Protección Anti-Bot Invisible

Cadences utiliza Cloudflare Turnstile en lugar de CAPTCHAs tradicionales. La diferencia es crítica: Turnstile verifica que el usuario es humano sin interrumpir la experiencia. No hay puzzles, no hay "selecciona los semáforos".

🤖

CAPTCHA Tradicional

  • ❌ Interrumpe el flujo del usuario
  • ❌ Accesibilidad mediocre
  • ❌ Google rastrea al usuario
  • ❌ Tasa de abandono 8-15%
🛡️

Cloudflare Turnstile

  • ✅ Invisible — cero fricción
  • ✅ Accesible por defecto
  • ✅ Sin tracking de terceros
  • ✅ Tasa de abandono ~0%
Worker: Turnstile Verification
async function verifyTurnstile(token: string, ip: string) {
  const response = await fetch(
    'https://challenges.cloudflare.com/turnstile/v0/siteverify',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        secret: env.TURNSTILE_SECRET_KEY,
        response: token,
        remoteip: ip,
      }),
    }
  );

  const result = await response.json();

  if (!result.success) {
    throw new Error('Bot detected — request rejected');
  }

  return result;
}

Turnstile se aplica en todos los formularios críticos: registro, login, contacto y pagos. El token se verifica server-side en el Worker, nunca en el cliente.

Capa 3

Autenticación: OAuth 2.0 + PKCE + JWT

Cadences soporta dos flujos de autenticación distintos según el contexto:

🌐 Web App (GIS Flow)

  1. 1. Redirect a Google OAuth
  2. 2. Google devuelve auth code
  3. 3. Worker valida code + client_secret
  4. 4. Se genera JWT firmado con HMAC-SHA256
  5. 5. JWT incluye orgId + userId + role + exp

🖥️ Desktop (PKCE Flow)

  1. 1. Genera code_verifier + code_challenge
  2. 2. Abre browser con challenge
  3. 3. Callback en localhost recibe code
  4. 4. Exchange code + verifier por tokens
  5. 5. Sin client_secret en el dispositivo

⚠️ ¿Por qué PKCE para Desktop?

Las apps de escritorio no pueden almacenar un client_secret de forma segura — cualquier usuario puede descompilar el binario. PKCE (Proof Key for Code Exchange) elimina esa necesidad: el challenge criptográfico reemplaza al secret, y solo el proceso que inició el flujo puede completarlo.

Capa 4

Premium Feature Guards

No todos los usuarios tienen acceso a las mismas funcionalidades. Cadences implementa un sistema de feature guards que protege las APIs costosas y las funcionalidades premium:

Worker: Premium Feature Guard
class PremiumAPIAccessError extends Error {
  constructor(feature: string) {
    super(`Premium feature "${feature}" not available`);
    this.name = 'PremiumAPIAccessError';
  }
}

function requirePremiumFeature(org: Org, feature: string) {
  const allowed = org.plan?.features || [];

  if (!allowed.includes(feature)) {
    throw new PremiumAPIAccessError(feature);
  }
}

// Ejemplo de uso en endpoint de Voice AI
requirePremiumFeature(org, 'voice_calls');
requirePremiumFeature(org, 'elevenlabs_tts');

Esto es especialmente importante para las APIs que tienen coste por uso (ElevenLabs, Twilio, OpenAI). Un usuario del plan gratuito no puede generar llamadas de voz por mucho que conozca la URL del endpoint.

🆓

Plan Free

CRM básico, 1 storefront, agentes IA limitados, sin voice, sin TTS

Plan Pro

Voice calls, TTS, agentes ilimitados, múltiples storefronts, webhooks

🏢

Plan Enterprise

SSO, API access, custom agents, dedicated support, SLA 99.9%

Capa 5

Aislamiento Total de Datos

El aislamiento de datos en Cadences no es un filtro de software — es una garantía arquitectónica. Cada organización tiene su propia base de datos D1 (SQLite en el edge). No hay WHERE org_id = ? — toda la base de datos pertenece a un solo tenant.

🔒

Data Isolation

Imposibilidad física de acceder a datos de otro tenant. No hay cross-tenant queries porque no hay tablas compartidas.

Compute Isolation

Cada request ejecuta en un V8 isolate independiente con sus propios límites de CPU y memoria.

📁

Storage Isolation

Archivos en R2 bajo prefix por organización. KV namespaces con org-scoped keys. Sin posibilidad de colisión.

🔑

Auth Isolation

JWT firmados por org con HMAC-SHA256. Un token de org A no funciona contra org B, nunca.

Capa 6

Content Security Policy y Headers

Cada respuesta HTTP de Cadences incluye headers de seguridad que bloquean ataques antes de que el navegador ejecute código malicioso:

Security Headers
// Content Security Policy — controla qué puede cargar el navegador
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'unsafe-inline' challenges.cloudflare.com;
  style-src 'self' 'unsafe-inline' fonts.googleapis.com;
  img-src 'self' data: images.unsplash.com *.googleusercontent.com;
  connect-src 'self' *.cadences.app api.elevenlabs.io;
  frame-src challenges.cloudflare.com;

// Otros headers de seguridad
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(self), geolocation=()
Header Qué previene
Content-Security-PolicyXSS, inyección de scripts, data exfiltration
Strict-Transport-SecurityDowngrade attacks, MITM en HTTP
X-Frame-Options: DENYClickjacking via iframes
X-Content-Type-OptionsMIME sniffing attacks
Permissions-PolicyAcceso no autorizado a cámara, micro, GPS

En las apps Electron (CadencesLab, Audio Hub), se aplica además context isolation: el código de la app no tiene acceso directo a las APIs de Node.js. Toda la comunicación pasa por un preload bridge con IPC tipado.

Compliance

GDPR: Cumplimiento Real, No Solo Banner

El GDPR no se cumple con un banner de cookies. Se cumple con decisiones arquitectónicas que permiten ejercer cada derecho que la regulación establece:

📋 Derecho de Acceso (Art. 15)

Exportación completa de datos del usuario en formato JSON/CSV. Un botón en Synapse Studio genera el paquete completo: contactos, deals, actividades, archivos.

✏️ Derecho de Rectificación (Art. 16)

Todos los datos son editables por el usuario propietario. Sin campos bloqueados, sin procesos opacos. Edita, guarda, listo.

🗑️ Derecho al Olvido (Art. 17)

Aquí es donde la arquitectura database-per-tenant brilla. ¿Quieres eliminar todos los datos de una organización?

// GDPR Article 17: Right to erasure
await env.CF_API.deleteD1Database(org.dbId);
await env.R2.deletePrefix(`org/${orgId}/`);
await env.KV.deletePrefix(`org:${orgId}:`);
// Toda la organización desaparece. No hay restos.

No hay soft-delete. No hay flags. DROP DATABASE. Aislamiento total significa eliminación total.

📦 Derecho a la Portabilidad (Art. 20)

Exportación en formatos estándar (JSON, CSV) de todos los datos del usuario. Compatible con importación en otros CRMs.

🍪 Consentimiento de Cookies (Art. 7)

Banner de consentimiento en cada Storefront. Sin tracking hasta que el usuario acepta explícitamente. Google Analytics y scripts de terceros bloqueados por defecto.

Capa 7

Gestión de Secretos

Cadences maneja docenas de API keys y secrets de servicios externos: Google OAuth, Twilio, ElevenLabs, Stripe, DeepSeek, OpenAI, Anthropic. Ninguno de estos secretos aparece en el código fuente:

Cómo se almacenan

  • • Cloudflare Secrets (encrypted at rest)
  • • Variables de entorno en wrangler.toml (dev)
  • • Secrets per-environment (staging/production)
  • • Rotación periódica de tokens OAuth

Nunca se hace

  • • Hardcoded secrets en código fuente
  • • Secrets en localStorage o cookies
  • • API keys en URLs o query params
  • • Logs con datos sensibles
Protección

Rate Limiting con Durable Objects

Cada organización tiene su propio Durable Object de rate limiting. No compartimos contadores entre tenants. Esto significa:

Endpoint Límite Ventana
API general1.000 reqpor minuto / org
Auth (login/register)10 reqpor minuto / IP
ElevenLabs TTS50 reqpor hora / org (plan Pro)
Voice Calls (Twilio)20 callspor hora / org
AI Agents100 execpor hora / org
Webhook incoming500 reqpor hora / org

El rate limiter usa sliding window implementado con Durable Objects. Cada org tiene su propio DO, lo que significa que un abuso de org A no afecta a org B (no hay noisy neighbor).

Checklist

Checklist de Seguridad Completo

🔐 Autenticación

  • ✅ OAuth 2.0 con Google
  • ✅ PKCE para apps desktop
  • ✅ JWT con expiración configurable
  • ✅ Refresh tokens cifrados
  • ✅ Session invalidation server-side

🛡️ Infraestructura

  • ✅ Cloudflare WAF + DDoS protection
  • ✅ TLS 1.3 everywhere
  • ✅ HSTS with preload
  • ✅ Zero trust networking
  • ✅ Edge-native (sin servidores propios)

📊 Datos

  • ✅ Database per tenant
  • ✅ Encryption at rest (D1)
  • ✅ Backup automático diario
  • ✅ GDPR data export
  • ✅ Right to erasure (DROP DB)

🖥️ Apps Desktop

  • ✅ Context isolation (Electron)
  • ✅ IPC bridge tipado
  • ✅ No nodeIntegration
  • ✅ CSP en renderer
  • ✅ Auto-update firmado

¿Tu plataforma cumple con GDPR?

Si estás construyendo un SaaS y necesitas cumplir con regulaciones de privacidad, Cadences ya lo hace por ti. Toda organización que opera en Cadences hereda automáticamente el modelo de seguridad completo.

Empieza con Cadences
Resumen

Conclusión

La seguridad en Cadences no es un checkbox — es una propiedad emergente de la arquitectura. El aislamiento por tenant no es un filtro SQL, es una database separada. La protección anti-bot no es un CAPTCHA irritante, es Turnstile invisible. El cumplimiento GDPR no es un banner de cookies, es la capacidad de hacer DROP DATABASE y que desaparezca todo.

Cada capa funciona independientemente. Si mañana se descubre una vulnerabilidad en Turnstile, las otras 6 capas siguen protegiendo. Si un JWT se compromete, el rate limiter y los feature guards siguen bloqueando acceso no autorizado. Defense in depth no es un buzzword — es la única forma seria de construir software en 2026.

La mejor seguridad es la que el usuario no nota pero el atacante no puede superar.