Auditoría de cumplimiento normativo — Panel CAPI Guardian

Fecha: 2026-05-07 Alcance: Repositorio admin-panel/capi-guardian (panel administrativo React + Firestore) Objetivo: Identificar qué controles normativos están realmente implementados en código y cuáles son gap, para tener un plan accionable que podamos compartir con el equipo y, en su momento, defender ante una visita de COFEPRIS o un requerimiento del INAI.


1. Por qué hacemos esto

CAPI es un sistema de expediente clínico electrónico que opera en territorio mexicano. Eso lo coloca, simultáneamente, bajo tres regímenes regulatorios:

Regulador Norma Qué exige
Secretaría de Salud / COFEPRIS NOM-024-SSA3-2012 Cómo deben funcionar los sistemas que registran información de salud (firma, integridad, identificación).
Secretaría de Salud NOM-004-SSA3-2012 Qué debe contener un expediente clínico, cómo custodiarlo y por cuánto tiempo.
INAI LFPDPPP + su Reglamento Cómo tratar datos personales de pacientes (sensibles, máxima protección).

El nombre “COFEPRIS” se usa en el panel como paraguas, pero en realidad estamos cubriendo los tres. Esta auditoría revisa los tres en conjunto.

Por qué importa para el equipo y para los clientes (clínicas):

  1. Riesgo legal directo del cliente. Una clínica que use CAPI sin firma electrónica ni CURP no puede acreditar el expediente ante una autoridad. El expediente “no existe legalmente”. Multa potencial al cliente: 100 a 4,000 UMAs (LFPDPPP), más sanciones sanitarias.
  2. Riesgo legal de SinCódigo. Bajo LFPDPPP somos encargados del tratamiento. Si hay vulneración por un control que omitimos, respondemos solidariamente con el responsable.
  3. Bloqueo comercial. Hospitales, aseguradoras y grupos médicos exigen cumplimiento NOM-024 documentado para integrar. Sin esto, el techo del producto son consultorios pequeños.
  4. El score actual del panel (83.3%) es engañoso. Solo mide solicitudes ARCO atendidas a tiempo. No mide nada de NOM-024 ni NOM-004. Si alguien lo presenta como “cumplimiento COFEPRIS” en una venta o auditoría, es exposición.

2. Estado actual — qué sí está bien

Control Dónde vive en el código
Control de acceso por rol (RBAC) — Super_Admin, COFEPRIS_Auditor, Clinic_Admin, Readonly_Auditor firestore-rules-addition.txt:40-150
Audit log con quién/qué/cuándo + IP src/types/firebase.ts:223-241, src/services/api.ts (createAuditLog)
UI de gestión ARCO con SLA 20 días hábiles src/pages/Compliance.tsx:88-109
Reglas Firestore con principio de mínimo privilegio firestore-rules-addition.txt

Esto cubre confidencialidad, no-repudio y la parte visible de derechos ARCO. Es base sólida; nadie tiene que rehacerla.


3. Los gaps que tenemos que cerrar

Estos cinco son los que, si no existen, hacen que un expediente generado por CAPI no sea legalmente válido ante una autoridad. Si una clínica nos pregunta “¿cumple COFEPRIS?”, hoy la respuesta honesta es “todavía no”.

# Requisito Norma De dónde sale Qué pasa si no lo tenemos
1 Firma electrónica del médico en cada nota y consentimiento NOM-024-SSA3-2012 §6.3 El sistema debe garantizar autenticidad del autor. Sin firma, no hay autoría acreditable. El expediente no se puede usar como prueba. Auditoría sanitaria lo invalida.
2 CURP del paciente (18 caracteres validados) NOM-024-SSA3-2012 §5.4.1 Identificador único nacional. Sin CURP no hay “identificación inequívoca del paciente”. No se puede emparejar al paciente con expedientes externos ni reportar a SS.
3 Cédula profesional del doctor NOM-024-SSA3-2012 §5.4.2 El sistema debe vincular cada nota al profesional acreditado. Las notas no pueden atribuirse legalmente al médico.
4 Consentimiento informado firmado y almacenado NOM-004-SSA3-2012 §10.1 El expediente debe contener el consentimiento del paciente para procedimientos. El paciente puede impugnar cualquier acto médico. Riesgo civil para la clínica.
5 Hash de integridad en audit log NOM-024-SSA3-2012 §6.4 Debe ser detectable cualquier alteración del registro. Un atacante (o admin malicioso) podría editar logs sin dejar rastro.

Dónde modificar el código (resumen):

  • src/types/firebase.ts → agregar campos User.curp, User.cedula_profesional, Consultation.firma_medico, Consultation.timestamp_firma
  • Nueva colección consentimientos con schema firmado
  • src/services/api.tscreateAuditLog() calcula y guarda integrity_hash SHA-256
  • firestore.rules → enforcement: rechazar writes sin CURP de 18 chars, sin firma, etc.

3.2 Gaps importantes — necesarios para LFPDPPP completa

# Requisito Norma Por qué importa
6 MFA obligatorio para Super_Admin y Clinic_Admin LFPDPPP — Reglamento art. 19 (medidas técnicas) Los roles privilegiados acceden a datos sensibles de salud. Una contraseña sola es insuficiente bajo “máximo nivel de seguridad” exigido para datos sensibles.
7 Bitácora de incidentes y vulneraciones LFPDPPP art. 20, Reglamento art. 63 Obligación de documentar cada brecha y notificar al titular afectado.
8 Exportación del expediente en formato estándar NOM-024 §7 + ARCO derecho de acceso El paciente puede pedir copia portable de su expediente. Hoy hay botón “Download” sin formato definido.
9 Flujo “oposición” en ARCO LFPDPPP art. 27 Hoy el panel maneja Acceso/Rectificación/Cancelación pero no está modelado oposición.

