Saltar a contenido

Investigacion: Anonimizacion de Lista de Medicamentos para Procesamiento Servidor

Identificador: MTS-INV-010 Version: 1.0.0 Fecha: 2025-12-05 Autor: SpecQueen (KnowledgeDrone) Solicitado por: Director del Proyecto Estado: Completado


1. Resumen Ejecutivo

Esta investigacion analiza las tecnicas y arquitecturas necesarias para que MedTime pueda procesar listas de medicamentos de usuarios en el servidor para fines de enriquecimiento de base de datos, mejora del servicio y validacion de interacciones, sin poder asociar esa informacion a ningun usuario especifico.

1.1. Conclusion Principal

1.1.1. La anonimizacion efectiva de listas de medicamentos es viable mediante una arquitectura de separacion de identidad (NO generalizacion a categorias)

CONCEPTO CLAVE - SEPARACION DE IDENTIDAD: - SÍ se envían nombres específicos de medicamentos (ej: "Glucophage 850mg") - NO se envían identificadores de usuario (user_id, email, device_id, IP) - La anonimización consiste en eliminar el vínculo con la identidad, NO en generalizar datos a categorías

CONSENTIMIENTO OBLIGATORIO: Para usuarios con cuenta, el consentimiento para tratamiento de datos anonimizados esREQUISITO para usar la aplicación (no es opt-in). Ver INV-009

Aspecto Evaluacion Complejidad
K-Anonymity para medicamentos Parcialmente efectivo Media
Differential Privacy Altamente efectivo Alta
Separacion de identidad Esencial Media
Re-identificacion por combinaciones Riesgo Alto Mitigable
Implementacion movil Viable Media-Alta
Cumplimiento regulatorio Lograble Media

2. Contexto y Problema

2.1. Necesidades del Negocio

MedTime necesita procesar listas de medicamentos para:

+------------------+     +------------------+     +------------------+
|   USUARIO        |     |   SERVIDOR       |     |   BENEFICIOS     |
|                  |     |                  |     |                  |
| Lista personal   |---->| Procesar datos   |---->| Enriquecer BD    |
| de medicamentos  |     | de medicamentos  |     | Validar interact.|
|                  |     |                  |     | Mejorar servicio |
+------------------+     +------------------+     +------------------+
Caso de Uso Descripcion Necesidad de Identificacion
Enriquecer base de datos Descubrir medicamentos nuevos o variantes NO
Validar interacciones Verificar pares de medicamentos NO
Mejorar algoritmos Entrenar modelos de adherencia NO
Estadisticas agregadas Medicamentos mas usados por region NO
Detectar patrones Combinaciones terapeuticas comunes NO

2.2. Requisito de Privacidad Absoluto

PRINCIPIO FUNDAMENTAL: El servidor DEBE poder procesar la lista de medicamentos, pero NUNCA DEBE poder asociar esa lista a un usuario especifico.

ESCENARIO IDEAL:
+----------------+                          +----------------+
|   Dispositivo  |   Datos Anonimizados     |   Servidor     |
|   Usuario #123 |  --------------------->  |                |
|                |   [Metformin, Enalapril] |   NO SABE que  |
|                |   Token: a7f2b9c3        |   viene del    |
|                |   Region: MX             |   Usuario #123 |
+----------------+                          +----------------+

3. Tecnicas de Anonimizacion

3.1. K-Anonymity

Definicion: K-anonymity asegura que cada individuo en un dataset no puede distinguirse de al menos k-1 otros individuos respecto a los quasi-identificadores.

ANTES (k=1, identificable):
+----------+---------------+------------------------+
| Usuario  | Region        | Medicamentos           |
+----------+---------------+------------------------+
| U001     | CDMX          | [Metformin, Insulina]  |  <- Unico
| U002     | Monterrey     | [Atorvastatina]        |  <- Unico
+----------+---------------+------------------------+

DESPUES (k=3, anonimizado):
+----------+---------------+------------------------+
| Grupo    | Region        | Medicamentos           |
+----------+---------------+------------------------+
| G-A      | Norte Mexico  | [Antidiabeticos]       |  <- 3+ usuarios
| G-B      | Norte Mexico  | [Estatinas]            |  <- 3+ usuarios
+----------+---------------+------------------------+

Limitaciones para MedTime:

Problema Descripcion Severidad
Homogeneity Attack Si todos en un grupo tienen el mismo medicamento raro, se revela informacion Alta
Background Knowledge Atacante con info externa puede inferir identidad Media
Perdida de utilidad Generalizacion excesiva reduce valor de datos Alta

Aplicabilidad: PARCIAL - Util como capa complementaria, no como solucion unica.

3.2. L-Diversity

Definicion: L-diversity requiere que cada clase de equivalencia tenga al menos l valores bien representados para cada atributo sensible.

EJEMPLO l-diversity (l=3):
+----------+------------------------+
| Grupo    | Medicamentos (diversos)|
+----------+------------------------+
| G-A      | Metformin (40%)        |
|          | Insulina (35%)         |
|          | Glibenclamida (25%)    |  <- 3 valores diversos
+----------+------------------------+

Limitaciones:

Problema Descripcion
Skewness Attack Distribucion sesgada puede revelar info
Similarity Attack Valores semanticamente similares reducen privacidad
Complejidad Dificil mantener diversidad con datos reales

Aplicabilidad: LIMITADA - Dificil de aplicar a listas de medicamentos variables.

