Módulo 4 · Autenticación y seguridad

Lección 23 — Secretos, rate limiting y RGPD

Gestión de secretos, límites de peticiones y protección de datos personales.

Publicada
En esta lección
  1. Ejercicio 1 — Token bucket con y sin atomicidad
  2. Ejercicio 2 — Secretos en tu repo
  3. Ejercicio 3 — Derechos RGPD en tu API
  4. Ejercicio 4 — Audit log mínimo
  5. Ejercicio 5 — Minimización
  6. Entrega

Redis + tu proyecto. No mires solutions.md hasta entregar.

Ejercicio 1 — Token bucket con y sin atomicidad

  1. Implementa allow(key, capacity, refill) con HGETALL/HSET como la lección. Demuestra la raza: 20 threads concurrentes pidiendo con capacity=5: ¿cuántos pasan? (deberían pasar 5; anota cuántos pasaron de verdad).
  2. Arregla con un script Lua (o django-ratelimit): repite la prueba. ¿Ahora sí son exactamente 5?
  3. Configura los límites reales de TicketFlow: login 5/min por usuario+IP, checkout 10/min por usuario, API pública 60/min por IP. ¿Dónde pondrías 429 y qué cabecera mandas?

Ejercicio 2 — Secretos en tu repo

  1. Corre trufflehog o git-secrets (o gitleaks) sobre tu historial: ¿apareció algo? (la 05 hizo limpieza; verifica).
  2. Inventa la rotación de la clave de pasarela: escribe el runbook paso a paso con rotación dual (aceptar dos claves → cambiar de usar vieja a nueva → revocar vieja) y qué código lo permite (setting con lista de claves válidas).
  3. ¿Dónde viviría GATEWAY_SECRET en tu despliegue ideal (nube/vault/env del orquestador) y por qué no en la imagen Docker?

Ejercicio 3 — Derechos RGPD en tu API

  1. GET /api/me/export/: JSON con perfil + reservas + pagos del usuario autenticado (solo el suyo, obviamente). ¿Qué forma le darías: un JSON gigante o un job con download? Justifica con el volumen esperado.
  2. DELETE /api/me/ → anonimización: email → f"{uuid}@anonymized", nombre → "Usuario eliminado", state de la cuenta → DELETED, sin borrar reservas/pagos. Implementa al menos el modelo y la transacción (10: atómica).
  3. ¿Qué pasa con su MFA, sus tokens y su membresía de organizador al anonimizar? Enumera y decide.

Ejercicio 4 — Audit log mínimo

  1. Modelo AuditLog(actor, action, object_type, object_id, before JSONB, after JSONB, created_at) append-only. Escribe el helper audit(user, "role.change", user_obj, before, after).
  2. Conéctalo al cambio de rol de la 21 (staff endpoint) y al reembolso. ¿Cómo garantizas append-only (sin UPDATE/DELETE desde la app)? (permisos de BD o señal que lo impida).
  3. Consulta: "quién cambió roles en marzo": escribe la query que respondería en un incidente.

Ejercicio 5 — Minimización

  1. Audita tu modelo User/Reservation: ¿qué campo sobra o debería ser opcional? Propón la eliminación con migración (11) y justifica con el Art. 5 (minimización).
  2. Escribe la política de retención: ¿cuánto viven los PENDING expirados, los tokens de reset, los logs de acceso? Propón el job que purga (el cron de la 31).

Entrega

Pega el conteo de threads que pasaron (antes/después), el runbook de rotación y la anonimización. Cierra el módulo de seguridad; después Lección 24 — SOLID e inyección de dependencias.