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):
- 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.
- 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.
- 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.
- 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
3.1 Gaps críticos — bloquean acreditación legal del expediente
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 camposUser.curp,User.cedula_profesional,Consultation.firma_medico,Consultation.timestamp_firma- Nueva colección
consentimientoscon schema firmado src/services/api.ts→createAuditLog()calcula y guardaintegrity_hashSHA-256firestore.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:
- 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”). - 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.
- Semana 3-4: Colección
consentimientos. UI en app móvil para que paciente firme. Storage de la firma + texto del consentimiento versionado. - Semana 4-5: Hash de integridad en audit log + validador en dashboard.
- 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:
- ¿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.
- ¿Migración de pacientes/doctores existentes? ¿Bloqueamos hasta que completen CURP/cédula, o periodo de gracia?
- ¿Quién es el responsable legal designado? Necesario para LFPDPPP.
- ¿Quién firma el aviso de privacidad? ¿CAPI/SinCódigo o cada clínica como responsable?
- ¿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