Tema
Procedimiento de Retención y Eliminación Segura de Datos
Documento: DOC-DATA-RET-01 Versión: 1.0 Fecha de aprobación: 2026-07-29 Owner: Security Lead + DPO Frecuencia de revisión: Anual Referencias PCI DSS: Req 3.2.1, Req 3.3.1, Req 9.4 Cuestionario ControlCase: Pregunta 25
1. Propósito
Definir el procedimiento operativo y automatizado para (a) mantener la retención de datos protegidos al mínimo necesario y (b) eliminarlos de forma segura al final de su ciclo de vida.
2. Alcance
Aplica a todos los datos clasificados en COVERED-INFORMATION-DATA-MATRIX.md, incluyendo:
- CHD (PAN, cardholder name, exp) almacenado en
card_vault.stored_cards - SAD (CVV) en RAM del
tokenization-service - Backups de Postgres
- Logs de aplicación e infraestructura
- Snapshots de Vault
- Media físico decomisionado
3. Principios
- Mínima retención: solo se retiene el dato mientras exista justificación de negocio activa
- Purge irreversible: eliminación cripto o físicamente irreversible (no soft delete)
- Auditabilidad: toda ejecución del purge genera evento en audit log inmutable
- Verificabilidad: el QSA puede reproducir el conteo de datos borrados en cualquier momento
4. Retenciones definidas
Ver COVERED-INFORMATION-DATA-MATRIX.md §7 para la tabla autoritativa.
5. Procedimientos de eliminación
5.1 SAD (CVV) — purge continuo
Frecuencia: cada 60 segundos + inmediato post-autorización.
Mecanismo dual:
Immediate purge post-authorization
tokenization-servicerecibe respuesta del payment processor- Independiente del resultado (aprobada/declinada/error) → invalida
tok_cvv_*inmediatamente - Emite evento Kafka
fintrix.security.sad.purgedcontoken_id,reason=post_auth,timestamp
Cron sweeper (safety net)
- Cronjob
sad-purge-sweepercorre cada 60 seg - Query Vault kv-v2: lista tokens
tok_cvv_*con lease > 15 min - Ejecuta
vault kv delete secret/data/sad/{token_id} - Emite evento Kafka
fintrix.security.sad.purgedconreason=ttl_sweep
- Cronjob
Ubicación del código: backend/apps/tokenization-service/src/sad/sad-purge.service.ts (SEC-019, pendiente de implementación)
Evidencia auditable:
- Vault audit log: entries
type=revoke path=sad/* - Kafka topic
fintrix.security.sad.purgedcon retention 7 años - Dashboard Grafana
SAD Purge Metricscon eventos/hora
5.2 PAN de tarjetas canceladas — purge diario
Frecuencia: diaria, 03:00 UTC (baja demanda).
Trigger: una tarjeta pasa a deleted_at IS NOT NULL cuando:
- El cliente elimina el payment method desde el dashboard
- La suscripción asociada se cancela y no queda otra suscripción activa con esa tarjeta
- El fraud team marca la tarjeta como comprometida
Ventana de gracia: 30 días desde deleted_at (para chargeback disputes).
Cronjob: pan-purge-canceled-cards
sql
-- Ejecutado por el cronjob (audit-logged):
BEGIN;
DELETE FROM card_vault.stored_cards
WHERE deleted_at IS NOT NULL
AND deleted_at < now() - interval '30 days'
RETURNING id, deleted_at;
-- rows returned se loguean con SHA-256 hash antes de commit
COMMIT;
-- Post-commit:
VACUUM FULL card_vault.stored_cards;
-- Fuerza reescritura del tablespace → dato en filesystem se sobrescribeUbicación del código: backend/apps/card-vault-service/src/purge/pan-purge.service.ts (SEC-020, pendiente de implementación)
Evidencia auditable:
- Postgres audit log (pgAudit extension) con
DELETEstatements + row counts - Kafka topic
fintrix.security.pan.purgedconcard_id_hash,purged_at,days_since_deletion - Job artifact en Kubernetes:
kubectl -n pci-cde logs job/pan-purge-canceled-cards-<date>
5.3 Backups >90 días
Frecuencia: automática vía DO Spaces object lifecycle policy.
Policy configurada en bucket fintrix-db-backup-nyc3:
json
{
"Rules": [
{
"ID": "PurgeBackupsOlderThan90Days",
"Status": "Enabled",
"Filter": { "Prefix": "postgres/" },
"Expiration": { "Days": 90 }
}
]
}Verificación:
bash
# Listar backups actuales con edad
s3cmd ls s3://fintrix-db-backup-nyc3/postgres/ | awk '{print $1, $NF}'
# Alerta si se encuentra archivo > 90 días5.4 Logs >365 días
Frecuencia: automática vía Loki retention + Spaces lifecycle.
- Loki:
retention_period: 2160h(90 días online) - DO Spaces archive: lifecycle policy con expiration a 275 días adicionales
- Total: 365 días máximo, cumple PCI DSS Req 10.5.1
5.5 Media físico decomisionado
Aplica si un droplet, disco físico, o dispositivo sale del CDE.
Procedimiento (MEDIA-DISPOSAL-RUNBOOK.md):
- Backup pre-decomiso (si aún se necesita el dato)
- Wipe con
shred -uvfz -n 3 /dev/sdXo equivalente - Overwrite verificable con patterns aleatorios (mínimo 3 pases)
- Para SSD:
blkdiscard+ verificación de erase conhdparm --security-erase - Destrucción física del disco (drill o triturado industrial) por vendor certificado
- Certificate of Destruction firmado por el vendor
- Archivar CoD en drive legal + evento
fintrix.security.media.destroyeda SIEM
Vendor autorizado en Colombia: [TO_DEFINE] (Iron Mountain o similar)
5.6 Vault snapshots
Retención: 30 días de snapshots diarios + 12 snapshots mensuales (para RTO/RPO).
Cronjob en el cluster Vault:
bash
# Diario 04:00 UTC
vault operator raft snapshot save /var/backups/vault-$(date +%Y%m%d).snap
# Upload a Spaces WORM (immutable)
s3cmd put /var/backups/vault-*.snap s3://fintrix-vault-audit-nyc3/snapshots/
# Purge locales > 7 días
find /var/backups/vault-*.snap -mtime +7 -delete
# Spaces lifecycle purga > 30 días automáticamente6. Verificación de ejecución (evidencia auditable)
Todo purge debe generar evidencia verificable por el QSA. Las evidencias se archivan en:
| Purge | Evidencia primaria | Ubicación | Retención evidencia |
|---|---|---|---|
| SAD sweeper | Vault audit log entries | s3://fintrix-vault-audit-nyc3/audit/ (WORM) | 3 años |
| PAN canceled | Postgres pgAudit + Kafka event | Loki + Kafka topic | 7 años |
| Backup lifecycle | Spaces access logs | s3://fintrix-logs-archive-nyc3/spaces-access/ | 1 año |
| Logs retention | Loki retention metrics | Prometheus loki_ingester_streams_removed_total | 1 año |
| Media disposal | Certificate of Destruction (PDF) | Drive legal + escrow notarial | Vida del sistema |
| Vault snapshots | S3 access log + snapshot list | Spaces WORM | 3 años |
7. Roles y responsabilidades
| Rol | Responsabilidad |
|---|---|
| Security Lead | Aprobar cambios al procedimiento, revisar evidencia mensualmente |
| DPO | Verificar cumplimiento GDPR/Ley 1581 (retención = minimización) |
| DevOps | Mantener cronjobs, monitorear alerts de purge fallido |
| DBA | Ejecutar VACUUM FULL, verificar libertad de dead tuples |
| QSA (externo) | Verificar evidencia trimestralmente y en assessment anual |
8. Métricas y alertas
Dashboard Grafana: PCI Data Retention Compliance
| Métrica | Alerta | Escalación |
|---|---|---|
sad_tokens_older_than_15_min | > 0 durante > 5 min | PagerDuty → Security oncall |
pan_purge_job_last_success_timestamp | > 26 h ago | PagerDuty → DevOps oncall |
backup_older_than_90_days_count | > 0 | Email → DevOps |
logs_older_than_365_days_count | > 0 | Email → DevOps |
vault_snapshot_last_uploaded_timestamp | > 26 h ago | PagerDuty → Security |
9. Runbook para failed purge
Si un purge falla (ej: constraint violation, deadlock, Vault sealed):
- Alerta dispara → oncall recibe
- Oncall revisa logs del cronjob:
kubectl -n pci-cde logs job/{name} - Diagnóstico común:
Vault sealed→ escalar a custodios para unseal ceremonydeadlock detected→ identificar tx en conflicto + retry manualpg connection refused→ verificar salud del Postgres primary
- Ejecutar purge manual con audit trail:bash
kubectl -n pci-cde create job --from=cronjob/pan-purge-canceled-cards \ pan-purge-manual-$(date +%Y%m%d-%H%M) - Documentar incidente en
INCIDENTS/YYYY-MM-DD-purge-failure.md - Post-mortem obligatorio si downtime > 24 h
10. Testing anual
Cada Q4 (previo a la re-certificación):
- Test de purge: insertar 100 registros dummy con
deleted_at = now() - interval '31 days', ejecutar cronjob manual, verificar 0 rows post-ejecución - Test de restauración de backup: restaurar snapshot de hace 30 días a cluster de staging, verificar integridad
- Test de recuperación Vault: unseal ceremony completa desde snapshot de Spaces
- Test de shred: wipe de disco de prueba + intento de recovery con
photorec— debe fallar
Resultados archivados en docs/pci-dss/annual-tests/YYYY/.
11. Aprobaciones
| Rol | Nombre | Firma | Fecha |
|---|---|---|---|
| CTO | [TO_FILL] | ||
| Security Lead | [TO_FILL] | ||
| DPO | [TO_FILL] |