3.3 No verificables desde código — necesitan evidencia externa

Estos no están en el repo del panel pero hay que documentarlos en algún lado para una auditoría real:

  • Backups automáticos de Firestore (frecuencia, retención, prueba de restore) → Firebase Console
  • Aviso de privacidad público accesible → landing/app
  • Designación formal del responsable y encargado del tratamiento → documento legal
  • Política de contraseñas y MFA en Firebase Auth → consola
  • Cifrado en reposo → delegado a GCP, hay que citar el documento de Google

4. Plan propuesto

Fase 1 — Cerrar bloqueadores legales (4-6 semanas)

Atacar gaps 1-5 en orden de dependencia:

  1. Semana 1-2: Modelo de datos. Agregar CURP + cédula a User. Migración de usuarios existentes (campos opcionales con flag de “pendiente de completar”).
  2. Semana 2-3: Firma electrónica. Decisión técnica: ¿hash + timestamp simple, o e.firma SAT real? Recomendación: empezar con SHA-256 + timestamp + foto de firma (cumple NOM-024) y dejar puerta abierta a e.firma.
  3. Semana 3-4: Colección consentimientos. UI en app móvil para que paciente firme. Storage de la firma + texto del consentimiento versionado.
  4. Semana 4-5: Hash de integridad en audit log + validador en dashboard.
  5. Semana 5-6: Tests de regresión + documentación técnica del cumplimiento (publicar en docs.doctorcapi.com/referencias/cofepris/ que hoy está vacío).

Fase 2 — Cerrar LFPDPPP completo (2-3 semanas)

Gaps 6-9: MFA, bitácora de incidentes, exportación PDF/CDA, flujo oposición.

Fase 3 — Documentación de evidencia externa (1 semana)

Recolectar y publicar en docs.doctorcapi.com:

  • Configuración de backups Firebase (screenshot + política)
  • Aviso de privacidad
  • Documento de designación responsable/encargado
  • Mapa de cifrado (Google Cloud encryption at rest documentation)

5. Decisiones que necesitamos del equipo

Antes de arrancar Fase 1:

  1. ¿Firma electrónica simple o e.firma SAT? Simple es 2 semanas, e.firma SAT real son 6+ semanas y requiere integración con SAT.
  2. ¿Migración de pacientes/doctores existentes? ¿Bloqueamos hasta que completen CURP/cédula, o periodo de gracia?
  3. ¿Quién es el responsable legal designado? Necesario para LFPDPPP.
  4. ¿Quién firma el aviso de privacidad? ¿CAPI/SinCódigo o cada clínica como responsable?
  5. ¿Compromiso comercial actual? ¿Hay clínicas que ya tienen el panel y a las que tenemos que comunicar el roadmap de cumplimiento?

6. Anexo — Matriz completa de 23 requisitos

# Requisito Norma Estado Evidencia
1 Identificación inequívoca del paciente (CURP) NOM-024   src/types/firebase.ts:46 — campo “expediente” opcional, sin CURP
2 Identificación inequívoca del personal (cédula) NOM-024   src/types/firebase.ts:14-67
3 Firma electrónica del médico NOM-024   src/types/firebase.ts:279-292
4 Integridad / hash en audit log NOM-024 Parcial src/types/firebase.ts:237-241
5 No-repudio NOM-024   src/services/api.ts createAuditLog
6 Exportación interoperable del expediente NOM-024   src/pages/Audit.tsx:29 (botón sin formato definido)
7 Campos obligatorios del expediente NOM-004   src/types/firebase.ts:279-292 (Consultation incompleto)
8 Retención 5 años NOM-004   src/types/firebase.ts:420 retentionPeriod sin enforcement
9 Confidencialidad por rol NOM-004   firestore-rules-addition.txt:40-130
10 Consentimiento informado firmado NOM-004   No existe tipo ConsentForm
11 Aviso de privacidad accesible LFPDPPP   Fuera del panel
12 Derechos ARCO + SLA 20 días hábiles LFPDPPP   src/pages/Compliance.tsx:88-109 (falta “oposición”)
13 Designación responsable / encargado LFPDPPP   Documento legal externo
14 Medidas de seguridad (admin/técnicas/físicas) LFPDPPP   Solo técnicas implementadas
15 Bitácora de incidentes / vulneraciones LFPDPPP   No diferenciada del audit log
16 Cifrado en tránsito y en reposo LFPDPPP   HTTPS sí, reposo delegado a GCP
17 Borrado / cancelación efectiva LFPDPPP   Sin evidencia de soft-delete o anonymization
18 Backups automáticos General   Firebase Console
19 Reglas Firestore least-privilege General   firestore-rules-addition.txt
20 Logs de auditoría inmutables General   Collection audit_logs, write-only rules
21 MFA para roles privilegiados General   Firebase Auth básico
22 Política de contraseñas General   Firebase Auth
23 Sesiones / expiración de tokens General   Token Firebase + localStorage sin httpOnly

Leyenda: Implementado · Parcial · Gap · No verificable desde el repo


This site uses Just the Docs, a documentation theme for Jekyll.