Cumplimiento Normativo: Cifrado PII & Derechos ARCO
La arquitectura de Mañuti está certificada bajo los principios de Privacidad desde el Diseño y por Defecto (Privacy by Design and by Default) estipulados por ISO/IEC 27701, GDPR y legislaciones de protección de datos personales (LFPDPPP).
1. Cifrado Selectivo de Datos en Reposo (Encryption at Rest)
Para mitigar el impacto de filtraciones en la capa de persistencia, Mañuti utiliza el patrón EAV (Entity-Attribute-Value) sobre la tabla configuracion_usuarios, permitiendo que los datos de identificación personal (PII) residan cifrados con AES-256-CBC.
flowchart LR
subgraph App ["[Capa Aplicación]"]
SET["$user->setConfig('celular', '555-1234')"]
GET["$user->getConfig('celular')"]
end
subgraph DB ["[Base de Datos MariaDB]"]
DATA["valor: 'eyJpdiI6IkV2YSt4...'<br/>(Texto Cifrado)"]
end
SET --> DATA
DATA -->|"valor descifrado en memoria al vuelo"| GET
Guardia de Integridad Criptográfica (validateEncryptionIntegrity)
Para evitar la corrupción de datos, el sistema prohíbe modificaciones inconsistentes en la lista de campos encriptados (security_pii_fields):
- Intento de Desactivación: Si se intenta remover un campo de la lista encriptada, el sistema audita la base de datos. Si existe al menos un registro previo, bloquea la acción para evitar que datos cifrados sean leídos como texto plano corrupto.
- Intento de Activación: Si se intenta agregar un campo existente con registros previos en texto plano, bloquea la acción para evitar excepciones
Payload invalidal intentar descifrar cadenas no cifradas.
2. Derecho a la Portabilidad (Exportación Asíncrona ARCO)
La exportación masiva de datos no se ejecuta de forma síncrona para evitar saturación de memoria RAM y bloqueos por timeout en servidores web.
flowchart TD
REQ["[Usuario solicita datos]"]
VAL["Valida Password (Sudo Mode)"]
JOB["[Dispatch: ExportUserDataJob]"]
SQL["[Extrae SQL + EAV (Descifrado)]"]
MONGO["[Cursor MongoDB: Chunk 1000]"]
JSON["[Compila JSON en Storage Privado]"]
URL["[Genera URL Temporal Firmada (24 hrs)]"]
MAIL["[Envía Correo al Titular vía SMTP]"]
REQ --> VAL
VAL --> JOB
JOB --> SQL
JOB --> MONGO
SQL --> JSON
MONGO --> JSON
JSON --> URL
URL --> MAIL
Protocolo de Seguridad en la Descarga
El archivo generado no se expone públicamente:
- Se almacena en el disco privado
storage/app/private/exports/. - El acceso está protegido por una URL Temporal Firmada Criptográficamente mediante el middleware
signed:$downloadUrl = URL::temporarySignedRoute( 'profile.export_download', now()->addHours(24), ['filename' => $filename] );
3. Derecho al Olvido (Anonimización Irreversible)
La supresión de datos no puede realizarse mediante un DELETE físico tradicional, ya que destruiría la integridad referencial de los reportes históricos y la bitácora de auditoría.
Mañuti resuelve el derecho de cancelación mediante Ofuscación Criptográfica Irreversible:
php artisan privacy:anonymize {user_id}
flowchart LR
subgraph Original ["[Registro Original]"]
O_ID["id: 5"]
O_USER["usuario: 'juan.perez'"]
O_MAIL["correo: '[email protected]'"]
O_PASS["password: '$2y$12$eX9...' (Bcrypt real)"]
O_STAT["cat_status: 1 (Activo)"]
O_CONF["configuracion_usuarios: [Tel, Dir, RFC]"]
O_LOG["login: [Sesiones activas]"]
end
subgraph Anonimizado ["[Registro Anonimizado]"]
A_ID["id: 5 (Se preserva integridad)"]
A_USER["usuario: 'deleted_5'"]
A_MAIL["correo: '[email protected]'"]
A_PASS["password: '$2y$12$r4N...' (Hash aleatorio inutilizado)"]
A_STAT["cat_status: 3 (Suspendido)"]
A_CONF["Registros eliminados físicamente"]
A_LOG["open = 0 (Expulsión forzosa)"]
end
O_ID ~~~ A_ID
O_USER --> A_USER
O_MAIL --> A_MAIL
O_PASS --> A_PASS
O_STAT --> A_STAT
O_CONF --> A_CONF
O_LOG --> A_LOG
Al concluir el proceso, el titular de los datos deja de ser identificable directa o indirectamente, cumpliendo la definición legal de disociación y anonimización de datos personales.