Saltar al contenido
AI Empire

Cómo está hecho por dentro, y lo que falta

Para quien revisa la seguridad de un proveedor: arquitectura, aislamiento entre clínicas, cifrado, acceso y continuidad. Sin sellos que nadie ha auditado.

Estado
Vigente
Última revisión
28 sep 2026

Arquitectura

Piezas del servicio y dónde corren
PiezaQué haceDónde
ServicioRecibe los mensajes, decide y responde. Sirve también el portal del paciente.Cloudflare Workers · Red global: cada petición se atiende en el centro de datos más cercano
Base de datosFichas, conversaciones, citas y registros.Supabase · UE (Irlanda · aws-eu-west-1)
Cola y cachéGuarda cada mensaje hasta procesarlo y los límites de uso.Upstash · UE (eu-central-1 · eu-west-1)
Modelo de lenguajeRedacta las respuestas; no guarda la base de datos.OpenAI · Irlanda; trata los datos en EE. UU. con cláusulas contractuales tipo
Panel de la clínicaAplicación aparte que habla con el servicio a través de su API.Cloudflare Pages
Esta webInformación pública; no recibe datos de pacientes.Vercel · Red global; los datos de la UE se tratan con cláusulas contractuales tipo

Todos los proveedores y lo que recibe cada uno, en subencargados.

Aislamiento entre clínicas

El servicio entra en la base de datos con la clave de servicio (service_role), que se salta la seguridad por filas de Postgres. Cada consulta del servicio filtra por la clínica en el propio código, y un test y un analizador lo vigilan; la seguridad por filas de la base de datos protege el acceso del panel, no el del servicio. En el panel, la clínica de cada petición sale de la cuenta del usuario, con su sesión verificada, y nunca de lo que envía el navegador. Comprobado en el código

Un analizador revisa cada consulta del servicio a la base de datos y bloquea el cambio si alguna no filtra por clínica. El 27 sep 2026 revisaba 550 consultas, con 0 sin filtro. Comprobado en el código

Además, la base de datos impide por construcción que una cita, una conversación o una derivación de una clínica apunte a un paciente de otra: las claves ajenas incluyen la clínica. Comprobado en el código

Lo que no es

El analizador lee el código: no ve consultas construidas en tiempo de ejecución, y complementa las pruebas de aislamiento, no las sustituye. Nadie ajeno ha auditado este aislamiento, y hay mejoras de endurecimiento abiertas que no detallamos hasta cerrarlas.

Cifrado

  • En tránsito: todo va por HTTPS y el servicio obliga al navegador a usarlo siempre (HSTS). Comprobado en el código
  • En reposo: Cifrado de disco de la plataforma de Supabase; la clave la gestiona Supabase. Sin verificar
  • Por columna: sólo las credenciales de la clínica (el token de WhatsApp y la clave de Cal.com) van cifradas dentro de la base de datos. Comprobado en el código

Lo que conviene saber

Las conversaciones con los pacientes se guardan en texto, sin cifrado por columna. No hay cifrado de «conocimiento cero»: el servicio lee los mensajes porque tiene que contestarlos. Y WhatsApp no llega cifrado de extremo a extremo hasta la clínica: el número y el contenido de cada mensaje de WhatsApp, que Meta descifra en sus servidores.

Acceso

  • Panel de la clínica: cada usuario entra con su cuenta y sólo ve su clínica. El panel admite segundo factor de autenticación, pero hoy no lo exige. Según documento interno
  • Portal del paciente: se entra con un enlace personal firmado que llega por WhatsApp. Un enlace para consultar caduca a las 24 horas; uno para exportar o borrar los datos, a los 30 minutos, y el primero nunca sirve para lo segundo. Comprobado en el código
  • Acceso interno: el fundador tiene acceso a producción y trabaja con agentes de IA de terceros para programar y operar el servicio. Hoy esas herramientas pueden llegar a leer la base de datos de producción. La medida propuesta, pendiente de aprobar y de comprobar, es cerrarles el acceso a los datos de pacientes, no declararlas subencargadas; mientras tanto, lo contamos aquí y en lo que falta por decidir.

Avisos que entran desde fuera

Los servicios que avisan al nuestro firman cada aviso, y la firma se comprueba antes de procesar nada. Comprobado en el código

Cómo se verifica cada aviso entrante
OrigenCómo se verifica
WhatsApp (Meta)Firma HMAC-SHA256 de Meta, comparada en tiempo constante.
StripeFirma de Stripe con ventana de tiempo, comparada en tiempo constante.
Cal.comFirma HMAC-SHA256, comparada en tiempo constante.

Continuidad

Qué hay y qué no
MedidaEstado
Copia de la base de datosCopia diaria de la base de datos, la que incluye el plan contratado de Supabase. Según documento interno
Recuperación a un punto en el tiempoNo activada. Se activará con la primera clínica de pago. Hasta entonces, si hubiera que restaurar, se perdería como mucho un día.
Simulacro de restauraciónNo hecho. Hay una comprobación automática de que la copia existe y está completa; no la restaura.
VigilanciaUn monitor externo comprueba el servicio cada 5 minutos. Los fallos que el propio servicio registra como críticos disparan un aviso por WhatsApp al fundador, y ese envío deja rastro. El estado, en estado del servicio.

Vulnerabilidades

Antes de que un cambio llegue a producción, la integración continua pasa estos controles:

Controles sobre cada cambio y qué pasa si fallan
ControlSi falla
Busca claves y contraseñas en todo el repositorio en cada cambio.Bloquea el cambio
Cada cambio en la base de datos lleva escrito cómo deshacerlo.Bloquea el cambio
Pruebas de ataque al asistente (manipulación de instrucciones, fugas de datos) según la lista OWASP para modelos de lenguaje.Bloquea el cambio
Análisis estático de seguridad con CodeQL y Semgrep.Avisa; no bloquea

Además, en cada cambio corre la batería completa de 15.826 pruebas automáticas (recuento de la integración continua).

Nadie ajeno ha hecho una prueba de intrusión, y el análisis automático no la sustituye. Si encuentras un fallo, cuéntanoslo: divulgación responsable.

Cómo se cambia el servicio

  • Los cambios se preparan en ramas y pasan la integración continua antes de fusionarse.
  • Fusionar no despliega: el paso del servicio a producción es manual y se hace aparte.
  • Los errores que se envían a Sentry pasan antes por un filtro que retira correos, teléfonos, documentos de identidad y enlaces del portal. Es un filtro por patrones: reduce lo que sale, no garantiza que no salga nada.

Qué datos se tratan y durante cuánto tiempo, en datos de pacientes. Qué hace y qué no hace el asistente, en IA y seguridad clínica.