Módulo 12 · Nivel empresarial (integración)

Lección 56 — Cumplimiento

RGPD, logs de auditoría y SOC 2 / ISO 27001 en visión general.

Publicada
En esta lección
  1. Ejercicio 1 — Las bases legales
  2. Ejercicio 2 — El mapa del Art. 30
  3. Ejercicio 3 — Las evidencias SOC 2
  4. Ejercicio 4 — El audit log y la brecha
  5. Ejercicio 5 — El DPO interno
  6. Resumen del profesor

Ejercicio 1 — Las bases legales

  1. La clasificación: email (contrato: la venta), teléfono opcional (consentimiento: solo si el org quiere avisos SMS), historial de compras (contrato + obligación fiscal: la retención), IP del login (interés legítimo: seguridad, la 23), la cookie analítica (consentimiento ANTES de cargarla: el banner), la foto del org (consentimiento + licitud del contenido). La tabla con la base por fila: el dato sin base no se recoge (minimización).
  2. La evidencia del opt-in:
python
class MarketingConsent(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    version_texto = models.CharField(max_length=20)     # "v2027-03"
    concedido_en = models.DateTimeField()
    revocado_en = models.DateTimeField(null=True)

# el filtro del marketing: consentimiento ACTIVO (concedido y no revocado) — el flag derivado, no el booleano suelto
  1. El flujo de supresión extendida: el perfil y los contactos se BORRAN; el email del ticket/ledger se ANONIMIZA (u-841@deleted.invalid — la integridad del histórico de facturación preservada) y el audit registra "supresión ejecutada por request X, 3 tablas, 2 anonimizadas". El test: el export posterior sin PII + el ledger cuadrando (la comisión del mes idéntica): la excepción legal del dinero funciona sin romper la facturación.

Ejercicio 2 — El mapa del Art. 30

  1. Los hallazgos del mapa: el log del 45: identificadores técnicos sin PII (base: interés legítimo, retención 30 días); la caché de perfil (38): PII en Redis → base contrato + purge por usuario (23) + TTL 60 s (el dato que caduca solo: la retención en el caché); la tabla de invitados del evento (el campo libre del nombre de los acompañantes): sin clasificar → clasificada (contrato, retención fin del evento + fiscal).
  2. El guard del PII: el test que escanea las claves de caché activas y las líneas de log de ejemplo contra los regex de email/teléfono: 0 matches. El hallazgo típico: el detalle del 26 con el email que el usuario escribió mal (el log del error llevaba el payload: corregido con el identificador).
  3. El doc del mapa con la revisión trimestral y el dueño: el documento del Art. 30 con el enlace a cada schema (48: doc-enlazado-al-código).

Ejercicio 3 — Las evidencias SOC 2

  1. Las 3 evidencias (scripts del repo):
bash
manage.py reporte_accesos --desde 2027-07   # los escalados de rol del audit (23/21)
manage.py reporte_secretos                  # las rotaciones del 27 con fecha y actor
manage.py reporte_cambios --sin-review      # los deploy sin PR: esperado 0 (41)
  1. La cadena de cambios probada: el push directo a main → bloqueado (protección de branch: el PR + CI del 41); el kubectl apply fuera del pipeline → el diff del drift del 44 lo caza al plan siguiente; el hotfix de emergencia → PR de emergencia con review posterior documentado (el 47). Los controles de cambio con evidencia: el CI + el IaC.
  2. El gap honesto: el access review trimestral (¿quién tiene acceso que ya no necesita?) no existía → el issue con dueño/fecha (el script del ejercicio 1 como su base). El gap declarado: el control en camino.

Ejercicio 4 — El audit log y la brecha

  1. Las consultas del auditor con su test:
python
def test_consulta_de_datos_de_usuario_solo_admin(self):
    self.client.force_authenticate(self.soporte)          # NO es auditor
    r = self.client.get(f"/admin/audit/dato/{self.user.id}")
    self.assertEqual(r.status_code, 403)                   # el 21: el acceso a la auditoría es privilegiado
    self.client.force_authenticate(self.auditor)
    self.assertEqual(self.client.get(...).status_code, 200)  # y la consulta quedó auditada (¡el meta-audit!)
  1. La retención como job: con FakeClock 13 meses: la fila de audit > 12 meses se archiva a frío (el bucket del 42) y el registro del purgado queda en audit. El consentimiento revocado: el dato de marketing purgado en el siguiente ciclo con su fila ("purgado por revocación").
  2. El runbook de brecha (extracto): T0 detectar (alerta del 46) → T+1h acotar (47: protocolo) → T+2h contener (flag/rollback 41) → T+24h evaluar riesgo (¿alto? → notificar afectados) → T+72h notificar regulador (la plantilla del doc) → postmortem con la acción regulatoria. Los umbrales escritos: "datos sensibles o >100 afectados: afectados siempre; el resto: evaluación del DPO" — la decisión documentada antes del reloj.

Ejercicio 5 — El DPO interno

  1. El linter del esquema:
python
def test_toda_tabla_con_pii_clasificada(self):
    for model in MODELOS_CON_DATOS_PERSONALES:
        assert hasattr(model, "data_classification"), \
            f"{model.__name__} sin base legal/retención: el mapa del Art. 30 miente"

El data_classification = {"base": "contrato", "retencion": "5y"} en el Meta: el esquema anota su cumplimiento (el mapa del §2 generado del código: la referencia viva del 48).

  1. El diagrama del DPO interno:
[mapa Art.30 generado del schema] ← el linter de clasificación (1)
[export/supresión API]  → audit ← SLA minutos (23)
[jobs de retención 31]  → audit ← purgados automáticos (4)
[evidencias SOC 2]      → reportes cron (3)
[runbook de brecha]     → doc con caducidad (48)
  1. La checklist final (10 ítems): bases legales, mapa generado, consentimiento con evidencia, supresión con excepción del dinero, portabilidad, PII en log/caché guardada, audit consultas del auditor, retención automatizada, runbook de brecha, evidencias SOC 2 (3 de 5: el access review en issue). El estado real: 9 de 10 — el cumplimiento como consecuencia de la ingeniería del curso, con el gap restante documentado.

Resumen del profesor

  • El RGPD se implementa en el ciclo del dato: base legal por dato, minimización, retención por tipo, y la supresión que respeta la excepción del dinero (anonimizar, no borrar la facturación).
  • SOC 2 audita controles operando: el curso ya produce las evidencias (PRs, rotaciones, drills, postmortems) — el 80% del certificado es ordenar la buena ingeniería.
  • El audit log append-only + las consultas del auditor + los jobs de retención + el linter de clasificación = el DPO interno: el cumplimiento como consecuencia observable del sistema.