Contexte : pourquoi la LGPD pèse davantage dans le e-learning
Les plateformes e-learning collectent plus de données sensibles que le e-commerce ou les réseaux sociaux :
- Données éducatives (LGPD Art. 11 — donnée personnelle sensible lorsqu'elle révèle l'état de santé/bien-être)
- Données comportementales riches — temps passé sur chaque cours, habitudes d'étude, difficultés, anxiété pré-examen
- Données de mineurs — primaire + collège + lycée = ~80 % du marché K-12 brésilien
- Données des parents/représentants légaux (liaison GuardianLink)
- Données biométriques lorsqu'il y a du proctoring via webcam (Studeia n'en dispose pas nativement, mais LTI vers Examity/ProctorU oui)
L'ANPD a déjà mené des contrôles auprès d'edtechs brésiliennes en 2024-2025. Les amendes de R$50 millions (2 % du chiffre d'affaires brut, plafonnées à R$50 M) sont bien réelles.
8 axes obligatoires
1. DPO (Data Protection Officer) — Art. 41
L'entreprise doit désigner une personne physique comme responsable du traitement des données. Ses responsabilités :
- Recevoir les réclamations et communications des personnes concernées
- Recevoir les communications de l'ANPD
- Orienter les collaborateurs sur la LGPD
- Exécuter les plans de mise en conformité
Options :
| Modèle | Coût | Adapté pour |
|---|---|---|
| DPO interne (salarié) | R$8 000-20 000/mois salaire | Entreprises >100 employés |
| DPO externe (cabinet conseil spécialisé) | R$2 000-8 000/mois | Entreprises 10-100 employés |
| DPO virtuel (cabinet d'avocats) | R$1 000-3 000/mois | Micro-entreprises |
À publier : nom + e-mail du DPO dans la politique de confidentialité.
2. Consentement parental réel pour les mineurs — Art. 14
LGPD Art. 14 §1 : « Le traitement des données personnelles d'enfants devra être réalisé avec le consentement spécifique et mis en évidence donné par au moins l'un des parents ou par le représentant légal. »
Les plateformes qui ignorent cette règle s'exposent à des sanctions :
- ❌ Anti-modèle : case à cocher « J'ai plus de 13 ans » sans vérification
- ❌ Anti-modèle : champ « E-mail du père » sans vérifier qu'il est réel
- ✅ Modèle Studeia : l'apprenant s'inscrit → statut
pending_parental_consent→ e-mail/SMS au parent → le parent clique sur le lien + répond à la vérification SMS (anti-fraude) → statutactive
En outre : le parent choisit le niveau d'accès par enfant via ProgressSharingConfig. Apprenant de moins de 13 ans : le parent a un accès TOTAL par défaut. 13-17 ans : le parent configure.
Implémentation concrète :
// L'apprenant s'inscrit
if (user.age < 18) {
user.isMinor = true;
user.status = "pending_parental_consent";
// GuardianLink créé mais inactif
await prisma.guardianLink.create({
data: {
childId: user.id,
parentEmail: parentEmail,
parentPhone: parentPhone,
verified: false,
verificationToken: generateSecureToken(),
}
});
// E-mail + SMS au parent avec lien de vérification
await sendVerification({ ... });
}
L'apprenant NE PEUT PAS accéder au contenu tant que le statut != "active". Aucune faille.
3. Export de données — Art. 18 IV
La personne concernée peut demander une copie de TOUTES ses données personnelles que vous traitez à son sujet. Dans un format structuré et lisible.
Studeia : GET /api/user/data-export retourne un JSON avec :
{
"user": { id, email, name, role, ... },
"enrollments": [ ... ],
"lessonCompletions": [ ... ],
"quizAttempts": [ ... ],
"chatSessions": [ ... ], // historique du chat avec le tuteur IA
"messages": [ ... ], // messages directs + forum
"badges": [ ... ],
"gamificationProfile": { ... },
"aiSupervisorIncidents": [ ... ], // le cas échéant
"consentRecords": [ ... ]
}
Limite de débit : 1 export par 24h par utilisateur (anti-abus). Clé Redis data-export-cooldown:{userId} TTL 86400.
Mis à disposition dans un délai de 15 jours à compter de la demande (la LGPD ne définit pas de délai précis, mais 15 jours est le standard ANPD).
4. Suppression de compte — Art. 18 VI
La personne concernée peut demander l'élimination de ses données personnelles. Mais il y a une nuance :
- PII (données personnelles identifiables) — DOIVENT être supprimées/anonymisées
- Données académiques historiques — peuvent être CONSERVÉES pour une finalité légitime (conservation fiscale, preuve de formation de l'apprenant, défense en cas de litige)
Studeia procède ainsi :
// DELETE /api/user/account
await prisma.$transaction(async (tx) => {
// 1. Anonymise les PII
await tx.user.update({
where: { id: userId },
data: {
email: `deleted-${userId}@anonymous.studeia.com`,
name: "Utilisateur supprimé",
phone: null,
address: null,
avatarUrl: null,
cpf: null, // CPF également
status: "deleted",
deletedAt: new Date(),
}
});
// 2. Supprime les données conversationnelles
await tx.chatSession.deleteMany({ where: { userId } });
await tx.directMessage.deleteMany({ where: { senderId: userId } });
await tx.directMessage.updateMany({ where: { recipientId: userId }, data: { recipientId: ANONYMIZED } });
// 3. Anonymise les données académiques (conserve l'historique mais sans PII)
// LessonCompletion, QuizAttempt, Grade référencent par User.id (conservé)
// Comme User.email et User.name ont été anonymisés, les données académiques deviennent « anonymes »
// 4. Anonymise les incidents de sécurité (conserve la sévérité + catégorie pour la conformité)
await tx.aiSupervisorIncident.updateMany({
where: { userId },
data: {
messagesSnapshot: [],
supervisorReasoning: null,
appealText: null,
}
});
// 5. Un cron purge automatiquement les données académiques de plus de 5 ans
});
5 ans = conservation fiscale compatible LGPD (Lei 10.406/2002 + notre CR Art. 7º XXIX).
5. DPA avec les tiers — divulgation obligatoire
Le tenant DOIT lister dans sa politique de confidentialité TOUS les sous-traitants de données tiers.
Studeia transmet à chaque tenant la liste suivante :
- Anthropic (Claude) — traite les prompts + réponses. DPA RGPD/LGPD. Siège USA. Rétention des données : 30 jours.
- OpenAI (GPT fallback) — idem. Siège USA. Rétention des données : 30 jours.
- Voyage AI (embeddings principal) — traite le texte pour l'embedding. Siège USA. Rétention des données : 30 jours.
- Stripe (paiements USD) — PCI-DSS Level 1. Siège USA. Rétention : 7 ans (fiscal).
- Asaas (paiements BR PIX/boleto) — siège Brésil. Rétention : 7 ans.
- Supabase (base de données + auth + stockage) — siège USA. Région : us-east-1 (par défaut) ou sa-east-1 en option.
- Sentry (observabilité) — Session replay avec maskAllText:true + blockAllMedia:true (conforme LGPD).
- PostHog (analytics) — anonymisation IP activée. Pas de suivi PII.
- Resend / SendGrid (e-mail) — siège USA. Rétention : 30 jours.
Le tenant copie cette liste dans sa politique de confidentialité. La divulgation est ainsi couverte.
6. Isolation réelle des tenants — RLS + filtre obligatoire
LGPD Art. 6 V : les données personnelles doivent être traitées avec une sécurité appropriée.
LMS multi-tenant = les données de l'École A ne doivent JAMAIS apparaître dans une requête de l'École B. Studeia l'implémente en 3 couches :
- Filtre obligatoire dans les requêtes Prisma : tout appel
prisma.X.findMany()dans le code applicatif DOIT inclurewhere: { tenantId }. Règle critique n°6 du projet. - RLS Supabase : policy automatique sur toutes les tables concernées :
CREATE POLICY tenant_isolation_courses ON courses FOR SELECT USING (tenant_id = current_setting('app.current_tenant_id')::uuid); - RAG tenantOnlyMode : la récupération ne cite jamais de matériel provenant d'une autre institution.
7. Journal d'audit immuable
LGPD Art. 37 + ANPD Resolução CD/ANPD nº 4/2023 : enregistrement des opérations de traitement.
Studeia : modèle AdminAuditLog avec :
model AdminAuditLog {
id String @id @default(uuid())
actorId String // qui a effectué l'action
action AdminAuditAction
targetType String // "user", "tenant", "course", etc
targetId String?
metadata Json?
ip String?
userAgent String?
createdAt DateTime @default(now())
}
Actions auditées (15+ types) :
- impersonate.start / stop
- tenant.create / plan.change / config.update / delete
- user.role.change / tenant.link
- ai_supervisor.* (transitions d'incidents, mises à jour de prompts, etc.)
- subscription.admin_update
- payment.manual.record
Immuable : append-only. Aucun endpoint de suppression (intentionnel).
8. Plan de réponse aux incidents
LGPD Art. 48 : un incident de sécurité susceptible d'entraîner un risque/préjudice significatif = communication à l'ANPD dans un délai raisonnable (interprétation : 24h).
Studeia : runbook dans docs/runbooks/incident-response.md avec table SEV :
| SEV | Déclencheur | Action principale | SLA notif |
|---|---|---|---|
| SEV1 | Fuite PII > 100 utilisateurs | Signalement ANPD + clients + page statut | <2h |
| SEV2 | Interruption > 30min OU PII < 100 utilisateurs | Clients + page statut | <4h |
| SEV3 | Dégradation des performances | Page statut | <12h |
| SEV4 | Bug fonctionnel sans PII | Backlog priorisé | N/A |
En outre : postmortem public (anonymisé) dans docs/incidents/ pour SEV1/SEV2.
Ajouts spécifiques pour Studeia
Journalisation des prompts LLM
Avant d'envoyer un prompt à Anthropic/OpenAI :
// Masquer les PII connues
function redactPIIBeforeLLM(prompt: string, user: User): string {
return prompt
.replace(new RegExp(user.email, 'gi'), '[EMAIL_REDACTED]')
.replace(new RegExp(user.cpf ?? '', 'g'), '[CPF_REDACTED]')
.replace(new RegExp(user.phone ?? '', 'g'), '[PHONE_REDACTED]');
}
Avant de journaliser le prompt dans AiUsageLog :
function redactPIIBeforeLog(prompt: string): string {
// Patterns génériques
return prompt
.replace(/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g, '[CPF]')
.replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[EMAIL]')
.replace(/\b\d{4,5}-?\d{4}\b/g, '[PHONE]');
}
AiUsageLog.prompt stocke la version masquée. Les coûts et l'analytics fonctionnent sans exposer de PII.
Tuteur IA + historique de chat
L'apprenant accède à « Mes conversations » et consulte son historique. Les parents disposant d'une permission y ont également accès (en fonction de ProgressSharingConfig.viewChatHistory).
Mais : l'ANPD peut en faire la demande par voie judiciaire. Réponse :
- Studeia conserve l'historique de chat pendant 1 an (rétention par défaut, configurable par tenant)
- Après 1 an : le cron
/api/cron/chat-cleanupanonymise (conserve le nombre de tours pour l'analytics, supprime le texte) - Sur demande judiciaire : export JSON avec le contenu demandé
- Journalisation de l'accès dans AdminAuditLog (action :
data.judicial_request)
Ce qu'il ne faut JAMAIS faire
❌ Collecter plus de données que nécessaire (principe de minimisation Art. 6 III) ❌ Partager des données d'apprenants à des fins marketing (même « en interne ») ❌ Entraîner un modèle d'IA avec des données d'apprenants sans consentement explicite ❌ Vendre des données comportementales d'étude à des tiers ❌ Utiliser des données de mineurs pour de la publicité ciblée (interdit par la loi) ❌ Conserver des données sans finalité claire (Art. 16) ❌ Utiliser un tuteur IA sans informer que c'est une IA (transparence, Art. 6 VI)
Avatar IA temps réel (disponible — opt-in)
Studeia propose déjà un avatar parlant en temps réel avec vidéo/voix (HeyGen LiveAvatar / D-ID, BYO key du fournisseur) en tant que fonctionnalité opt-in par cours. Considérations LGPD lors de l'activation :
- Consentement supplémentaire explicite recommandé (utilisation d'une « image virtuelle de tuteur »)
- Divulgation que c'est une IA (pied de page « Tuteur virtuel généré par IA »)
- Ne pas utiliser la voix réelle d'une personne publique sans licence (risque deepfake)
- La clé API principale du fournisseur reste côté serveur et n'est jamais transmise au client ; seuls des tokens de session éphémères parviennent au navigateur. Voir Avatar & TTS.