## 13. Conformité RGPD ### 13.1 Gestion du consentement **Décision** : Tarteaucitron.js + PostgreSQL backend **Implémentation web** : - ✅ Tarteaucitron.js (opensource, self-hosted) - ✅ Banner RGPD français, customisable - ✅ Granularité : fonctionnel / analytique / marketing **Implémentation backend** : - Table `user_consents` avec versioning - Champs : user_id, consent_type, version, accepted, timestamp - Historique complet conservé (preuve légale) **Consentements requis** : - **Géolocalisation précise** : obligatoire (banner + permission OS) - **Analytics** : optionnel (Matomo) - **Notifications push** : optionnel (permission OS) **Justification** : - Opensource, 0€, conformité RGPD garantie - Historique backend = preuve légale en cas de contrôle - Granularité conforme recommandations CNIL --- ### 13.2 Anonymisation des données GPS **Décision** : Geohash après 24h **Processus** : 1. Données précises conservées **24h** (recommandation personnalisée) 2. Après 24h : conversion en geohash précision 5 (~5km²) 3. Coordonnées originales supprimées définitivement **Implémentation PostGIS** : ```sql -- Job quotidien UPDATE location_history SET location = ST_SetSRID(ST_GeomFromGeoHash(ST_GeoHash(location::geography, 5)), 4326)::geography, anonymized = true WHERE created_at < NOW() - INTERVAL '24 hours' AND anonymized = false; ``` **Exceptions** : - ✅ Historique personnel visible (liste trajets) : conservation intégrale tant que compte actif - ❌ Analytics globales : uniquement geohash anonyme **Justification** : - Vraie anonymisation RGPD (CNIL compliant) - Permet analytics agrégées (heatmaps trafic) - PostGIS natif, 0€ --- ### 13.3 Export des données (portabilité) **Décision** : JSON + HTML + ZIP, génération asynchrone **Contenu de l'export** : ``` export-roadwave-[user_id]-[date].zip ├── export.json # Machine-readable ├── index.html # Human-readable (stylé) ├── audio/ │ ├── content-123.opus │ ├── content-456.opus │ └── ... └── README.txt # Instructions ``` **Données exportées** : - Profil utilisateur (email, pseudo, date inscription, bio) - Historique d'écoute (titres, dates, durées) - Contenus créés (audio + métadonnées) - Abonnements et likes - Centres d'intérêt (jauges) - Historique consentements **Processus** : 1. Demande via paramètres compte 2. Génération asynchrone (worker background) 3. Email avec lien download (expire **7 jours**) 4. Délai : **48h maximum** (conformité RGPD) **Limite** : - Maximum **1 export/mois** (anti-abus) **Justification** : - Conformité article 20 RGPD (portabilité) - Double format (human + machine) - Worker asynchrone évite timeout --- ### 13.4 Suppression du compte **Décision** : Grace period 30j + anonymisation contenus **Processus** : 1. Utilisateur clique "Supprimer mon compte" 2. Compte désactivé immédiatement (login impossible) 3. Contenus cachés pendant 30 jours (non diffusés) 4. Email confirmation + lien annulation (valide 30j) 5. Après 30j sans annulation : suppression effective **Suppression effective** : - ✅ Compte utilisateur supprimé (données personnelles) - ✅ Historique d'écoute supprimé - ✅ GPS historique supprimé - ✅ Sessions et tokens révoqués - ⚠️ Contenus créés **anonymisés** (créateur = "Utilisateur supprimé") - ⚠️ Likes et abonnements supprimés (mais compteurs préservés) **Contenus conservés anonymement** : - Audio files (CDN) - Métadonnées (titre, description, tags, géolocalisation) - Statistiques d'écoute **Justification** : - Grace period évite suppressions impulsives - Anonymisation contenus = intérêt légitime communauté - Conforme RGPD si créateur = donnée supprimée --- ### 13.5 Mode dégradé (sans GPS précis) **Décision** : GeoIP par défaut, GPS optionnel **Niveaux de précision** : | Niveau | Technologie | Contenus accessibles | Consentement | |--------|-------------|---------------------|--------------| | **Pays** | Aucune géoloc | Contenus nationaux uniquement | ❌ Non requis | | **Ville** | GeoIP (IP2Location) | Contenus régionaux/ville | ❌ Non requis | | **Précis** | GPS | Tous contenus (hyperlocaux inclus) | ✅ Requis | **Implémentation** : - Démarrage app : GeoIP automatique (IP → ville) - Banner in-app : "Activez la géolocalisation pour découvrir du contenu près de chez vous" - Upgrade volontaire vers GPS **API GeoIP** : - IP2Location Lite (gratuit, self-hosted, voir [ADR-021](../adr/021-geolocalisation-ip.md)) - Update DB mensuelle automatique - Précision ~80% au niveau ville **Justification** : - RGPD : pas de consentement requis pour GeoIP (pas de donnée personnelle) - UX dégradée acceptable (contenus disponibles) - Progressive disclosure (upgrade optionnel) --- ### 13.6 Durée de conservation des données **Décision** : 5 ans inactivité → purge automatique **Règles** : | Type de compte | Seuil inactivité | Action | |----------------|------------------|--------| | **Auditeur uniquement** | 5 ans sans connexion | Suppression automatique | | **Créateur avec contenus actifs** | Jamais (tant qu'écoutes) | Conservation indéfinie | | **Créateur inactif** | 5 ans sans connexion + 2 ans sans écoute | Suppression automatique | **Notifications avant suppression** : - Email + push : **90 jours** avant - Email + push : **30 jours** avant - Email + push : **7 jours** avant - Toute connexion = reset compteur inactivité **Contenu conservé** : - Contenus créés par comptes supprimés (anonymisés) : conservation indéfinie **Justification** : - Conformité principe minimisation RGPD - 5 ans = équilibre raisonnable (standard industrie) - Exception créateurs actifs = intérêt légitime plateforme --- ### 13.7 Cookies et trackers web **Décision** : Matomo self-hosted, zéro cookie tiers **Cookies utilisés** : | Cookie | Type | Durée | Finalité | Consentement | |--------|------|-------|----------|--------------| | `session` | Technique | 30j | Authentification | ❌ Non requis | | `refresh_token` | Technique | 30j | Session persistante | ❌ Non requis | | `_pk_id` | Analytique | 13 mois | Matomo (IP anonyme) | ✅ Requis | **Analytics : Matomo self-hosted** : - Hébergé sur nos serveurs (Docker) - IP anonymisées automatiquement (2 derniers octets) - Pas de cookie si consentement refusé - Alternative : Plausible (SaaS EU, 9€/mois) **Trackers interdits** : - ❌ Google Analytics - ❌ Facebook Pixel - ❌ Hotjar, Mixpanel, etc. **Justification** : - Souveraineté données (pas de transfert US) - Conformité RGPD max (CNIL compatible) - Matomo = opensource, 0€ infra --- ### 13.8 Registre des traitements **Décision** : Document Markdown versionné Git (MVP) **Emplacement** : - `docs/rgpd/registre-traitements.md` - Versionné Git (historique modifications) **Contenu obligatoire par traitement** : - Nom et finalité du traitement - Catégories de données collectées - Base légale (consentement / contrat / intérêt légitime) - Durée de conservation - Destinataires (sous-traitants, CDN, etc.) - Transferts hors UE (aucun prévu) **Responsable** : - DPO / Fondateur - Review trimestrielle obligatoire - Update immédiate si nouveau traitement **Migration future** : - Si > 100K utilisateurs : interface admin PostgreSQL **Justification** : - Obligation RGPD Article 30 - Markdown = simple, versionné, auditable - 0€ --- ### 13.9 Notification violations de données (breach) **Décision** : Monitoring + alertes + runbook **Détection automatique** : | Événement | Outil | Alerte | |-----------|-------|--------| | Erreurs backend critiques | Sentry | Discord/Slack immédiat | | Pic requêtes anormal | Grafana | Email équipe | | Accès non autorisé DB | PostgreSQL logs | SMS fondateur | | Authentification suspecte | Zitadel alerts | Email équipe | **Procédure breach** : - Runbook : `docs/rgpd/procedure-breach.md` - Checklist 72h CNIL : 1. H+0 : Détection et confinement 2. H+24 : Évaluation gravité (données concernées, utilisateurs impactés) 3. H+48 : Notification CNIL si risque pour utilisateurs 4. H+72 : Notification utilisateurs si risque élevé **Contact CNIL** : - Email pré-rédigé (template) - Formulaire en ligne (account CNIL créé) **Justification** : - Obligation RGPD Article 33 (notification 72h) - Monitoring proactif évite découverte tardive - Sentry gratuit < 5K events/mois --- ### 13.10 DPO (Délégué à la Protection des Données) **Décision** : Fondateur = DPO temporaire (MVP) **Raison légale** : - Non obligatoire si : - < 250 employés - Pas de traitement à grande échelle de données sensibles - RoadWave : données localisation = sensible MAIS échelle MVP **Formation** : - CNIL : formation gratuite en ligne (4h) - Certification CNIL "Atelier RGPD" (gratuit) **Contact** : - Email : dpo@roadwave.fr - Publié dans CGU et mentions légales - Délai réponse : **1 mois** (RGPD) **Migration future** : - Si > 100K utilisateurs : DPO externe mutualisé (~200€/mois) - Ou recrutement DPO interne si > 10 employés **Justification** : - Conforme RGPD (non obligatoire en phase MVP) - 0€, contrôle total - Bonne pratique : avoir un contact identifié --- ## Récapitulatif Section 13 | Mesure | Implémentation | Coût | |--------|----------------|------| | **Consentement** | Tarteaucitron.js + PostgreSQL | 0€ | | **Anonymisation GPS** | Geohash PostGIS (24h) | 0€ | | **Export données** | JSON+HTML+ZIP asynchrone | 0€ | | **Suppression compte** | Grace period 30j + anonymisation | 0€ | | **Mode dégradé** | GeoIP IP2Location + GPS optionnel | 0€ | | **Conservation** | Purge auto 5 ans inactivité | 0€ | | **Analytics** | Matomo self-hosted | ~5€/mois | | **Registre traitements** | Markdown Git | 0€ | | **Breach detection** | Sentry + Grafana + runbook | 0€ | | **DPO** | Fondateur formé CNIL | 0€ | **Coût total RGPD : ~5€/mois** --- ## Points d'attention pour Gherkin - Tester consentement géolocalisation (accept/refuse → contenus différents) - Tester anonymisation GPS après 24h (job cron) - Tester export données (génération complète + vérification contenu) - Tester grace period suppression (annulation possible) - Tester mode GeoIP (ville détectée correctement) - Tester purge automatique (5 ans inactivité) - Tester notifications avant purge (90j/30j/7j)