Sus datos están físicamente aislados
Cada contador tiene su propia base de datos y sus propios archivos en el servidor. Es técnicamente imposible que un usuario acceda a información de otro estudio contable.
Aislamiento físico
Supabase PostgreSQL con Row-Level Security forzado + bases SQLite individuales por tenant. Cada contador en su propia carpeta.
Credenciales SUNAT cifradas
Claves SOL cifradas con AES-256-GCM (estándar bancario). Ni nosotros podemos verlas en texto plano.
Sesiones HMAC firmadas
Cookies firmadas con HMAC-SHA256, HttpOnly, Secure, SameSite=Lax. Logout revoca la sesión inmediatamente.
Cómo aislamos a cada contador
Combinamos 3 capas de almacenamiento— cada una con su propia garantía de aislamiento:
1. Supabase PostgreSQL con RLS forzado
Datos centrales del SaaS (tenants, suscripciones, audit logs) protegidos por Row-Level Security. Incluso si un developer olvida agregar el filtro WHERE tenant_id = ..., PostgreSQL automáticamente solo devuelve filas del tenant actual.
Patrón: política RLS con app.current_tenant + rol restringido contabuz_app que NO bypassea las políticas (fail-closed).
2. Bases SQLite individuales por tenant
Datos masivos (SIRE compras/ventas, libro diario PCGE, activos fijos, buzón SOL) viven en archivos de base de datos físicamente separados:
data/tenants/estudio-juan/sire.db ← Datos de Juan data/tenants/estudio-maria/sire.db ← Datos de María data/tenants/estudio-pedro/sire.db ← Datos de Pedro
No hay queries cruzadas posibles — son archivos independientes.
3. Carpetas JSON por tenant
Cada contador tiene su carpeta dedicada con sus clientes, configuración, evidencia SIRE, expediente, tickets de soporte. Los nombres de tenant se sanitizan para evitar path traversal.
Ataques que nos preocupan y cómo nos defendemos
| Ataque | Defensa |
|---|---|
| Modificar cookie con tenantId ajeno | Cookie firmada HMAC-SHA256 — falsificación rechazada (401) |
| Olvidar filtro WHERE tenant_id en query | RLS PostgreSQL forzado — solo devuelve filas del tenant actual |
| SQL injection | Prepared statements en better-sqlite3 + pg, sin concatenación |
| Path traversal en nombres de tenant | Sanitización regex [^a-zA-Z0-9_-] antes de tocar disco |
| Sesión robada por XSS | HttpOnly cookie + CSP estricto + logout invalida nonce en servidor |
| CSRF en formularios | Double-submit cookie+header en todas las mutaciones |
| Brute force en login | Rate limit Redis 5 intentos/15min + Cloudflare Turnstile |
| Backup filtrado físicamente | Cifrado AES-256 con GPG antes de almacenamiento |
| Bot scrappers consumiendo recursos | robots.txt bloquea 16 scrappers + rate limit por IP |
Cumplimiento Ley de Protección de Datos Personales (Perú)
Cumplimos con la Ley 29733 y su reglamento (D.S. 003-2013-JUS). Implementamos las medidas técnicas y organizativas exigidas por la Autoridad Nacional de Protección de Datos Personales (ANPDP):
- Cifrado AES-256-GCM para credenciales sensibles (claves SOL SUNAT)
- Conservación según Art. 87 TUO Código Tributario: 5 años mínimo
- Derechos ARCO (Acceso, Rectificación, Cancelación, Oposición) ejercitables
- Cookies estrictamente técnicas — sin tracking publicitario
- Audit log estructurado de accesos sensibles
Reporta una vulnerabilidad
Si encuentras un problema de seguridad, te lo agradecemos enormemente. Por favor reporta a través de WhatsApp o correo. Garantizamos:
- Confirmación del reporte en menos de 48 horas
- Fix de severidad crítica en menos de 7 días
- Crédito público (opcional) si lo deseas
Auditoría técnica abierta
Si trabajas con clientes con requisitos enterprise (auditoría externa, ISO 27001, SOC 2), podemos compartir más detalle bajo NDA.