Estado del documento. Este documento describe el
diseño del sistema.
El desarrollo está en su fase de fundación, así que cada control lleva marcada su etapa real.
Nada aquí afirma estar implementado si no lo está — un documento de seguridad que exagera no sirve
para auditar nada.
IMPLEMENTADO ya corre y tiene pruebas ·
DISEÑADO decidido y especificado, pendiente de construir ·
FUERA deliberadamente no incluido
1Resumen para el área de IT
El sistema permite al broker levantar programas de afinidad por sponsor: una tienda con la marca del
sponsor, cotización sobre tarifa registrada, emisión de certificados de adhesión, cobro y captura de
siniestros. Cada sponsor es un tenant con sus datos aislados.
| Pregunta | Respuesta corta |
| ¿Qué datos personales toca? | Nombre, correo, teléfono del contratante y asegurado. Comprobante fiscal (CFDI), que contiene RFC. Evidencia fotográfica de siniestros. |
| ¿Toca datos de identificación oficial? | No en el alcance actual. Ver §11. |
| ¿Quién es responsable de los datos? | El broker. SINDRI es encargado. Ver §2. |
| ¿Quién tiene el registro ante CNSF? | El broker. SINDRI es proveedor de tecnología, no intermediario. |
| ¿Puede un sponsor ver datos de otro? | No. El aislamiento se impone en el tipo, no en la disciplina. Ver §4. |
| ¿La IA decide algo con efecto contractual? | No. Ni prima, ni cobertura, ni dictamen. Ver §11. |
2Quién es responsable de qué
La distinción de la LFPDPPP entre responsable y encargado define todo el reparto de
obligaciones, y conviene fijarla por escrito antes de la primera línea de código en producción.
| Rol | Quién | Obligaciones |
| Responsable |
El broker (Hylant) |
Decide las finalidades del tratamiento. Publica el aviso de privacidad. Atiende los derechos ARCO. Titular del registro ante CNSF. |
| Encargado |
SINDRI |
Trata datos únicamente por instrucción del responsable y solo para las finalidades que él fijó. No los usa para fines propios. No los transfiere sin instrucción. Los devuelve o suprime al terminar la relación. |
| Subencargado |
Terceros del §8 |
Se declaran en el aviso de privacidad. Cada uno con su finalidad acotada. |
Esto se formaliza en un contrato de encargado, que es el instrumento que la ley pide
y que resuelve el problema de fondo. Un repositorio de documentos tipo data room sirve para
compartir archivos en una due diligence: no acredita nada sobre cómo opera un sistema con datos de
asegurados.
3Por qué este stack
| Componente | Elección | Razón de seguridad o de operación |
| API | Node 24 · TypeScript · Fastify · Kysely | El aislamiento entre tenants queda verificado por el compilador. Un query sin filtro de sponsor no compila. Ver §4. |
| Base de datos | MariaDB 11 | Motor que el equipo ya opera. Constraints, índices únicos y triggers hacen cumplir invariantes en el esquema y no en la aplicación. |
| Tienda pública | Renderizado en servidor, sin SPA | Superficie de ataque mínima en el cliente. Presupuesto de peso probado automáticamente. |
| Canal | WhatsApp Business (Meta Cloud API) | Los mensajes llegan de números verificados por Meta, no de un endpoint web abierto. Es una capa de control de abuso que no hay que construir. |
| Cobro | Checkout por redirección | Los datos de tarjeta nunca pasan por nuestra infraestructura ni por la tienda. No cargamos el SDK del proveedor. |
| Cifrado en reposo | scrypt + AES-256-GCM, llave solo en memoria | Patrón ya en producción en otro producto de SINDRI. Ver §9. |
4Aislamiento de datos entre sponsors
Es el control central del sistema y la pregunta que un área de IT hace primero. La respuesta no es
"tenemos la disciplina de filtrar siempre": es que el sistema no permite lo contrario.
flowchart TD
A["Request con JWT"] --> B["Middleware de scope"]
B --> C["AccessScope
lista explicita y no vacia"]
C --> D["createScopedDb"]
D --> E["Todo query lleva el filtro
de sponsor aplicado"]
F["La conexion cruda a la base"] -.->|privada del directorio db/| G["Ningun modulo la alcanza"]
H["sponsor_id en query string,
body o header"] -.->|SE IGNORA| B
| Control | Cómo | Etapa |
| Filtro por tenant en todo query | Los módulos solo reciben un objeto de acceso con el filtro ya aplicado; la conexión cruda es privada del directorio de base de datos y una prueba de arquitectura falla el build si algún archivo fuera de él la importa | DISEÑADO |
| Verificación por el compilador | Pruebas de tipos que deben fallar la compilación si alguien ensancha el acceso. El gate es que el chequeo de tipos pase, lo que significa que cada aserción negativa se disparó | DISEÑADO |
| Sin comodín de acceso | Todo scope lleva una lista explícita y no vacía de sponsors. No existe valor "todos" ni rol que evada el filtro, ni el administrador del broker: recibe la lista enumerada en tiempo de request | DISEÑADO |
| El scope sale del token | Un identificador de sponsor que llegue por parámetro del request se ignora | DISEÑADO |
| Revocación inmediata | El alcance de un ejecutivo se consulta en cada request, así que quitarle acceso surte efecto al instante y no cuando expire su token | DISEÑADO |
| Sin fuga por código de error | Un recurso de otro sponsor responde "no encontrado", nunca "prohibido" — un 403 confirmaría que el recurso existe en otro tenant. Y nunca una lista vacía donde correspondía un rechazo | DISEÑADO |
| Verificación extremo a extremo | Prueba de integración contra el servidor real: un ejecutivo con acceso a un sponsor recibe "no encontrado" al pedir recursos de otro, en cada endpoint que los expone | DISEÑADO |
Excepción declarada. Dos tablas no llevan identificador de sponsor: la de ejecutivos y
la de sus permisos. Los ejecutivos pertenecen al broker, no a un sponsor, y uno puede atender varios
programas. Esas dos tablas son alcanzables únicamente por un accesor con nombre propio, usado por un
solo módulo. La excepción está escrita y es auditable, en lugar de ser un hueco silencioso.
5Controles de seguridad
| Control | Detalle | Etapa |
| Autenticación | JWT sin estado. El scope de datos se deriva del token. | DISEÑADO |
| Consultas parametrizadas | Todo acceso a base pasa por un constructor de queries tipado. Sin concatenación de SQL. | IMPLEMENTADO |
| Superficie de inyección SQL acotada | La ejecución de múltiples sentencias por conexión está habilitada solo en el proceso de migraciones, nunca en la conexión de la aplicación. Verificado en revisión de código. | IMPLEMENTADO |
| Bitácora de accesos append-only | Registra quién vio qué dato de qué asegurado y cuándo. Los UPDATE y DELETE los rechaza un trigger de la base, que aplica a todo usuario incluido el administrador. Para producción se combina con permisos a nivel de tabla, para que un DBA no pueda quitar el trigger en silencio. | DISEÑADO |
| Idempotencia de cobro | El identificador de pago del proveedor es único en el esquema. Un pago nunca emite dos certificados, y un webhook duplicado lo rechaza el motor, no la lógica. | DISEÑADO |
| Webhook no es prueba de pago | Un certificado nunca pasa a vigente por un webhook sin verificar el pago contra la API del proveedor. | DISEÑADO |
| Límite de tasa | Por conexión en la API, más presupuesto duro por identificador de canal. | DISEÑADO |
| Integridad de evidencia | Cada archivo de evidencia guarda su hash SHA-256. | DISEÑADO |
| Contrato de errores cerrado | Conjunto fijo de códigos de error. Los mensajes no exponen estado interno ni existencia de recursos ajenos. | DISEÑADO |
6Datos personales — LFPDPPP
| Principio | Cómo se cumple |
| Aviso de privacidad | Se presenta en el punto de captura del canal, no enterrado en un enlace. El consentimiento queda registrado con su marca de tiempo. |
| Finalidad limitada | Los datos se usan solo para cotizar, emitir y atender siniestros del programa que los originó. El aislamiento por sponsor lo hace estructural. |
| Minimización | Cuando una imagen solo sirve para extraer datos, no se conserva: se extrae, se valida y se destruye la imagen. Del comprobante fiscal se conservan identificador, RFC emisor, total y fecha. La evidencia de siniestro sí se conserva cifrada, porque sustenta el dictamen. |
| Derechos ARCO | Mecanismo de acceso, rectificación, cancelación y oposición, operado por el responsable. El sistema expone la consulta y el borrado verificable. |
| Retención | Declarada por tipo de documento, con borrado verificable al vencer. |
| Trazabilidad | Bitácora append-only de accesos a datos de asegurados. |
Regla dura sobre credenciales de terceros. Ningún servicio que requiera la contraseña
del portal fiscal del cliente (la CIEC) entra al sistema. Eso nos volvería custodios de una credencial
ajena y es un riesgo que no se acepta a ningún precio. Solo se usan servicios que operan con los datos
que el cliente ya proporcionó.
7Marco de seguros — LISF y CNSF
| Tema | Posición |
| Comercialización por canal digital | Artículo 102, segundo párrafo de la LISF: contrato de prestación de servicios para promoción o venta de productos de seguro de adhesión, con registro previo ante CNSF. Más la Circular Única de Seguros y Fianzas, disposición 33.2.10, sobre mecanismos análogos de comercialización. |
| Titular del registro | El broker. El sistema lo referencia por póliza maestra, de modo que cada programa queda trazable a su registro. |
| Rol de SINDRI | Proveedor de tecnología. No intermedia, no asesora, no suscribe. |
| Estructura del producto | Una póliza maestra por programa; cada asegurado recibe un certificado de adhesión. No se emiten pólizas individuales. |
| Origen de la prima | Tabla de tarifa registrada del producto. Determinista y auditable: a partir de los mismos insumos, la misma prima. |
Por qué el modelo de lenguaje nunca calcula la prima. Asesorar para la celebración de
un contrato de seguro es intermediación con licencia. Además, si el modelo nunca toca la prima, no
existe manipulación de la conversación que consiga un descuento: el asistente solo llena un objeto de
datos que el motor de tarifa valida. Es control regulatorio y control de seguridad con una sola decisión.
8Terceros y subencargados
| Tercero | Para qué | Qué datos recibe |
| Meta (WhatsApp Business) | Canal de conversación | Número de teléfono y contenido de los mensajes. Se declara en el aviso de privacidad — es el detalle que la mayoría de las implementaciones de WhatsApp en México omite. |
| Proveedor de OCR | Extraer datos de documentos | La imagen del documento, transitoriamente. No se usa para entrenar. |
| Servicio de validación fiscal | Verificar el comprobante contra el SAT | Identificador del comprobante, RFC emisor y total. Nunca credenciales del cliente. |
| Proveedor de cobro | Procesar el pago de la prima | Monto y referencia. Los datos de tarjeta se capturan en su dominio, no en el nuestro. |
| Proveedor de hosting | Infraestructura | Datos en reposo, cifrados según §9. |
9Secretos y cifrado en reposo
| Control | Detalle | Etapa |
| Derivación de llave | Passphrase maestra → scrypt → llave AES-256-GCM. La llave existe solo en memoria y nunca se persiste. La base guarda salt, verificador y el secreto cifrado. | DISEÑADO patrón ya en producción en otro producto de SINDRI |
| Desbloqueo | Una vez por sesión. Revelar un secreto requiere la bóveda abierta; los listados van enmascarados. | DISEÑADO |
| Credenciales de aplicación | Variables de entorno, nunca en el repositorio. El arranque falla si falta un secreto obligatorio, en lugar de tomar un valor por defecto en silencio. | IMPLEMENTADO |
| Datos de prueba | Ningún dato personal real entra a fixtures, semillas ni al repositorio. Se usa el entorno de pruebas de los proveedores, que no toca sistemas reales. | IMPLEMENTADO |
10Abuso, costo y disponibilidad
Un asistente conversacional que consume cómputo por mensaje tiene una superficie de abuso propia: no
basta con protegerlo del acceso indebido, hay que protegerlo del agotamiento.
| Riesgo | Control |
| Saturación del asistente | Presupuesto duro por identificador de canal: número máximo de mensajes y de cómputo por día. Al tope, respuesta de plantilla estática y escalamiento a humano. |
| Conversación que no cierra | Techo de turnos con cierre elegante. Una conversación que no cierra en N turnos va a un ejecutivo. |
| Tráfico fuera de dominio | Filtro barato antes del modelo costoso. Lo que no es del dominio se contesta con plantilla. |
| Gasto descontrolado | Interruptor global de gasto diario con corte automático. |
| Comportamiento anómalo | Reglas de velocidad y lista de bloqueo, sobre un motor de scoring ya probado con volumen real en otro producto de SINDRI. |
| Endpoint abierto | El canal principal no lo es: todo mensaje proviene de un número verificado por Meta. |
11Lo que el sistema NO hace
Cada punto es una decisión deliberada, no una omisión. Limitar el alcance es parte del control.
| No hace | Por qué |
| FUERA Calcular la prima con un modelo de lenguaje | La prima sale de la tarifa registrada, por un motor determinista. Regulatorio y de seguridad. Ver §7. |
| FUERA Asesorar sobre cobertura | Es intermediación con licencia. El asistente informa el contenido registrado del producto; no opina sobre su idoneidad. |
| FUERA Dictaminar siniestros | Resolver un siniestro es acto de la aseguradora y tiene consecuencias contractuales. El sistema arma el expediente —evidencia, scoring, validación del comprobante, verificación de cobertura— y dictamina un humano. |
| FUERA Capturar identificación oficial | El producto inicial se emite con nombre, correo y teléfono. Exigir una identificación oficial sería fricción injustificada y captación de datos innecesaria: lo contrario de la minimización que este mismo diseño exige. Entra solo cuando un producto lo requiera. |
| FUERA Almacenar datos de tarjeta | El cobro va por redirección al dominio del proveedor. |
| FUERA Custodiar credenciales fiscales del cliente | Ningún servicio que pida la CIEC entra al sistema. Ver §6. |
| FUERA Cotizar contra portales de aseguradoras | Un programa equivale a una aseguradora. No se automatiza navegación en portales de terceros. |
| FUERA Conciliación de pagos y comisiones | Alcance posterior. Hoy el sistema registra, no concilia. |
12Hosting y despliegue
| Aspecto | Detalle |
| Entorno de desarrollo | Base de datos desechable en contenedor local, aislada por puerto de cualquier otro proyecto de la máquina. Se puede destruir y recrear sin efectos fuera del proyecto. |
| Migraciones de esquema | Archivos SQL numerados y secuenciales, registrados al aplicarse. Idempotentes: una segunda corrida no aplica nada. Nunca se edita una migración ya aplicada. |
| Producción | Por definir con el broker. Región de datos y proveedor son decisión del responsable, no del encargado. |
| Respaldos | Volcado con retención definida. El detalle se acuerda con el área de IT del broker. |
| Separación de entornos | Los datos de producción nunca se copian a desarrollo. Las pruebas corren con datos sintéticos. |
Lo que este documento no pretende ser. No es una certificación ni un informe de
auditoría. Es el diseño de seguridad puesto por escrito para que el área de IT del broker pueda
cuestionarlo antes de que se construya, que es cuando cambiarlo cuesta barato. Las preguntas y
objeciones son el propósito del documento.