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
Contexto
El Colegio de Enfermeros del Perú publica un validador para que cualquiera compruebe si quien la atiende está habilitada. Es una consulta legítima y frecuente: pacientes, clínicas y empleadores necesitan confirmarlo 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. Este es un ejercicio personal para resolverla con las restricciones de una institución sin equipo técnico ni presupuesto.
Problema
Problema
Ofrecer una consulta pública de colegiatura que sea útil para una persona e inútil para quien quiera extraer el padrón completo, sin pedir identificación al consultante y sin depender de infraestructura 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 al sistema institucional expone el padrón maestro por una superficie que no controla quien lo administra.
Proceso
Proceso
-
Delimitar qué se reemplaza y qué no
El alcance quedó fijado en sustituir únicamente el validador legado, 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 origen institucional, se diseñó una proyección pública independiente que recibe una exportación mínima.
Evidencia relacionada: EV-04
-
Construir tres adaptadores y probar que producen lo mismo
Como se desconoce en qué formato entregaría los datos una institución real, se escribieron adaptadores para JSON, CSV y API/NDJSON, y se verificó que los tres producen un snapshot canónico idéntico.
Evidencia relacionada: EV-09
-
Frenar la extracción masiva y automatizar la verificación
Búsqueda exacta sin comodines, cinco resultados como máximo, Turnstile validado en servidor y limitación de tasa en el borde. Sobre eso, una cadena de integración continua con la rama principal protegida.
Decisiones
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
- Origen privado, exportación mínima, validación, staging y activación atómica. La aplicación pública solo lee la proyección; nunca alcanza el origen.
- 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
Limitación de tasa en el borde en lugar de Redis
- Decisión
- Cinco solicitudes cada diez segundos por IP, con bloqueo temporal al excederlas, usando el propio borde de Cloudflare.
- Razón
- Redis 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
- Convierte la integración futura en un problema resuelto de antemano: el formato de origen deja de importar mientras el adaptador produzca el snapshot esperado.
Evidencia relacionada: EV-09
Turnstile obligatorio y fail-closed
- 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
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
- Es la arquitectura que la industria consideraría seria y la que garantiza que el proyecto muera: nadie en la institución podría operarla ni pagarla.
Implementación
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, ZAP y Dependabot
- Bloquear la integración ante hallazgos de análisis estático, dependencias vulnerables o alertas dinámicas.
- Evidencia: EV-05
Resultados
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.
Integración futura resuelta como contrato, no como promesa
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 el lockfile.
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
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 WAF administradas no están habilitadas
Requieren un plan superior al gratuito. Como control compensatorio se añadió un smoke HTTP de bajo volumen junto al baseline dinámico.
Impacto: La defensa ante patrones conocidos es menor que la de un despliegue con WAF administrado.
La ingesta remota está desactivada
El CLI de carga opera en simulación por defecto y solo escribe con confirmación explícita de la versión y las variables de cuenta.
Impacto: El circuito de actualización está diseñado y probado, pero no ejercitado contra datos reales.
Aprendizaje
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 de seguridad sin comprobación automática es 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.
Evidencia
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
- 2026-08-16
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
- 2026-08-09