Anonymisation et pseudonymisation d’une base ScoDoc¶
Informations techniques
- Cette page est destinée aux personnes qui souhaitent approfondir leur compréhension des traitements de pseudonymisation effectué par ScoDoc. Pour un usage normal, la documentation sur le RGPD est suffisante.
Le RGPD impose de limiter la conservation des données personnelles à la durée
nécessaire aux finalités du traitement. Le script tools/anonymize_db.py permet
de supprimer ou de remplacer certaines données personnelles anciennes tout en
conservant une partie de l’historique scolaire nécessaire aux statistiques et au
suivi des cohortes.
Ce traitement constitue principalement une pseudonymisation, et non une anonymisation irréversible au sens strict du RGPD. L'ensemble des données personnelle est supprimé ou remplacé par des valeurs fictives, mais, par des croisements et recoupements avec d'éventuelles sources de données externes, il peut être théoriquement possible de remonter à des données personnelles. C'est un scénario très peu réaliste en situation réelle, mais la base pseudonymisée doit restée protégée, et surtout ne pas passer en accès public.
Précautions d’utilisation¶
Le script modifie directement une base PostgreSQL ScoDoc. Avant de l’utiliser en production :
- avertir les utilisateurs et arrêter le serveur ScoDoc et les traitements susceptibles de modifier la base ;
- effectuer et vérifier une sauvegarde (bases sql et fichiers annexes ScoDoc) ;
- tester d’abord le traitement avec
--dry-run; - vérifier la date limite et la liste des étudiants et semestres affichée ;
- exécuter le traitement réel ;
- supprimer séparément les fichiers signalés par le script ;
- contrôler la base avant de remettre le service en production.
Il est préférable de tester initialement le traitement sur une copie récente de la base.
Le script s’exécute avec l’utilisateur système scodoc, PostgreSQL étant
démarré :
cd /opt/scodoc
tools/anonymize_db.py [options] NOM_BASE
Toutes les opérations sont exécutées dans une transaction unique. En cas
d’erreur, la transaction n’est pas validée. Les tables temporaires utilisées
sont supprimées au COMMIT ou au ROLLBACK.
Le traitement prend typiquement de l'ordre de 10 secondes à quelques minutes, suivant la taille de votre base et votre serveur. Une transaction importante peut produire du WAL (Write-Ahead Log), conserver des verrous et retarder le nettoyage par PostgreSQL. Il est donc préférable d’exécuter le traitement hors période d’activité.
Rappel: en production, la base de données postgresql est nommée SCODOC.
Sélection des étudiants¶
Par défaut, tous les étudiants sont traités.
Avec une date limite :
tools/anonymize_db.py --before 2020-01-01 NOM_BASE
un étudiant est sélectionné si la date de fin la plus récente de tous les
formsemestres auxquels il a été inscrit est strictement antérieure à celle fournie (1er janvier 2020 dans l'exemple ci-dessus).
MAX(notes_formsemestre.date_fin) < '2020-01-01'
Les étudiants sans aucune inscription sont exclus lorsque --before est
utilisé. Sans --before, tous les étudiants de identite sont sélectionnés.
Note technique: la sélection est enregistrée dans la table temporaire indexée
students_to_anonymize.
Utilisation du script¶
Le script modifie directement une base PostgreSQL ScoDoc. Avant son exécution en production :
- arrêter le serveur ScoDoc et les traitements susceptibles d’écrire dans la base ;
- effectuer et vérifier une sauvegarde PostgreSQL ;
- tester le traitement avec
--dry-run; - vérifier le nombre d’étudiants, les semestres et les fichiers affichés ;
- exécuter le traitement réel avec
--archives-file; - utiliser ensuite un script distinct pour supprimer les fichiers listés ;
- contrôler la base avant de redémarrer ScoDoc.
Il est recommandé de tester préalablement le traitement sur une copie récente de la base.
Syntaxe¶
Le script doit être lancé avec l’utilisateur système scodoc, PostgreSQL étant démarré :
cd /opt/scodoc
tools/anonymize_db.py \
[--users | --all-users | --only-users] \
[--no-students | --only-students] \
[--before YYYY-MM-DD] \
[--archives-file CHEMIN] \
[--dry-run] \
NOM_BASE
Options¶
| Option | Effet |
|---|---|
--before YYYY-MM-DD |
Définit la date limite. Pour les étudiants, leur dernier formsemestre doit se terminer strictement avant cette date. Avec --users, le compte doit être inactif et sa dernière activité antérieure à cette date. |
--users |
Traite aussi les utilisateurs vérifiant active = FALSE et last_seen < before. Nécessite --before. |
--all-users |
Traite aussi tous les utilisateurs, sans filtre sur active ou last_seen. |
--only-users |
Traite tous les utilisateurs sans traiter les étudiants ni la configuration générale. |
--no-students |
Ne traite pas les étudiants. Peut être combiné avec --users --before pour traiter uniquement les anciens comptes inactifs. |
--only-students |
Ne traite que les étudiants, sans utilisateurs ni configuration générale. |
--archives-file CHEMIN |
Après un COMMIT réussi, écrit les archives et photos à supprimer dans le fichier indiqué, à raison d’un chemin relatif par ligne. Nécessite le traitement des étudiants. |
--dry-run |
Exécute toutes les requêtes puis effectue un ROLLBACK. La base reste inchangée et aucun manifeste de fichiers n’est écrit. |
-h, --help |
Affiche l’aide. |
Exemples¶
Simuler le traitement des anciens étudiants :
tools/anonymize_db.py \
--dry-run \
--before 2020-01-01 \
NOM_BASE
Traiter les anciens étudiants et produire le manifeste des fichiers à supprimer :
tools/anonymize_db.py \
--before 2020-01-01 \
--archives-file /tmp/archives-a-supprimer.txt \
NOM_BASE
Traiter les anciens étudiants et les anciens comptes utilisateurs inactifs :
tools/anonymize_db.py \
--users \
--before 2020-01-01 \
--archives-file /tmp/archives-a-supprimer.txt \
NOM_BASE
Ne traiter que les anciens comptes utilisateurs inactifs :
tools/anonymize_db.py \
--no-students \
--users \
--before 2020-01-01 \
NOM_BASE
Traiter tous les étudiants et tous les utilisateurs :
tools/anonymize_db.py \
--all-users \
--archives-file /tmp/archives-a-supprimer.txt \
NOM_BASE
Ne traiter que les étudiants :
tools/anonymize_db.py \
--only-students \
--before 2020-01-01 \
--archives-file /tmp/archives-a-supprimer.txt \
NOM_BASE
Manifeste des fichiers à supprimer¶
Le manifeste contient des chemins relatifs à :
/opt/scodoc-data
Exemple :
archives/docetuds/8/21219
archives/justificatifs/8/21219/2026-03-16-13-56-47
photos/F44/RT_21219.jpg
photos/F44/RT_21219.h90.jpg
Il est trié et ne contient pas de doublons. Les archives et photos ne sont pas
supprimées par anonymize_db.py (mais par un autre script à lancer séparément).
Transaction¶
Les opérations SQL sont exécutées dans une transaction unique. Les tables
temporaires sont supprimées lors du COMMIT ou du ROLLBACK.
Le manifeste est préparé avant la validation, mais n’est publié au chemin
demandé qu’après un COMMIT réussi. En cas d’échec du commit, le manifeste
temporaire est supprimé.
Données étudiantes traitées¶
Identité¶
Dans identite :
| Champ | Traitement |
|---|---|
nom, prenom |
Remplacés par des noms et prénoms fictifs. |
nom_usuel |
Mis à NULL. |
civilite_etat_civil, prenom_etat_civil |
Mis à NULL. |
date_naissance |
Ramenée au 1er janvier de l’année de naissance. |
lieu_naissance, dept_naissance, nationalite |
Remplacés par ?. |
statut |
Mis à NULL. |
boursier |
Mis à FALSE. |
photo_filename |
Mis à NULL. |
code_nip, code_ine, code_pegase_apprenant, scodoc7_id |
Mis à NULL. |
Exemple :
2001-03-15 → 2001-01-01
L’année de naissance est conservée pour permettre des statistiques par âge ou cohorte.
Les fichiers physiques des photos correspondant à photo_filename sont ajoutés
au manifeste pour suppression séparée.
Adresses et coordonnées¶
Dans adresse :
emaildevientano@nyme.fr;emailperso,description, adresse postale, ville, pays, téléphones et fax sont mis àNULL.
Admission¶
Dans admissions :
- le nom du lycée est remplacé ;
- le rapporteur, la localisation et le code du lycée sont supprimés ;
- le type d’admission et les informations de bourse antérieure sont supprimés ;
- les groupes et classements APB sont supprimés.
Les informations scolaires générales non explicitement listées, comme le type de baccalauréat, peuvent rester disponibles pour les statistiques.
Suivi et annotations¶
Dans itemsuivi, situation est mis à NULL.
Les associations entre les éléments de suivi et leurs tags sont supprimées dans
itemsuivi_tags_assoc. Les définitions des tags dans itemsuivi_tags ne sont
pas supprimées.
Dans etud_annotations, les commentaires sont mis à NULL.
Assiduités et absences¶
Les champs suivants sont supprimés :
| Table | Champs |
|---|---|
billet_absence |
description |
assiduites |
description, external_data |
justificatifs |
raison, external_data, fichier |
Le champ fichier contient le nom d’une archive de justificatifs. Avant de le
mettre à NULL, le script mémorise et affiche les répertoires physiques à
supprimer séparément :
archives/justificatifs/8/21219/2026-03-16-13-56-47
Ces chemins sont relatifs à :
/opt/scodoc-data
Le script SQL ne supprime pas lui-même les fichiers présents sur le système de
fichiers: il faut ensuite lancer un second script charger d'effacer tous les
fichiers annexes identifiés: tools/delete_anonymized_archives.sh (c'est
indiqué en clair à l'issue du script de anonymize_db.py).
Notes et appréciations¶
Les textes libres suivants sont mis à NULL :
| Table | Champ |
|---|---|
notes_appreciations |
comment |
notes_notes |
comment |
notes_notes_log |
comment |
Les valeurs des notes et leur historique sont conservés.
Photos¶
Les photos des étudiants anciens sont déréférencées et lister comme à effacer pour le script suivant.
Journaux¶
Les lignes de scolog associées aux étudiants sélectionnés sont supprimées
intégralement.
Demandes d’inscription¶
Lorsque --before est fourni, les lignes de form_semestre_demande_inscription
dont :
date_demande < DATE_LIMITE
sont supprimées intégralement.
Cette suppression concerne notamment les noms, coordonnées, NIP, INE, motivations et pièces jointes enregistrés dans ces demandes.
Sans --before, aucune demande d’inscription n’est supprimée.
Configuration générale¶
Sauf avec --only-students ou --only-users, les valeurs suivantes de
scodoc_site_config sont mises à NULL :
rgpd_coordonnees_dpo;pegase_password.
Utilisateurs¶
Les utilisateurs ne sont traités qu’avec --users ou --only-users.
Pour tous les comptes :
- les mots de passe et anciens mots de passe sont invalidés ;
- les jetons sont supprimés ;
- les dates de création et d’expiration sont remplacées ;
- les adresses électroniques sont remplacées.
Pour tous les comptes sauf admin :
- nom et prénom sont remplacés ;
- le nom d’utilisateur est remplacé par un identifiant fictif unique ;
- les références textuelles au nom d’utilisateur sont mises à jour dans plusieurs tables de journaux et d’historique.
Bilan affiché¶
À la fin du traitement, le script affiche :
- le nombre d’étudiants traités ;
- la liste des formsemestres auxquels ces étudiants ont été inscrits ;
- le nombre d’étudiants concernés pour chaque formsemestre ;
- la liste des archives et photos à supprimer.
En mode --dry-run, ces informations décrivent ce qui aurait été modifié.
Limites et pseudonymisation¶
Le traitement conserve volontairement un historique scolaire détaillé afin de permettre notamment :
- le suivi longitudinal des cohortes ;
- le calcul des taux de réussite ;
- l’analyse des parcours et réorientations ;
- les statistiques sur les notes, validations et décisions de jury ;
- les statistiques d’assiduité ;
- les analyses par année de naissance ou formation.
Pour permettre ces usages, le script conserve notamment :
- l’
etudidinterne ; - les inscriptions aux formsemestres ;
- les notes et leurs historiques ;
- les validations et décisions de jury ;
- les dates et événements scolaires ;
- les groupes, parcours et formations ;
- certaines données d’admission ;
- les stages, apprentissages et badges éventuels.
Ces informations peuvent permettre d’individualiser un parcours. Le croisement d’une formation rare, de dates, d’un établissement d’origine, d’un stage ou d’une trajectoire particulière peut parfois conduire à une réidentification.
La base résultante doit donc être considérée comme pseudonymisée, sauf analyse complémentaire démontrant que toute réidentification est raisonnablement impossible.
Elle doit continuer à bénéficier de mesures de protection adaptées :
- accès limité aux personnes autorisées ;
- finalité statistique définie ;
- journalisation des accès ;
- absence de diffusion publique de données individuelles ;
- agrégation des résultats avant publication ;
- vigilance pour les cohortes ou sous-groupes de faible effectif ;
- durée de conservation documentée ;
- réévaluation périodique du risque de réidentification.
Le script ne remplace pas une politique RGPD complète : registre des traitements, définition des durées de conservation, base légale, information des personnes, gestion des droits et analyse des risques restent nécessaires.
Voir aussi