RGPD et Rails : suppression douce, historique des versions et droit à l'effacement

« Supprimer » n'a pas le même sens pour un développeur Rails et pour le RGPD. Une suppression douce cache une ligne sans l'effacer ; une gem d'historique garde une copie de chaque version, y compris de l'enregistrement détruit. Ces outils sont utiles, mais ils obligent à prévoir une vraie purge. Voici ce que demandent les textes, et comment l'organiser.
Ce que demandent le RGPD et la CNIL
Trois règles du RGPD touchent directement ces gems. L'article 5 pose le principe de limitation de la conservation : les données qui permettent d'identifier une personne ne sont conservées que le temps nécessaire aux finalités du traitement. L'article 17 donne à chacun un droit à l'effacement dans plusieurs situations, par exemple lorsque les données ne sont plus nécessaires ou que la personne retire son consentement. Et l'article 12 fixe le délai de réponse : dans les meilleurs délais et au plus tard dans un mois à compter de la demande, délai qui peut être prolongé de deux mois pour les demandes complexes ou nombreuses, à condition d'en informer la personne. Les articles 12 et 17 figurent au chapitre III du règlement, publié sur le site de la CNIL.
Pour les équipes de développement, la CNIL traduit ces règles en pratique dans son guide RGPD du développeur. Sur l'effacement, elle conseille de prévoir une fonctionnalité qui efface toutes les données relatives à une personne, de notifier automatiquement les sous-traitants, et de traiter aussi les sauvegardes, ou du moins d'empêcher la restauration des données effacées. Sur la conservation, sa fiche « Gérer la durée de conservation des données » distingue trois temps : la base active, utilisée pour l'objectif du traitement ; l'archivage intermédiaire, pour des données qui ne servent plus mais doivent être gardées (contentieux possible, obligation légale), séparé de la base active physiquement ou logiquement et réservé à des personnes habilitées ; et, plus rarement, l'archivage définitif.
La suppression douce n'est pas un effacement
Les gems de suppression douce remplacent la destruction d'une ligne par le remplissage d'une colonne de date. Avec Discard, Paranoia ou acts_as_paranoid (comparés dans notre guide en anglais), l'enregistrement reste dans la table, avec toutes ses colonnes.
- Discard (version 2.0.0) ajoute une colonne
discarded_at, les portéeskeptetdiscarded, et ne modifie pas les requêtes par défaut : c'est au code de filtrer. - Paranoia (version 3.1.0) ajoute une portée par défaut qui masque les lignes marquées et redéfinit
destroy. Son propre README la déconseille pour les nouveaux projets. Pour une suppression réelle, il faut appelerreally_destroy!, qui détruit aussi les enregistrements liés pardependent: :destroy.
Au regard des trois temps de la CNIL, une ligne « supprimée » de cette façon est toujours en base active : elle est lisible par tout le code de l'application et par toute personne qui a accès à la base. Elle ne peut tenir lieu d'archivage intermédiaire que si l'accès en est réellement restreint, ce qu'une simple portée Active Record ne garantit pas. Et elle ne répond pas à une demande d'effacement.
La suppression douce reste légitime pour d'autres besoins : annuler une erreur, garder le lien avec des factures, conserver des statistiques. Il faut alors décider combien de temps une ligne peut rester marquée avant d'être détruite, et écrire cette durée quelque part.
L'historique des versions garde une copie de tout
Les gems d'historique, présentées dans notre guide anglais sur les journaux d'audit, posent la même question en plus aigu. PaperTrail (version 17.0.0) enregistre, à chaque mise à jour et à chaque destruction, l'état de l'objet avant la modification dans la colonne object de la table versions. Conséquence directe : après un destroy, l'enregistrement a disparu de sa table, mais sa dernière version complète est toujours dans versions. C'est d'ailleurs ce qui permet de le restaurer.
PaperTrail fournit plusieurs moyens d'en limiter la portée :
has_paper_trail skip: [...]: les attributs listés ne sont jamais copiés dans l'historique. C'est l'option à utiliser pour les champs sensibles ;has_paper_trail ignore: [...]ouonly: [...]: choisir les modifications qui créent une version ;version_limit, global ou par modèle : plafonner le nombre de versions gardées par enregistrement ;- la suppression directe des anciennes versions, que la documentation présente comme sûre puisque chaque version est autonome, par exemple
PaperTrail::Version.where("created_at < ?", 1.year.ago).delete_all.
Organiser une vraie purge
Une demande d'effacement se traite comme une fonctionnalité, pas comme une requête SQL écrite à la main le jour où elle arrive.
- Inventorier les tables qui contiennent des données sur la personne : la table principale, les tables liées, les lignes marquées par une suppression douce, la table
versions, les fichiers Active Storage, les tâches de fond en attente qui transportent ses données. - Écrire un service d'effacement testé, qui détruit réellement les lignes (
really_destroy!avec Paranoia,destroyaprèsdiscard), puis supprime les versions correspondantes, par exemplePaperTrail::Version.where(item_type: "User", item_id: user.id).delete_all, sans oublier les modèles liés qui ont leur propre historique. - Prévenir les sous-traitants (envoi de courriels, suivi d'erreurs, stockage de fichiers) comme le recommande la CNIL, et documenter le sort des sauvegardes.
- Planifier les purges ordinaires dans une tâche récurrente : destruction des lignes marquées depuis plus de N jours, des versions de plus de N mois. Les durées viennent de l'analyse de conformité du responsable de traitement, pas du code.
Si une partie des données doit être gardée pour une obligation légale, la CNIL donne l'exemple des données de facturation conservées dix ans en application du Code de commerce. Mieux vaut alors les extraire dans une base ou un schéma d'archive à accès restreint que de les laisser, masquées, dans la base active.
Et les journaux applicatifs ?
La CNIL a adopté en 2021 une recommandation sur la journalisation (délibération n° 2021-122 du 14 octobre 2021). Elle y recommande, de manière générale, de tracer les accès et les actions des utilisateurs habilités et de conserver ces traces entre six mois et un an. Une durée plus longue, jusqu'à trois ans dans les cas les plus courants, peut se justifier pour des traitements soumis à un contrôle interne, à condition de la documenter. Lorsque les données du traitement principal sont gardées moins de six mois, les journaux ne devraient pas en contenir, pour ne pas prolonger leur conservation par la bande.
Pour une application Rails, cela touche trois endroits : les journaux de production (le filtrage des paramètres sensibles par config.filter_parameters est un minimum) ; l'outil de suivi des erreurs, qui recopie souvent les paramètres et le contexte des requêtes ; et la table versions si elle sert aussi de journal d'audit, auquel cas ses durées de conservation doivent suivre la même logique. Une gem d'historique n'est pas un journal de sécurité, et l'inverse non plus : séparer les deux simplifie les règles de purge.
Ce qu'il faut retenir
- Une ligne avec
deleted_atoudiscarded_atest toujours là : ce n'est ni un effacement, ni un archivage sécurisé. - PaperTrail garde l'état complet d'un enregistrement détruit ; une demande d'effacement doit aussi purger
versions. - Les durées (lignes marquées, versions, journaux) se décident, s'écrivent et se programment dans une tâche récurrente.
- Le délai de réponse à une demande d'effacement est d'un mois, prolongeable de deux mois dans les cas prévus par l'article 12.
Pour les mots de passe et l'authentification, voir notre article sur la recommandation de la CNIL appliquée à Rails.
Article mis à jour le 10 novembre 2026. Il décrit des pratiques techniques et ne constitue pas un conseil juridique : les durées de conservation relèvent du responsable de traitement.
Guides pratiquesMots de passe et recommandation CNIL
Entropie de 80 ou 50 bits, blocage après 10 échecs, stockage haché et salé : les réglages de Devise et de Rails 8 à revoir.
Guides pratiquesRails pour l'administration : DSFR et ProConnect
Les composants du Système de design de l'État et la connexion ProConnect en Rails : les gems, leurs versions, et qui a le droit de s'en servir.
DonnéesRails dans le secteur public : les chiffres
143 dépôts Ruby recensés par code.gouv.fr, 33 applications Rails analysées : 9 sur Rails 8.1, 21 sur une série antérieure à 8.0. Méthode et CSV.