Caso de estudio · Servicio público digital
Conoce a tu Enfermera(o)
Prototipo de consulta pública de colegiatura que responde sin pedir identificación y sin guardar quién consultó, sobre un plan gratuito y sin infraestructura permanente.
- Periodo
- Agosto de 2026
- Rol
- Diseño, desarrollo y despliegue
- Responsabilidad
- Proyecto personal completo, de extremo a extremo
Contexto
El Colegio de Enfermeros del Perú ofrece en su web un validador para comprobar si una enfermera o enfermero está habilitado para ejercer. Sirve a pacientes, clínicas y empleadores antes de aceptar una atención o firmar un contrato.
El servicio tiene una tensión incómoda: para responder necesita exponer parte de un padrón, pero exponerlo mal lo convierte en una fuente de extracción masiva. Y la solución habitual —pedir identificación al consultante— crea un problema nuevo: una base de datos de quién preguntó por quién. Es un ejercicio personal. Partí de un supuesto: una institución sin equipo técnico ni presupuesto para mantener servidores.
Problema
El reto era ofrecer una consulta pública de colegiatura útil para una persona e inútil para quien quiera copiar el padrón completo. Tenía dos condiciones: no pedir identificación a quien consulta y no depender de servidores que alguien deba mantener y pagar.
Consecuencias observadas
- Pedir DNI o login genera un registro de quién consultó a quién, un dato sensible que hay que custodiar y justificar.
- Permitir búsquedas parciales, comodines o listados convierte el validador en un exportador del padrón por goteo.
- Conectar la web pública directamente al sistema interno deja el padrón completo al alcance de cualquier ataque contra la web.
Proceso
-
Delimitar qué se reemplaza y qué no
Fijé el alcance en sustituir únicamente el validador actual, no en reconstruir el sitio institucional. Recortar el problema fue la primera decisión de diseño y la que hizo viable todo lo demás.
Evidencia relacionada: EV-01
-
Aislar la consulta del sistema que administra el padrón
En lugar de conectar la aplicación al sistema de la institución, diseñé una copia pública separada que recibe una exportación mínima.
Evidencia relacionada: EV-04
-
Construir tres adaptadores y probar que producen lo mismo
Como no sé en qué formato entregaría los datos una institución real, escribí adaptadores para JSON, CSV y API/NDJSON, y verifiqué que los tres producen un snapshot canónico idéntico.
Evidencia relacionada: EV-09
-
Frenar la extracción masiva y automatizar la verificación
Limité la búsqueda a coincidencias exactas y a cinco resultados. Añadí una verificación contra bots (Cloudflare Turnstile) comprobada en el servidor y un tope de consultas por dirección IP. Además, cada cambio pasa por pruebas automáticas antes de publicarse.
Decisiones
No recolectar nada del consultante
- Decisión
- La consulta no pide registro, login ni DNI, y no se guarda ningún dato de quién consultó.
- Razón
- Un dato que no se recolecta no se puede filtrar ni hay que custodiarlo. Eliminar la obligación sale más barato que gestionarla.
- Impacto
- El abuso tuvo que frenarse por la forma de la consulta, no por la identidad de quien la hace.
Evidencia relacionada: EV-03
Proyección pública aislada, con flujo en una sola dirección
- Decisión
- Los datos salen del sistema privado en una exportación mínima, se validan en un entorno de prueba y se publican de una sola vez, sin estados intermedios. La aplicación pública solo lee esa copia y nunca llega al sistema original.
- Razón
- Si la aplicación pública se ve comprometida, el atacante llega a una copia recortada y ya publicada, no al sistema institucional ni a sus credenciales.
- Impacto
- Si una carga falla, el snapshot anterior sigue activo y el servicio no se degrada.
Evidencia relacionada: EV-04
Limitar las consultas desde la red de Cloudflare, sin un servidor adicional
- Decisión
- Cinco solicitudes cada diez segundos por IP, con bloqueo temporal al excederlas, usando el propio borde de Cloudflare.
- Razón
- Redis (una base de datos en memoria) habría añadido un servicio permanente que pagar, monitorear y parchear. El borde ya ve todo el tráfico y no agrega superficie que mantener.
- Impacto
- La línea base no requirió crear recursos facturables.
Evidencia relacionada: EV-01
Un snapshot canónico como contrato de ingesta
- Decisión
- Tres adaptadores demostrativos (JSON, CSV y API/NDJSON) que convergen en un snapshot canónico con versión, checksum e invariantes verificadas.
- Razón
- Si una institución adoptara el sistema, bastaría escribir un adaptador para su formato; el resto no cambia.
Evidencia relacionada: EV-09
Verificación contra bots obligatoria: si falla, la consulta se bloquea
- Decisión
- Sin token válido no hay consulta. Se validan en servidor el token, el hostname y la acción, con un tiempo de espera controlado.
- Razón
- Un control que ante la duda deja pasar la petición no es un control. Prefiero que el servicio falle visiblemente antes que abrirse en silencio.
Evidencia relacionada: EV-03
Alternativas descartadas
Identificar al consultante con RENIEC o PIDE
- Alternativa
- Exigir DNI verificado contra los servicios de identidad del Estado antes de permitir la consulta.
- Motivo para descartarla
- Resuelve el abuso creando un problema mayor: un registro permanente de quién consultó a quién, con obligaciones de custodia que la institución no puede asumir. Además levanta una barrera de acceso a un dato que debería ser público.
Reconstruir el portal institucional completo
- Alternativa
- Migrar todo el sitio del colegio junto con el validador.
- Motivo para descartarla
- Multiplica el alcance, el costo y el riesgo para resolver un problema localizado en una sola ruta.
Kubernetes, microservicios y un gestor de identidad
- Alternativa
- Desplegar la solución sobre un clúster con Keycloak y servicios separados.
- Motivo para descartarla
- Resolvería el problema, pero exige un equipo que la opere y un presupuesto mensual. Una institución sin personal técnico no podría sostenerla.
Implementación
Todo corre sobre Cloudflare Workers, con los datos en una base D1 que contiene solo la proyección pública. La búsqueda acepta una colegiatura exacta de cinco o seis dígitos —incluidos los ceros iniciales— o un nombre completo normalizado, y devuelve cinco coincidencias como máximo.
El acceso a la base usa consultas preparadas, un esquema JSON cerrado y límites explícitos de cuerpo, campos y longitud. No hay comodines, listados, paginación ni exportación.
{
"synthetic": true,
"sources": [
{ "source": "demo:postgres-view-json", "record_count": 60,
"checksum_sha256": "fb404fa8338bb8eb8b8f67ed190b47a136cae8691640c1257dd0b934ea6e87db" },
{ "source": "demo:legacy-csv", "record_count": 60,
"checksum_sha256": "fb404fa8338bb8eb8b8f67ed190b47a136cae8691640c1257dd0b934ea6e87db" },
{ "source": "demo:api-ndjson", "record_count": 60,
"checksum_sha256": "fb404fa8338bb8eb8b8f67ed190b47a136cae8691640c1257dd0b934ea6e87db" }
],
"equivalent": true
}
Apoyo técnico
- Cloudflare Workers y D1
- Ejecutar el servicio y almacenar la proyección pública sin un proceso permanente que pagar y parchear.
- Evidencia: EV-02
- Cloudflare Turnstile
- Verificar que la consulta proviene de una persona, sin identificarla.
- Evidencia: EV-03
- GitHub Actions con CodeQL, revisión de dependencias y OWASP ZAP
- Bloquear cada cambio ante hallazgos de CodeQL o dependencias vulnerables, y revisar cada semana el despliegue con OWASP ZAP.
- Evidencia: EV-05
Resultados
Consulta pública operativa sin registro de consultantes
VerificadoEl servicio responde consultas de colegiatura sin pedir identificación y sin crear ninguna base de datos de quién consultó.
Alcance: Despliegue de demostración con datos sintéticos, accesible públicamente.
Tres formatos de origen, un mismo resultado verificable
VerificadoTres formatos de origen distintos producen un snapshot idéntico, verificado por checksum y respaldado por pruebas que detectan alteraciones y dejan sin activar cualquier carga incompleta.
Alcance: Adaptadores demostrativos sobre orígenes simulados, no sobre el padrón real.
Evidencia: EV-09
Cadena de verificación automática y bloqueante
VerificadoNingún cambio llega a producción sin pasar por la cadena completa de comprobaciones, y cualquiera de ellas puede detenerlo. La revisión de agosto de 2026 cerró sin vulnerabilidades conocidas en las dependencias del proyecto.
Alcance: Cada cambio hacia la rama principal, que está protegida y solo admite integración por pull request.
Evidencia: EV-05
Sin recursos facturables en la línea base
VerificadoLa arquitectura desplegada no requirió crear recursos de pago ni procesos permanentes.
Alcance: Línea base vigente al cierre de la revisión de agosto de 2026.
Evidencia: EV-01
Límites
Los datos son sintéticos y el proyecto no es institucional
El padrón está generado y no existe encargo ni relación con el Colegio de Enfermeros del Perú. El servicio no consulta el registro real ni emite verificaciones oficiales.
Impacto: Cualquier adopción real exigiría autorización, acceso al origen y validación del catálogo oficial.
Las reglas administradas del firewall de aplicaciones web (WAF) no están habilitadas
Requieren un plan superior al gratuito. Para compensar, añadí una prueba automática ligera que comprueba en el despliegue las cabeceras de seguridad y que la API rechace peticiones sin verificación válida, además del análisis semanal con OWASP ZAP.
Impacto: La defensa ante patrones conocidos es menor que la de un despliegue con WAF administrado.
La ingesta remota está desactivada
La herramienta de carga funciona en modo de prueba por defecto: solo escribe datos si confirmo la versión y la cuenta de destino.
Impacto: El circuito de actualización está diseñado y probado, pero no ejercitado contra datos reales.
Aprendizaje
- Diseñar para no recolectar un dato es más barato que diseñar para protegerlo. Al no guardar quién consulta, desaparece una categoría entera de obligaciones en lugar de tener que administrarla.
- Una afirmación técnica sin comprobación automática es solo una intención. El checksum idéntico entre tres adaptadores vale más que cualquier párrafo asegurando que la ingesta es equivalente.
- La capacidad de mantenimiento del destinatario es un requisito de diseño. Una arquitectura que la institución no puede operar ni pagar es una solución que fracasa más tarde, no una solución mejor.
Registro de evidencia
Código fuente y documentación del prototipo
Repositorio público con la aplicación, los adaptadores, el esquema, las pruebas y la documentación de arquitectura y seguridad.
- Fecha
Demostración pública en funcionamiento
Despliegue accesible de la consulta. Puede probarse con el número de colegiatura sintético 00001.
- Alcance
- Datos sintéticos. No consulta el padrón real ni emite verificaciones oficiales.
Contrato OpenAPI de la API de consulta
Especificación de la API pública: formato de búsqueda aceptado, campos devueltos y límite de cinco resultados.
Consultar el contrato OpenAPIEsquema JSON del snapshot del padrón
Contrato que define la proyección publicada y sus invariantes. Es la frontera formal entre lo que se expone y lo que permanece en el origen.
Ver el esquema del snapshotCadena DevSecOps en integración continua
Flujo que ejecuta validación de datos, lint, pruebas, build, auditoría del lockfile, Dependency Review y CodeQL en cada cambio hacia la rama principal.
Ver las ejecuciones de DevSecOpsInforme de equivalencia de los tres adaptadores
Salida generada que compara los snapshots producidos desde JSON, CSV y API/NDJSON, con número de registros y checksum de cada uno.
- Fecha