3.3. T-Closeness

Definicion: T-closeness requiere que la distribucion de un atributo sensible en cualquier clase de equivalencia sea cercana (distancia <= t) a la distribucion global.

DISTRIBUCION GLOBAL:
Antidiabeticos: 30%
Antihipertensivos: 25%
Estatinas: 20%
Otros: 25%

CLASE DE EQUIVALENCIA (debe ser similar):
Antidiabeticos: 32%    <- |diff| = 2%
Antihipertensivos: 23% <- |diff| = 2%
Estatinas: 22%         <- |diff| = 2%
Otros: 23%             <- |diff| = 2%

Distancia total = 8% <= t (umbral)

Aplicabilidad: MEDIA - Util para proteger distribucion de categorias terapeuticas.

3.4. Differential Privacy (Recomendado)

Definicion: Differential Privacy garantiza que la probabilidad de cualquier output del proceso de anonimizacion no cambia "significativamente" si se agrega o elimina un individuo del dataset.

FORMULA:
Pr[M(D) = O] <= e^epsilon * Pr[M(D') = O]

Donde:
- M: Mecanismo de privacidad
- D: Dataset original
- D': Dataset sin un individuo
- epsilon: Parametro de privacidad (menor = mas privado)
- O: Output observado

Mecanismos para MedTime:

Mecanismo Uso Descripcion
Laplaciano Conteos Agrega ruido Laplace a conteos de medicamentos
Gaussiano Promedios Agrega ruido Gaussiano a estadisticas
Randomized Response Binario Volteo aleatorio de respuestas
Exponential Seleccion Seleccion privada de categorias

Nota sobre Differential Privacy en MedTime:

IMPORTANTE: MedTime usaSEPARACIÓN DE IDENTIDAD como enfoque principal, NO generalización a categorías. Differential Privacy es una técnica complementaria opcional para estadísticas agregadas, pero NO se usa para transformar medicamentos específicos en categorías genéricas.

# PSEUDOCODIGO - Anonimización por Separación de Identidad
def reportar_medicamentos_anonimos(lista_medicamentos, user_context):
    """
    Reporta medicamentos SIN vínculo a identidad del usuario.
    El servidor SÍ ve los medicamentos específicos, pero NO sabe de quién son.
    """

    # 1. MANTENER medicamentos específicos (NO generalizar)
    medicamentos = [med.nombre for med in lista_medicamentos]
    dosis = [med.dosis for med in lista_medicamentos]

    # 2. ELIMINAR todos los identificadores de usuario
    # user_context.user_id -> NO SE ENVÍA
    # user_context.email -> NO SE ENVÍA
    # user_context.device_id -> NO SE ENVÍA
    # user_context.ip -> NO SE ENVÍA

    # 3. Generalizar solo metadata de contexto
    region = generalizar_region(user_context.region)  # "CDMX" -> "Centro"
    periodo = generalizar_timestamp(now())  # "2025-12-05" -> "2025-12"

    # 4. Generar token efímero no vinculado
    session_token = random_bytes(32)  # Nuevo cada sesión

    return {
        "session_token": session_token,
        "medicamentos": medicamentos,  # ["Glucophage 850mg", "Enalapril 10mg"]
        "dosis": dosis,
        "region": region,
        "periodo": periodo
        # SIN user_id, email, device_id, IP
    }

Ventajas de Differential Privacy:

Ventaja Descripcion
Garantia matematica Proteccion demostrable contra cualquier atacante
Composicion Multiples consultas tienen privacidad acotada
Post-procesamiento Cualquier operacion posterior mantiene garantia
Robustez Resistente a ataques con conocimiento auxiliar

Aplicabilidad: ALTA - Recomendado como mecanismo principal.

3.5. Data Masking y Pseudonimizacion

ISO 25237:2017 - Health Informatics Pseudonymization:

"Pseudonimizacion es el proceso donde datos personales no pueden atribuirse a un sujeto especifico sin el uso de informacion adicional, siempre que dicha informacion se mantenga separada."

PSEUDONIMIZACION EN MEDTIME:
+------------------+     +------------------+     +------------------+
|   Dispositivo    |     |   Gateway        |     |   Servidor       |
|                  |     |   Anonimizador   |     |   Procesamiento  |
|  user_id: U123   |---->|  Elimina         |---->|  No tiene        |
|  meds: [A,B,C]   |     |  user_id         |     |  user_id         |
|  timestamp: T    |     |  Generaliza T    |     |  Solo datos      |
+------------------+     +------------------+     +------------------+

Tecnicas de Masking para Medicamentos:

Tecnica Aplicacion Ejemplo
Generalizacion Reducir especificidad "Metformin 850mg" -> "Antidiabetico oral"
Supresion Eliminar datos raros Omitir medicamentos con <1000 usuarios globales
Tokenizacion Reemplazar con tokens "Metformin" -> "MED_CAT_A_001"
Truncamiento Reducir precision "10:35:22" -> "Manana"
Agrupacion (Bucketing) Agrupar valores "5 medicamentos" -> "3-7 medicamentos"

4. Arquitectura Propuesta

4.1. Principio de Separacion de Identidad

+-----------------------------------------------------------------------+
|                        ARQUITECTURA DE ANONIMIZACION                   |
+-----------------------------------------------------------------------+
|                                                                        |
|  +------------------+                         +------------------+      |
|  |   CAPA IDENTIDAD |                         |   CAPA DATOS     |      |
|  |   (Dispositivo)  |                         |   (Servidor)     |      |
|  +------------------+                         +------------------+      |
|  | - user_id        |       BARRERA DE        | - tokens_sesion  |      |
|  | - email          |       SEPARACION        | - categorias_med |      |
|  | - nombre         |    ================>    | - regiones_gen   |      |
|  | - meds_reales    |       IRREVERSIBLE      | - timestamps_gen |      |
|  +------------------+                         +------------------+      |
|                                                                        |
|  La identidad NUNCA cruza la barrera. Los datos llegan sin origen.     |
+-----------------------------------------------------------------------+

4.2. Tokens de Sesion Desvinculados

Problema: Si usamos tokens fijos por usuario, multiples envios del mismo usuario son correlacionables.

Solucion: Tokens de sesion efimeros, no vinculados a identidad:

GENERACION DE TOKEN ANONIMO:

Dispositivo:
1. session_id = random_bytes(32)  // Nuevo cada sesion
2. NO incluir user_id, device_id, ni derivados
3. Token valido solo para esta transmision

Servidor:
- Recibe session_id efimero
- NO puede correlacionar con envios anteriores del mismo usuario
- Procesa datos y descarta session_id

Implementacion:

// PSEUDOCODIGO - Cliente (Dispositivo)
async function enviarDatosAnonimos(listaMedicamentos) {
    // 1. Generar token efimero (no vinculado a usuario)
    const sessionToken = crypto.randomBytes(32).toString('hex');

    // 2. Anonimizar datos localmente
    const datosAnonimos = {
        session_token: sessionToken,  // Efimero, no rastreable
        categorias: generalizarMedicamentos(listaMedicamentos),
        region: generalizarRegion(usuario.region), // "CDMX" -> "Centro"
        rango_edad: generalizarEdad(usuario.edad), // 45 -> "40-50"
        timestamp: generalizarTimestamp(Date.now()) // "Diciembre 2025"
    };

    // 3. NO incluir ningun identificador de usuario
    // datosAnonimos.user_id = ... // PROHIBIDO

    return await enviarAServidor('/api/v1/analytics/anonymous', datosAnonimos);
}

4.3. Agregacion Antes de Transmision

Concepto: Agregar datos de multiples usuarios en el dispositivo antes de enviar, haciendo imposible distinguir contribuciones individuales.

OPCION A: Agregacion por Batches Locales (Single User)
+-------------------+
| Dispositivo       |
| Usuario U1        |
+-------------------+
| Dia 1: [Med A]    |
| Dia 2: [Med A,B]  |  --Batch semanal-->  {categorias: {cat_A: 7, cat_B: 3}}
| Dia 7: [Med A,B]  |
+-------------------+

OPCION B: Secure Aggregation (Multi-User) - Avanzado
+-------------------+     +-------------------+     +-------------------+
| Dispositivo U1    |     | Dispositivo U2    |     | Dispositivo U3    |
| vector: [1,0,1]   |     | vector: [1,1,0]   |     | vector: [0,1,1]   |
+-------------------+     +-------------------+     +-------------------+
         |                        |                        |
         +------------------------+------------------------+
                                  |
                         Agregacion Segura
                                  |
                                  v
                    Servidor recibe: [2, 2, 2]
                    (suma, sin ver individuales)

4.4. Flujo de Datos Anonimizados Completo

sequenceDiagram
    participant D as Dispositivo
    participant A as Modulo Anonimizador (Local)
    participant S as Servidor MedTime
    participant P as Procesador Analitico

    Note over D: Usuario tiene: Metformin 850mg, Enalapril 10mg

    D->>A: Lista de medicamentos del usuario

    Note over A: PASO 1: SEPARACIÓN DE IDENTIDAD (NO generalización)
    A->>A: Mantener "Metformin 850mg" (SÍ se envía específico)
    A->>A: Mantener "Enalapril 10mg" (SÍ se envía específico)

    Note over A: PASO 2: Eliminar TODOS los identificadores
    A->>A: Eliminar user_id, device_id, IP, email
    A->>A: Generalizar timestamp: "2025-12-05 10:30" -> "2025-12"
    A->>A: Generalizar region: "CDMX" -> "Centro Mexico"

    Note over A: PASO 3: Generar token efímero
    A->>A: session_token = random(32 bytes)
    A->>A: Token NO vinculado a usuario, nuevo cada sesión

    A->>S: Enviar paquete anonimizado
    Note right of S: {session: "a7f2...", medicamentos: ["Metformin 850mg", "Enalapril 10mg"], region: "centro_mx", periodo: "2025-12"}

    S->>P: Procesar para enriquecer catálogos

    Note over P: Servidor SÍ sabe:<br/>- Medicamentos específicos usados<br/>- Dosis exactas<br/>- Región generalizada<br/>- Período (mes/año)<br/><br/>Servidor NO sabe:<br/>- Quién es el usuario<br/>- user_id, email, device_id<br/>- IP, timestamps exactos<br/>- Historial del usuario

4.5. Batch Processing para Evitar Correlacion Temporal

Problema: Si el servidor recibe datos en tiempo real, puede correlacionar por timestamp.

Solucion: Procesamiento por lotes con retrasos aleatorios.

MECANISMO DE BATCHING:

Dispositivo:
1. Acumular eventos localmente (24-168 horas)
2. Seleccionar momento aleatorio para envio
3. Agregar jitter: delay_random(0, 6 horas)
4. Enviar batch completo

Resultado:
- Usuario cambia medicamento el Lunes 10:00
- Servidor recibe el dato entre Martes y Domingo
- Imposible correlacionar evento con momento exacto
# PSEUDOCODIGO - Batch Processing
class BatchAnonymizer:
    def __init__(self):
        self.batch = []
        self.batch_window_hours = 72  # 3 dias
        self.jitter_max_hours = 6

    def agregar_evento(self, evento_medicamento):
        # Almacenar localmente (cifrado)
        evento_generalizado = self.generalizar(evento_medicamento)
        self.batch.append(evento_generalizado)

        # Verificar si es momento de enviar
        if self.debe_enviar():
            self.enviar_batch()

    def debe_enviar(self):
        # Enviar cuando:
        # - Batch tiene >= 10 eventos, O
        # - Han pasado >= 72 horas desde primer evento
        # - Agregar jitter aleatorio
        return (
            len(self.batch) >= 10 or
            self.horas_desde_primer_evento() >= self.batch_window_hours
        )

    async def enviar_batch(self):
        # Agregar delay aleatorio para decorrelacionar
        jitter = random.uniform(0, self.jitter_max_hours * 3600)
        await asyncio.sleep(jitter)

        # Enviar batch anonimizado
        await self.enviar_a_servidor(self.batch)
        self.batch = []

5. Riesgos de Re-identificacion y Mitigaciones

5.1. Combinaciones Unicas de Medicamentos

Riesgo ALTO: Ciertas combinaciones de medicamentos son muy raras y pueden identificar individuos.

EJEMPLO DE RIESGO:
Usuario toma: [Imatinib, Trastuzumab, Letrozol]

Problemas:
1. Combinacion sugiere cancer de mama HER2+ con LMC
2. Solo 0.001% de usuarios tendrian esta combinacion
3. Con 1 millon de usuarios = ~10 personas
4. Con region + edad, podria ser unico

ATACANTE CON CONOCIMIENTO PREVIO:
"Se que Maria tiene cancer de mama y LMC"
+ "Datos anonimos muestran combinacion rara en Monterrey, mujer 50-60"
= Alta probabilidad de identificar a Maria

Mitigaciones:

Mitigacion Implementacion Efectividad
Supresion de raros No reportar combinaciones con <1000 usuarios globales Alta
Generalizacion agresiva [Imatinib, Trastuzumab] -> [Antineoplasico, Antineoplasico] Alta
Ruido DP Agregar medicamentos "falsos" con probabilidad p Alta
Agregacion temporal Solo reportar despues de N dias Media

Implementacion Recomendada:

# PSEUDOCODIGO - Supresion de Combinaciones Raras
def filtrar_combinaciones_raras(medicamentos, umbral_k=1000):
    """
    Suprime medicamentos que harian la combinacion rara.
    """
    # Consultar estadisticas globales (precalculadas, anonimas)
    freq_global = obtener_frecuencias_globales()

    # Ordenar medicamentos por rareza (menos frecuente primero)
    meds_ordenados = sorted(medicamentos,
                           key=lambda m: freq_global.get(m, 0))

    # Construir combinacion incrementalmente
    combinacion_segura = []
    for med in meds_ordenados:
        combinacion_tentativa = combinacion_segura + [med]

        # Verificar si combinacion es suficientemente comun
        if frecuencia_combinacion(combinacion_tentativa, freq_global) >= umbral_k:
            combinacion_segura = combinacion_tentativa
        else:
            # Suprimir este medicamento (muy raro)
            log_supresion(med, "combinacion_rara")

    return combinacion_segura

5.2. Patrones Temporales

Riesgo MEDIO: La secuencia de cambios en medicamentos puede ser unica.

EJEMPLO:
Semana 1: Agrega Metformin
Semana 3: Agrega Atorvastatina
Semana 5: Quita Metformin, agrega Insulina
Semana 8: Agrega Aspirina

Esta secuencia especifica puede ser unica entre usuarios.

Mitigaciones:

Mitigacion Descripcion
Solo estados, no cambios Reportar lista actual, no deltas
Agregacion temporal Reportar solo mensual/trimestral
Jitter en timestamps Agregar ruido a fechas
Eliminacion de orden Reportar conjuntos, no secuencias

5.3. Correlacion con Otros Datos

Riesgo MEDIO: Datos externos pueden correlacionarse con datos anonimizados.

VECTORES DE CORRELACION:
+-------------------+     +-------------------+     +-------------------+
| Datos MedTime     |     | Datos Externos    |     | Correlacion       |
| Anonimos          |     | (Atacante)        |     | Potencial         |
+-------------------+     +-------------------+     +-------------------+
| Region: Centro MX | + | Registro civil     | = | Poblacion reducida |
| Edad: 50-60       | + | Lista de pacientes | = | Match potencial    |
| Categoria: IECA   | + | Historial clinico  | = | Identificacion     |
+-------------------+     +-------------------+     +-------------------+

Mitigaciones:

Mitigacion Implementacion
K-anonymity como capa Asegurar grupos >= 1000 usuarios
No reportar combinaciones de quasi-identifiers Region + edad + categoria = suprimido
Generalizacion jerarquica "CDMX" -> "Centro" -> "Mexico"

5.4. Tabla de Riesgos y Mitigaciones

Riesgo Probabilidad Impacto Mitigacion Principal Mitigacion Secundaria
Combinacion unica de meds Alta Alto Supresion de raros Generalizacion a categorias
Medicamento muy raro Alta Alto Umbral k=1000 No reportar
Patron temporal Media Medio Solo estados actuales Agregacion mensual
Correlacion externa Media Alto K-anonymity complementario No enviar quasi-identifiers
Inferencia por volumen Baja Bajo Ruido DP en conteos Jitter en timestamps
Ataque de reconstruccion Baja Alto Epsilon bajo (e<1) Limitar consultas

6. Implementacion Tecnica

6.1. Algoritmos Especificos Recomendados

6.1.1. Local Differential Privacy (LDP) - Randomized Response

ALGORITMO: Randomized Response para Categorias de Medicamentos

Input:
- vector_categorias: vector binario [1,0,1,0,...] indicando categorias presentes
- epsilon: parametro de privacidad (recomendado: 1.0 - 4.0)

Output:
- vector_perturbado: vector con ruido DP

Pasos:
1. Para cada bit b en vector_categorias:
   a. Calcular p = e^epsilon / (1 + e^epsilon)
   b. Con probabilidad p: reportar b (valor real)
   c. Con probabilidad 1-p: reportar bit aleatorio

Ejemplo con epsilon=2.0:
- p = e^2 / (1 + e^2) = 0.88
- 88% de las veces reporta valor real
- 12% de las veces reporta valor aleatorio

6.1.2. Nota sobre Generalización Jerárquica

NOTA IMPORTANTE: MedTimeNO USA generalización jerárquica como enfoque principal. Esta sección se incluye solo como referencia académica. El enfoque de MedTime es SEPARACIÓN DE IDENTIDAD: enviar medicamentos específicos pero SIN ningún identificador de usuario.

ENFOQUE DE MEDTIME (Separación de Identidad):

LO QUE SE ENVÍA:                    LO QUE NO SE ENVÍA:
+---------------------------+       +---------------------------+
| Metformin 850mg           |       | user_id                   |
| Enalapril 10mg            |       | email                     |
| Región: "Centro Mexico"   |       | device_id                 |
| Período: "2025-12"        |       | IP                        |
| session_token: <efímero>  |       | timestamps exactos        |
+---------------------------+       +---------------------------+

El servidor VE los medicamentos específicos,
pero NO PUEDE vincularlos a ningún usuario.

La generalización jerárquica (Metformin → "Antidiabético") podría usarse como capa adicional de protección en casos de alto riesgo de re-identificación, pero NO es el enfoque estándar de MedTime.

6.1.3. Supresion Basada en Frecuencia

# PSEUDOCODIGO - Supresion Adaptativa
class SupresorAdaptativo:
    # Frecuencias globales (actualizadas periodicamente, anonimas)
    FRECUENCIAS_GLOBALES = cargar_frecuencias()

    # Umbral minimo de usuarios para reportar
    K_MINIMO = 1000

    def suprimir_raros(self, lista_medicamentos):
        """
        Elimina medicamentos que harian al usuario identificable.
        """
        resultado = []

        for med in lista_medicamentos:
            categoria = self.generalizar_a_categoria(med)
            freq = self.FRECUENCIAS_GLOBALES.get(categoria, 0)

            if freq >= self.K_MINIMO:
                resultado.append(categoria)
            else:
                # Suprimir - demasiado raro
                self.log_supresion(categoria)

        # Verificar combinacion completa
        freq_combinacion = self.frecuencia_combinacion(resultado)
        if freq_combinacion < self.K_MINIMO:
            # Combinacion muy rara - generalizar mas
            resultado = self.generalizar_mas(resultado)

        return resultado

6.2. Librerias y Frameworks Disponibles

6.2.1. Para Backend (Servidor)

Libreria Lenguaje Caracteristicas Uso en MedTime
Google Differential Privacy C++, Java, Go DP de Google, alta performance Procesamiento servidor
PipelineDP4j Java/Kotlin DP end-to-end para JVM Backend analytics
OpenDP Rust/Python Framework academico riguroso Validacion algoritmos
ARX Java K-anonymity, l-diversity, t-closeness, DP Anonimizacion datasets

6.2.2. Para Cliente (Movil)

Libreria Plataforma Caracteristicas Consideraciones
SwiftDP (OpenMined) iOS/Swift Wrapper de Google DP para iOS Requiere Objective-C++ bridge
Google DP (via C++) Android/iOS Compilacion nativa Alta complejidad
Implementacion propia LDP Kotlin/Swift Randomized Response es simple Recomendado para v1.0

Recomendacion para MedTime v1.0:

ARQUITECTURA RECOMENDADA:

CLIENTE (Movil):
- Implementacion propia de LDP (Randomized Response)
- Generalizacion jerarquica de medicamentos
- Supresion de raros (con tabla local de frecuencias)
- Batch processing con jitter

SERVIDOR:
- ARX para validacion de k-anonymity
- Google DP / PipelineDP4j para agregaciones
- OpenDP para auditorias matematicas

6.3. Consideraciones de Rendimiento Movil

Operacion Tiempo Estimado Impacto Bateria Optimizacion
Generalizacion (local) <10ms Minimo Tabla lookup
LDP Randomized Response <5ms Minimo Crypto seguro
Supresion (con lookup) <20ms Bajo Cache local
Batch + cifrado <100ms Bajo Background task
Transmision (batch) Variable Medio WiFi preferido
// PSEUDOCODIGO iOS - Implementacion Eficiente
class AnonymizadorEficiente {
    // Cache local de frecuencias (actualizado semanalmente)
    private var cacheFrequencias: [String: Int] = [:]

    // Generalizacion via lookup O(1)
    private let tablaGeneralizacion: [String: String] = cargarTabla()

    func anonimizar(medicamentos: [Medicamento]) -> DatosAnonimos {
        // 1. Generalizar - O(n) con lookup O(1)
        let categorias = medicamentos.map {
            tablaGeneralizacion[$0.nombre] ?? "OTRO"
        }

        // 2. Suprimir raros - O(n)
        let categoriasSeguras = categorias.filter {
            (cacheFrequencias[$0] ?? 0) >= 1000
        }

        // 3. Aplicar LDP - O(n)
        let vectorRuidoso = aplicarRandomizedResponse(
            categorias: categoriasSeguras,
            epsilon: 2.0
        )

        // 4. Preparar para batch
        return DatosAnonimos(
            categorias: vectorRuidoso,
            timestamp: generalizarTimestamp(Date()),
            region: generalizarRegion(usuario.region)
        )
    }
}

7. Validacion de Anonimato

7.1. Metricas para Verificar Anonimizacion Efectiva

Metrica Descripcion Umbral Recomendado
k-Anonymity Minimo de usuarios indistinguibles k >= 1000
l-Diversity Diversidad en categorias sensibles l >= 5
Epsilon (DP) Parametro de privacidad diferencial epsilon <= 2.0
Probabilidad re-identificacion P(identificar individuo) P < 0.001
Information gain Bits de informacion revelados < 1 bit por categoria

7.2. Framework de Auditoria

PROCESO DE AUDITORIA TRIMESTRAL:

1. ANALISIS DE DATOS ANONIMIZADOS
   +------------------+
   | Extraer muestra  |
   | de datos enviados|
   +--------+---------+
            |
            v
   +------------------+
   | Verificar        |
   | k-anonymity      |
   | (k >= 1000)      |
   +--------+---------+
            |
            v
   +------------------+
   | Verificar        |
   | supresion de     |
   | raros            |
   +--------+---------+

2. PRUEBAS DE RE-IDENTIFICACION
   +------------------+
   | Simular ataques  |
   | con conocimiento |
   | auxiliar         |
   +--------+---------+
            |
            v
   +------------------+
   | Medir tasa de    |
   | re-identificacion|
   | (< 0.1%)         |
   +--------+---------+

3. VALIDACION MATEMATICA
   +------------------+
   | Verificar epsilon|
   | efectivo con     |
   | OpenDP           |
   +------------------+

7.3. Pruebas de Re-identificacion

Metodologia de Testing:

# PSEUDOCODIGO - Prueba de Re-identificacion
def test_reidentificacion(datos_anonimizados, conocimiento_auxiliar):
    """
    Simula ataque de re-identificacion.

    Args:
        datos_anonimizados: Dataset anonimizado a probar
        conocimiento_auxiliar: Datos externos que atacante podria tener

    Returns:
        tasa_exito: Porcentaje de registros re-identificados
    """

    exitos = 0
    intentos = len(datos_anonimizados)

    for registro in datos_anonimizados:
        # Intentar vincular con conocimiento auxiliar
        candidatos = buscar_candidatos(registro, conocimiento_auxiliar)

        if len(candidatos) == 1:
            # Re-identificacion exitosa (unico match)
            exitos += 1
        elif len(candidatos) <= 5:
            # Casi exitoso (pocos candidatos)
            exitos += 0.2

    tasa_exito = exitos / intentos

    # UMBRAL: < 0.1% tasa de exito
    assert tasa_exito < 0.001, f"Tasa de re-identificacion muy alta: {tasa_exito}"

    return tasa_exito

7.4. Auditorias Periodicas

Tipo Frecuencia Responsable Entregable
Automatizada Continua Sistema Dashboard metricas
Interna Mensual Equipo Seguridad Reporte tecnico
Externa Trimestral Auditor independiente Certificacion
Regulatoria Anual Autoridad (INAI/OCR) Cumplimiento

8. Cumplimiento Regulatorio

8.1. Mapeo a Regulaciones

Regulacion Requisito Como lo cumple esta arquitectura
HIPAA De-identification (Safe Harbor/Expert) Supresion de 18 identificadores + DP
LGPD Anonimizacao (Art. 12) Datos no pueden asociarse a titular
LFPDPPP Disociacion (Art. 3-V) Procedimiento irreversible
GDPR Anonymisation Datos ya no son "personales"
ISO 25237 Pseudonymization requirements Separacion de identidad

8.2. Safe Harbor vs Expert Determination (HIPAA)

METODO SAFE HARBOR (18 identificadores):
+------------------+--------------------+---------------------+
| Identificador    | Eliminado en       | Metodo              |
+------------------+--------------------+---------------------+
| Nombres          | Dispositivo        | No transmitido      |
| Fechas           | Dispositivo        | Generalizado a mes  |
| Telefonos        | Dispositivo        | No transmitido      |
| Geografia        | Dispositivo        | Generalizado        |
| ...              | ...                | ...                 |
+------------------+--------------------+---------------------+

METODO EXPERT DETERMINATION:
- Experto certifica que riesgo de re-identificacion es "muy pequeno"
- Documenta metodologia estadistica
- MedTime usa AMBOS metodos para maxima proteccion

8.3. Documentacion Requerida

Documento Contenido Actualizacion
Privacy Impact Assessment (PIA) Analisis de riesgos y mitigaciones Anual
Data Processing Agreement (DPA) Terminos de procesamiento anonimo Inicial
Technical Specification Algoritmos y parametros Por cambio
Audit Trail Logs de anonimizacion Continuo
User Consent Consentimiento para analytics Registro

9. Modelo de Datos para Anonimizacion

9.1. Estructura de Datos Anonimizados

// ESQUEMA - Datos Anonimizados Transmitidos
// NOTA: Se usa SEPARACIÓN DE IDENTIDAD, no generalización a categorías
interface DatosAnonimosMedicamentos {
    // Token efimero (no vinculado a usuario)
    session_token: string;  // 32 bytes aleatorios, nuevo cada sesión

    // Medicamentos ESPECÍFICOS (SÍ se envían)
    medicamentos: string[];  // ["Glucophage 850mg", "Enalapril 10mg"]
    dosis: string[];  // ["850mg", "10mg"]

    // Metadata generalizada (protección adicional)
    region_generalizada: string;  // "Centro Mexico" (no ciudad exacta)
    periodo: string;  // "2025-12" (solo mes/año, no timestamp exacto)

    // Control de calidad
    version_anonimizador: string;  // "1.0.0"
}

// LO QUE SÍ SE INCLUYE (anonimizado por separación de identidad):
// + medicamentos específicos (Glucophage, no "antidiabético")
// + dosis exactas
// + región generalizada
// + período (mes/año)

// LO QUE NUNCA SE INCLUYE (eliminado completamente):
// - user_id
// - device_id
// - email
// - nombre del usuario
// - timestamps exactos
// - IP
// - cualquier identificador directo o indirecto

9.2. Tabla de Frecuencias Globales (Publica)

// ESQUEMA - Frecuencias Globales (para cliente)
interface FrecuenciasGlobales {
    version: string;
    fecha_actualizacion: string;

    // Frecuencias por categoria (k-anonymity)
    categorias: {
        [categoria: string]: {
            frecuencia_global: number;  // Usuarios que la usan
            puede_reportar: boolean;  // true si freq >= 1000
        }
    };

    // Frecuencias de combinaciones comunes
    combinaciones_comunes: {
        [combinacion: string]: number;  // "antidiabetico+ieca": 50000
    };
}

10. Diagrama de Arquitectura Completo

+===========================================================================+
|                    ARQUITECTURA DE ANONIMIZACION MEDTIME                   |
+===========================================================================+

                          DISPOSITIVO (LOCAL)
+-------------------------------------------------------------------------+
|                                                                          |
|  +------------------+     +------------------+     +------------------+   |
|  | Datos Usuario    |     | Anonimizador     |     | Cola de Batch    |   |
|  |                  |     | Local            |     |                  |   |
|  | user_id: U123    |     |                  |     | [dato_anon_1]    |   |
|  | meds: [Met,Ena]  |---->| 1. Generalizar   |---->| [dato_anon_2]    |   |
|  | region: CDMX     |     | 2. Suprimir raros|     | [dato_anon_3]    |   |
|  | edad: 47         |     | 3. Aplicar LDP   |     | ...              |   |
|  +------------------+     | 4. Gen token     |     +--------+---------+   |
|                           +------------------+              |             |
|                                                             |             |
|  +------------------+                              +--------v---------+   |
|  | Frecuencias      |<-----(Actualizar semanal)---|  Gestor Batch    |   |
|  | Globales (cache) |                              |                  |   |
|  +------------------+                              | - Acumular 72h   |   |
|                                                    | - Jitter envio   |   |
|                                                    | - Cifrar TLS     |   |
|                                                    +--------+---------+   |
|                                                             |             |
+-------------------------------------------------------------------------+
                                                              |
                               BARRERA DE ANONIMIZACION       |
                        ======================================|=======
                                                              |
                                                              v
                              RED (TLS 1.3)
+-------------------------------------------------------------------------+
|                                                                          |
|                           SERVIDOR (BACKEND)                             |
|                                                                          |
|  +------------------+     +------------------+     +------------------+   |
|  | API Gateway      |     | Validador        |     | Procesador       |   |
|  |                  |     | Anonimato        |     | Analytics        |   |
|  | - Sin logs IP    |---->| - Verificar k    |---->| - Agregar datos  |   |
|  | - Token efimero  |     | - Verificar DP   |     | - Entrenar ML    |   |
|  | - No session     |     | - Descartar ID   |     | - Generar stats  |   |
|  +------------------+     +------------------+     +--------+---------+   |
|                                                             |             |
|                                                             v             |
|  +------------------+     +------------------+     +------------------+   |
|  | Frecuencias      |<----| Agregador        |<----| Dataset          |   |
|  | Actualizadas     |     | Estadistico      |     | Anonimo          |   |
|  | (para clientes)  |     | (con DP)         |     | (sin IDs)        |   |
|  +------------------+     +------------------+     +------------------+   |
|                                                                          |
+-------------------------------------------------------------------------+

GARANTIAS (SEPARACIÓN DE IDENTIDAD):
- El servidor NUNCA recibe user_id, device_id, email, IP, ni identificadores
- El servidor SÍ recibe medicamentos específicos (Glucophage, no "antidiabético")
- El servidor SÍ recibe dosis exactas
- Cada transmision usa token efimero no correlacionable
- Región generalizada (Centro Mexico, no CDMX)
- Período generalizado (2025-12, no timestamp exacto)
- El servidor NO PUEDE vincular medicamentos a ningún usuario específico
- Consentimiento OBLIGATORIO para usuarios con cuenta (requisito de uso)

11. Recomendaciones de Implementacion

11.1. Para MedTime v1.0 (Separación de Identidad)

ENFOQUE PRINCIPAL: Separación de identidad (enviar medicamentos específicos SIN identificadores de usuario)

Componente Prioridad Complejidad Recomendacion
Eliminación de identificadores CRÍTICA Baja Filtrar user_id, email, device_id, IP
Tokens efímeros CRÍTICA Baja crypto.randomBytes(32), nuevo cada sesión
Generalización de región Alta Baja "CDMX" → "Centro Mexico"
Generalización de timestamp Alta Baja "2025-12-05 10:30" → "2025-12"
Consentimiento obligatorio CRÍTICA Media Obtener durante onboarding
Batch processing Media Media Cola local, envío diferido
Jitter temporal Media Baja delay aleatorio en envíos

Nota: NO se generalizan medicamentos a categorías. Se envía "Glucophage 850mg", no "Antidiabético".

11.2. Para Versiones Futuras

Componente Version Descripcion
Secure Aggregation v2.0 Agregacion multiusuario
Federated Learning v2.0 ML sin datos centralizados
Verificacion formal DP v1.5 Prueba matematica con OpenDP
Auditoria externa v1.0+ Certificacion independiente

11.3. Checklist de Implementacion

FASE 1: INFRAESTRUCTURA - SEPARACIÓN DE IDENTIDAD (v1.0)
[ ] Implementar filtro de identificadores (eliminar user_id, email, device_id, IP)
[ ] Crear generador de tokens efímeros (32 bytes, nuevo cada sesión)
[ ] Implementar generalización de región (CDMX  Centro Mexico)
[ ] Implementar generalización de timestamp (fecha  mes/año)
[ ] Implementar cola de batch local para envío diferido
[ ] Agregar jitter aleatorio al envío

FASE 2: CONSENTIMIENTO Y FLUJO (v1.0)
[ ] Implementar flujo de consentimiento OBLIGATORIO en onboarding
[ ] Integrar anonimizador en flujo de sync
[ ] Configurar API sin logs de IP
[ ] Validar que medicamentos específicos  se envían
[ ] Validar que identificadores NUNCA se envían
[ ] Documentar Privacy Impact Assessment

FASE 3: VALIDACION (v1.0)
[ ] Ejecutar pruebas de re-identificación (verificar que user_id no se filtra)
[ ] Auditoria interna de código
[ ] Revision legal de cumplimiento (LFPDPPP, LGPD, HIPAA)
[ ] Pruebas de penetración
[ ] Verificar que consentimiento se obtiene correctamente

FASE 4: OPERACION (v1.0+)
[ ] Monitoreo continuo: verificar ausencia de identificadores en logs
[ ] Auditorias trimestrales de anonimización
[ ] Ajuste de proceso según regulaciones actualizadas

12. Referencias

12.1. Estandares y Normativas

12.2. Papers Academicos y Tecnicos

12.3. Herramientas y Librerias

12.4. Documentos MedTime Relacionados

12.4.1. Especificaciones de Anonimización (Serie INV-010)

Documento Descripción Catálogo Enriquecido
INV-010 (este documento) Anonimización de medicamentos Catálogo de Medicamentos
INV-011 Anonimización de estudios y tratamientos Catálogo de Estudios
INV-012 Anonimización de interacciones med-med Catálogo de Interacciones
INV-013 Anonimización de interacciones med-estudio Catálogo de Interacciones Med-Estudio
INV-014 Anonimización de efectos secundarios Catálogo de Efectos Adversos

12.4.2. Documentos de Cumplimiento y Regulaciones

12.4.3. Módulos Funcionales

  • MTS-PRI-001: Privacidad y Consentimiento
  • MTS-CAT-001: Catálogo de Medicamentos
  • MTS-MED-001: Medicamentos
  • MTS-AUTH-001: Autenticación y Seguridad

12.4.4. Especificación Técnica


13. Glosario Especifico

Termino Definicion
K-Anonymity Propiedad donde cada registro es indistinguible de al menos k-1 otros
L-Diversity Extension de k-anonymity que requiere diversidad en atributos sensibles
T-Closeness Extension que requiere distribucion similar a la poblacion
Differential Privacy Marco matematico que limita lo que puede inferirse de un individuo
Epsilon (ε) Parametro de privacidad en DP; menor = mas privado
LDP Local Differential Privacy - DP aplicado en el dispositivo
Randomized Response Tecnica donde respuestas se voltean aleatoriamente
Quasi-identificador Atributo que combinado puede identificar individuos
Re-identificacion Proceso de vincular datos anonimos con identidad
Safe Harbor Metodo HIPAA que elimina 18 identificadores especificos

Documento generado por SpecQueen (KnowledgeDrone) - "La resistencia es futil. Tus datos seran anonimizados... perfectamente."