Files
hcornet 78fb13b0e5
CI / Backend — lint, types, tests (push) Failing after 4m44s
CI / Interface — types et compilation (push) Successful in 10m23s
CI / Construction des images (sans publication) (push) Skipped
first sync
2026-09-12 13:10:16 +02:00

4.1 KiB

Conformité RGPD

Un service public de recherche sur des personnes fait de toi un responsable de traitement. Ce document décrit ce qui est effectivement implémenté — pas des intentions.

Ce qui est conservé, et pourquoi

Donnée Durée Justification
Recherches et résultats RETENTION_DAYS (30 j) permettre à l'utilisateur de relire
Compte jusqu'à suppression accès et quota
Compteurs de quota 13 mois contrôle de la facturation
Journal d'exploitation 90 jours détection d'abus
Demandes d'effacement permanente preuve du traitement (art. 17)

expires_at est posé à la création de chaque recherche. La purge horaire s'appuie dessus, avec un index dédié — sans lui elle balaierait toute la table.

Minimisation : le terme n'est pas conservé en clair

Avec LIMIER_STORE_RAW_IDENTIFIERS=false (recommandé pour une instance ouverte), la base ne contient plus que l'empreinte SHA-256 du terme recherché, salée par un poivre applicatif.

Conséquence concrète : la base seule ne permet plus de reconstituer la liste des personnes recherchées. Une demande d'effacement reste possible — on rehache le terme fourni pour retrouver les enregistrements.

Le poivre est applicatif et non par enregistrement : sinon la même recherche produirait des empreintes différentes, et déduplication comme effacement deviendraient impossibles. Sa place est dans Vault.

Le journal d'exploitation ne porte que les 16 premiers caractères de l'empreinte : corrélation possible, réidentification non.

Le journal n'expose jamais un identifiant

logging.py installe un processeur masquer_identifiants qui retire les clés sensibles (term, email, username, query, token, secret…) de tout évènement, quelle que soit la négligence de l'appelant. Le gestionnaire d'erreurs de validation de FastAPI est également remplacé : par défaut il renvoie la valeur fautive dans la réponse, ce qu'on ne veut pas s'agissant d'identifiants.

Droit d'accès et portabilité (art. 15 et 20)

GET /api/confidentialite/export rend à l'utilisateur connecté l'intégralité de ses données en JSON téléchargeable.

Droit à l'effacement (art. 17)

POST /api/confidentialite/effacement enregistre une demande. Elle n'est pas appliquée immédiatement : sans quoi n'importe qui pourrait supprimer les recherches d'autrui en devinant un terme.

Un administrateur l'applique depuis /api/admin/effacements/{id}/appliquer. Trois effets :

  1. toutes les recherches portant sur cet identifiant sont supprimées, résultats compris (cascade) ;
  2. l'identifiant entre dans la liste d'exclusion — toute recherche ultérieure est refusée avec un HTTP 451 ;
  3. le terme en clair de la demande est effacé, seule l'empreinte subsiste.

Sans le point 2, l'effacement serait sans effet dès la requête suivante.

Information (art. 13)

GET /api/confidentialite publie la politique sous forme lisible par machine autant que par humain, en reflétant la configuration réelle de l'instance (durée de conservation, minimisation active ou non). La page publique s'en sert comme source unique : aucune divergence possible entre ce qui est annoncé et ce qui est appliqué.

Ce qui reste à ta charge

Le code ne peut pas décider à ta place :

  • Base légale. L'intérêt légitime (art. 6-1-f) est retenu par défaut dans la politique publiée. Si tu ouvres au public, cette qualification mérite un examen — ce n'est pas une question technique.
  • Mentions légales. Identité du responsable de traitement, contact, droit de réclamation auprès de la CNIL.
  • Registre des traitements (art. 30) si tu dépasses le seuil.
  • Modération. Le service ne distingue pas un usage légitime d'un harcèlement. La liste d'exclusion, la limitation de débit et le journal sont les outils fournis ; leur usage relève de toi.