OneDrive vient d’ajouter une date d’expiration aux fichiers. Ce n’est pas une fonctionnalité — c’est un aveu : les données que vous conservez sont celles que vous finirez par perdre. Après 1 000+ violations et des délais de divulgation qui s’allongent, thésauriser les données clients n’est plus une décision neutre ; c’est un passif. Si votre SaaS s’appuie encore sur des « soft delete » et des sauvegardes sans limite, vous n’êtes qu’à une assignation, un gang de ransomware ou un bucket mal configuré d’un incident évitable.
Ce billet est un playbook pour CTO afin d’implémenter l’expiration dès la conception : des politiques de time-to-live (TTL) globales avec des SLO de suppression, des legal holds et des reçus auditables sur chaque stockage que vous utilisez — OLTP, objets, recherche, analytique, journaux, sauvegardes et fournisseurs. Vous obtiendrez un plan 30-60-90 jours et des conseils d’implémentation concrets pour Postgres, S3, Elasticsearch, Kafka, BigQuery/Snowflake et les systèmes de sauvegarde — ainsi que les arbitrages à affronter en tant que dirigeant·e technique.
Pourquoi l’expiration dès la conception maintenant
- Les violations continuent, les délais de divulgation empirent. Les bilans publics montrent des divulgations plus lentes, pas plus rapides. Cela signifie que davantage de données obsolètes sont exposées plus longtemps. La seule façon de réduire le rayon d’explosion est de stocker moins, moins longtemps.
- Les fournisseurs bougent en premier. L’ajout d’une expiration des fichiers par OneDrive de Microsoft est un signal : les clients attendent désormais des contrôles de rétention. Si votre application ne suit pas, vous perdrez des deals face à des concurrents plus matures en sécurité.
- Les régulateurs ont déjà écrit le mode d’emploi. RGPD art. 5(1)(e) (limitation de la conservation) et art. 17 (effacement), LGPD du Brazil arts. 15–16, et lois étatiques sur la vie privée sont alignés : ne conserver que ce qui est nécessaire, uniquement le temps nécessaire, et le prouver.
- L’IA augmente la pénalité du stockage massif. Les fenêtres de contexte et les vector stores disséminent du texte/des images sensibles partout. Même avec des « Lockdown Modes », la meilleure défense reste de ne pas détenir la donnée en premier lieu.
Le cadre de décision : cinq choix difficiles
Avant d’écrire une ligne de code, vous avez besoin de réponses nettes :
1) Classes d’objets et rétention par défaut
Chaque octet correspond à une classe d’objet avec un TTL par défaut. Commencez par une taxonomie simple et ajustez ensuite :
- Événements/metrics opérationnels : 7–30 jours
- Logs/traces produit : 14–60 jours
- Messages/commentaires d’utilisateurs finaux : 90–365 jours
- Pièces jointes/téléversements : 90–365 jours
- Enregistrements transactionnels (commandes, factures) : selon contrat/droit fiscal (souvent 3–7 ans)
- Logs d’audit/sécurité : 365–730 jours (ou selon SOC2/ISO)
Faites-en des valeurs par défaut par tenant, conditionnées au plan. Les PME acceptent généralement 90–180 jours ; les entreprises demanderont 7 ans et le legal hold. Prix à ajuster en conséquence.
2) SLO de suppression et votre « budget d’expiration »
Engagez-vous sur un SLO interne pour la vitesse à laquelle la donnée disparaît une fois éligible :
- p95 du temps jusqu’à la suppression définitive : moins de 6 heures
- p99 du temps jusqu’à la suppression définitive : moins de 24 heures
- Sauvegardes cryptodétruites : moins de 7 jours (ou votre SLA de sauvegarde)
Publiez ces engagements dans votre DPA. Si vous ne pouvez pas encore les tenir, fixez une cible initiale et instrumentez les écarts. Cela devient votre « budget d’expiration ».
3) Source de vérité : le Tombstone Ledger
Sans système d’enregistrement, une politique dérive. Créez un Tombstone Ledger append-only contenant object_id, object_type, tenant_id, created_at, expiry_at, legal_hold_flag, reason_code. Les workers de suppression sur tous les stockages s’abonnent à ce ledger et agissent de manière idempotente. Le ledger est votre piste d’audit et votre générateur de reçus.
4) Legal holds et exceptions
Les ingénieurs détestent les exceptions ; les régulateurs les adorent. Vous avez besoin d’un legal_hold_flag qui stoppe l’expiration partout. Relié à votre workflow de ticketing/GC. Les holds doivent être bornés dans le temps et visibles dans l’interface produit. Chaque exception a un coût ; suivez-les.
5) Garanties client
Exposez les paramètres de rétention par classe d’objet dans l’application. Affichez les expirations à venir, autorisez l’opt-down (TTL plus court) et l’opt-up conditionné au plan (TTL plus long). Envoyez des reçus de suppression avec les décomptes d’objets, les temps p95/p99 et la couverture par stockage. C’est désormais un critère compétitif dans les RFP.
L’architecture : transformer la politique en code
Mettez en place un schéma simple et robuste :
- Retention Policy Service : Évalue les politiques et écrit (object_id, expiry_at) dans le Tombstone Ledger lors de la création/mise à jour. Réévalue à l’accès si vous utilisez des TTL basés sur last_accessed.
- Tombstone Ledger : Table append-only (p. ex., Postgres partitionnée par mois) ou flux d’événements (Kafka). Enregistrements immuables et signés.
- Deletion Orchestrator : Consomme les tombstones, diffuse vers des workers spécifiques à chaque stockage, suit les SLO par stockage et émet des reçus.
- Store Workers : Workers pour Postgres, S3, Elasticsearch, Kafka, BigQuery/Snowflake, CDN et sauvegardes. Idempotents, réessayables, avec dead-letter queues.
- Métriques + audits : Longueur du backlog de suppression, temps p95/p99 par stockage, % de couverture par classe d’objet, nombre de legal holds, et audits par échantillonnage (prouver l’absence).
Implémentation, stockage par stockage
Postgres (OLTP)
- Schéma : Ajoutez
expiry_atettombstoned_ataux tables expirables. Évitez les suppressions en cascade surprises ; supprimez explicitement les enfants d’abord. - Partitionnement : Partitionnez par
expiry_atoucreated_at. L’expiration par drop de partition est en O(1) et évite les tempêtes de vacuum. Si le partitionnement par expiration est difficile, maintenez une table « shadow » séparée et partitionnée des IDs à supprimer. - Worker : Supprimez par lots en petits chunks (p. ex., 1–5 k lignes) pour garder des verrous courts. Utilisez un
DELETE ... USINGavec jointure sur une table temporaire d’IDs éligibles. Surveillez le bloat ; exécutez autovacuum de façon agressive sur les tables chaudes. - Clés étrangères : Si vous devez conserver les parents plus longtemps que les enfants, inversez la relation : l’enfant référence le parent, mais l’enfant peut être supprimé sans deadlocks ON DELETE RESTRICT.
Stockage d’objets (S3/GCS)
- Lifecycle : Utilisez les règles S3 Lifecycle pour expirer les objets à
expiry_at. Si vous utilisez le versioning, configurez aussi NoncurrentVersionExpiration et supprimez les delete markers périodiquement. - Multipart uploads : Expirez les téléversements multipart inachevés (fuite courante). Activez AbortIncompleteMultipartUpload à 7 jours.
- Chiffrement : Des clés KMS par tenant permettent de cryptodétruire les sauvegardes en supprimant les clés. Faites une rotation annuelle a minima.
- CDN : Purgez à la suppression. Définissez un Cache-Control max-age inférieur à votre TTL le plus court sauf si le contenu est immuable.
Recherche (Elasticsearch/OpenSearch)
- ILM (Index Lifecycle Management) : Rollover par taille/temps, puis suppression au TTL. Pour des index multi-tenant, partitionnez par temps pour rendre la suppression peu coûteuse.
- Suppressions : Supprimez définitivement les documents par ID depuis le flux de tombstones pour éviter les résultats fantômes pendant la phase warm.
- Écueil : Les snapshots conservent des segments supprimés ; alignez la rétention des snapshots sur votre SLO de sauvegarde.
Événements/logs (Kafka/Pulsar)
- Rétention : Définissez
retention.mspar topic. Pour les topics à payload généré par l’utilisateur, préférez log compaction + rétention courte, ou chiffrez côté producteur avec des clés par tenant. - DLQ : Les dead-letter queues doivent hériter du TTL applicable le plus court ; elles deviennent facilement un puits de dark data.
Analytique (BigQuery/Snowflake)
- Partitionnement : Partitionnez les tables par
event_dateetcluster by tenant_id. Utilisez des table TTLs (BigQuery) ou un DROP PARTITION planifié (Snowflake) pour faire respecter l’expiration. - Vues matérialisées : Recalculez uniquement sur les partitions courantes. Les jobs de backfill ne doivent pas ressusciter des données expirées.
- Ensembles d’entraînement de modèles : Suivez la provenance. Si votre TTL invalide un cohort d’entraînement, journalisez et réentraînez. Mieux que d’expliquer à votre conseil pourquoi vous avez utilisé des données que vous aviez promis de supprimer.
Sauvegardes
- Rétention par tiers : Sauvegardes chaudes (7–14 jours), tièdes (30 jours), pas de froides sauf exigence contractuelle. Raccourcissez par défaut.
- Cryptodestruction : Chiffrez par tenant ou par bucket. Lorsqu’un objet expire, marquez sa clé pour révocation à l’échéance du SLO de sauvegarde.
- Discipline de restauration : Les restaurations ne doivent pas réintroduire des données expirées. À la restauration, exécutez un job d’expiration post-restore avant la remise en service.
Vérification : ne vous contentez pas de supprimer — prouvez l’absence
- Reçus : Pour chaque tenant, émettez des reçus mensuels : objets expirés, temps de suppression p95/p99, stockages couverts, exceptions (holds). Cela fait la différence en RFP.
- Audits aléatoires : Échantillonnez 100 IDs expirés chaque mois et tentez de les récupérer depuis chaque stockage et système analytique. Zéro ne doit répondre. Alertez au moindre hit.
- Attestations fournisseurs : Pour les fournisseurs critiques (p. ex., observabilité, support SaaS, prestataires LLM avec stockage de fichiers), obtenez des rapports SOC/ISO couvrant les contrôles de suppression ; ajoutez au DPA une clause exigeant des TTL et une preuve sous 10 jours ouvrés.
Ce que cela économise : coûts et rayon d’explosion
Ne cadrez pas l’expiration uniquement comme de la conformité. C’est aussi des économies et de la disponibilité.
- Exemple de coût S3 : Un SaaS de stade intermédiaire avec 400 To sur S3 Standard paie environ 400 000 Go × 0,023 $ = 9 200 $/mois. Si 60 % des pièces jointes de plus de 180 jours ne sont jamais réaccédées (typique), un TTL de 180 jours plus suppression retire ~240 To, économisant ~5 520 $/mois avant les économies sur requêtes et réplication.
- Recherche et analytique : Des index et partitions plus petits signifient moins de nœuds, des requêtes plus rapides et un clustering moins cher. Il n’est pas rare de voir 20–40 % de réduction d’infra après des TTL agressifs.
- Rayon d’explosion d’incident : Si un attaquant atterrit à T0, tout ce qui est plus ancien que votre TTL n’existe pas à exfiltrer. C’est la seule « mitigation » garantie.
Arbitrages à assumer
- Attentes produit : Les clients qui adorent « rouvrir un ticket de 2018 » se plaindront. Proposez des exports et des rétentions étendues conditionnées au plan, mais ne revenez pas à l’immortalité.
- Utilité ML vs. vie privée : Des TTL courts réduisent l’historique d’entraînement. Contrez par l’échantillonnage, l’augmentation synthétique ou des fenêtres glissantes.
- Complexité : L’orchestration de suppressions cross-store est un vrai travail d’ingénierie. Mais il est borné et testable — contrairement au passif de tout garder indéfiniment.
30-60-90 jours : livrez sans tout refaire d’un coup
Jours 0–30 : inventaire et fondamentaux
- Inventaire : Énumérez les classes d’objets et les stockages (OLTP, objets, recherche, analytique, logs, sauvegardes, CDN, LLM/vector stores, outils de support). Attendez-vous à 12–20 puits de données matériels dans un SaaS typique.
- Valeurs par défaut : Choisissez des TTL par défaut visibles côté tenant (p. ex., 90 jours pour messages/fichiers, 365 jours pour l’audit, 30 jours pour les logs). Inscrivez-les dans votre DPA.
- Tombstone Ledger : Construisez-le dans Postgres, partitionné mensuellement. Ajoutez des hooks d’écriture dans les chemins de code qui créent/modifient des données.
- Legal hold : Créez une API et une UI pour définir/lever des holds par tenant/classe d’objet, avec expiration et motifs.
- Implémentez S3 + Postgres : Déployez les règles de lifecycle, un worker de suppression par lots Postgres, et les premiers reçus. Fixez des SLO internes (p95 : 6 h ; p99 : 24 h).
Jours 31–60 : étendre et instrumenter
- Recherche + analytique : Appliquez ILM aux index. Partitionnez les tables analytiques par date, ajoutez des scripts de TTL. Bloquez les requêtes qui couvrent des partitions expirées sauf autorisation explicite.
- Logs/bus d’événements : Alignez la rétention Kafka/Pulsar. Assurez-vous que les DLQ héritent des TTL. Cessez d’envoyer des PII dans les logs sans TTL défini.
- Métriques + alertes : Tableaux de bord pour le backlog de suppression, le temps de suppression par stockage, le nombre de legal holds, et les échecs d’audit. Alertez en cas de dépassement p99.
- UI client : Exposez les contrôles de rétention par classe d’objet et les reçus mensuels. Formez le Support à répondre « où est passé mon fichier de 2 ans ? »
Jours 61–90 : boucler la boucle
- Sauvegardes : Raccourcissez la rétention. Implémentez la cryptodestruction par clés par tenant. Validez que les pipelines de restauration ne ressuscitent pas de données expirées.
- Fournisseurs : Mettez à jour les DPA pour exiger des TTL et des attestations. Remplacez les fournisseurs qui refusent.
- Chaos deletion : Exercice trimestriel : choisissez un tenant, simulez un événement d’expiration massive et vérifiez la suppression de bout en bout dans les SLO.
- Feuille de route : Ajoutez un suivi last_accessed par classe d’objet afin de passer des TTL fixes à des TTL basés sur l’activité lorsque pertinent.
Pièges courants (et comment les éviter)
- Le soft delete n’est pas une suppression. Si la ligne vit encore et que les index la référencent, les utilisateurs peuvent encore l’inférer (comptages, résultats de recherche). Le soft delete uniquement comme état transitoire ; planifiez une suppression définitive peu après.
- Copies fantômes en cache. Les caches CDN et applicatifs survivent souvent aux données. Alignez les TTL des caches sur votre TTL de données le plus court et purgez sur tombstones.
- La réindexation recherche ressuscite les données. Les jobs de reindex qui lisent de vieux snapshots ramèneront des documents expirés. Limitez la réindexation aux partitions vivantes uniquement.
- Exports non bornés. Des exports CSV qui traînent dans des buckets S3 « exports/ » deviennent un nouveau lac de dark data. Traitez les exports comme des objets expirables avec des TTL courts (7–30 jours).
- Prolifération d’observabilité. Vos fournisseurs d’APM et de logs stockent souvent des PII par accident. Nettoyez à la source, masquez agressivement et imposez des TTL côté fournisseurs dans les contrats.
- LLM/vector stores. Si vous embeddez du contenu utilisateur pour du RAG, la base vectorielle est une nouvelle copie. Faites des vecteurs des objets de première classe avec des TTL et une suppression liée au tombstone de l’original.
Lien avec le profil de risque IA actuel
Même les meilleurs fournisseurs de modèles déploient des « Lockdown Modes » pour isoler la donnée et réduire le rayon d’explosion des prompt injections. C’est nécessaire, mais insuffisant. Un prompt ne peut pas fuiter une donnée que vous avez déjà supprimée. L’expiration dès la conception est la barrière la plus économique et la plus fiable pour les fonctionnalités IA, car elle réduit le contexte potentiellement exposable.
À quoi ressemble un bon résultat en production
- Couverture : 100 % des classes d’objets mappées à des TTL, avec support du legal hold.
- Latence : p95 du temps jusqu’à la suppression définitive sous 6 heures sur chaque stockage, auditable.
- Reçus : Les tenants peuvent récupérer des reçus de suppression et exporter en un clic un rapport de politique pour les auditeurs.
- Sauvegardes : Cryptodestruction sous 7 jours ; les restaurations ne réintroduisent pas de données expirées.
- Fournisseurs : DPA avec clauses TTL et attestations annuelles ; signaux faibles escaladés aux achats.
Comment staffer
Vous n’avez pas besoin d’une nouvelle plateforme. Il vous faut une petite équipe senior — 1 staff backend, 1 infra/SRE, 1 data engineer, 0,5 produit/GC — pour piloter le ledger, les workers et l’alignement fournisseurs. Pour les équipes US, une équipe nearshore au Brazil offre 6–8 heures de recouvrement et, d’après notre expérience, 20–30 % de TCO en moins pour ce travail trans-systèmes riche en « plomberie » technique. L’essentiel est de leur donner l’autorité de dire « non » aux fonctionnalités immortelles.
Bottom line
Le toggle d’expiration de OneDrive et le compteur de violations qui ne s’arrête jamais vous disent la même chose : la suppression est désormais une exigence produit. Vous pouvez soit la codifier avec un ledger, des SLO et des reçus — soit continuer à payer des intérêts composés sur des données dont vous n’avez pas besoin. Livrez l’expiration dès la conception en un trimestre et rendez le prochain incident significativement plus petit avant même qu’il ne commence.
Points clés à retenir
- Définir des TTL par défaut par classe d’objet, avec extensions conditionnées au plan et legal holds.
- Implémenter un Tombstone Ledger et un orchestrateur de suppression ; mesurer les temps p95/p99.
- Faire respecter l’expiration sur Postgres, S3, la recherche, l’analytique, les logs, les sauvegardes, le CDN et les fournisseurs.
- Prouver l’absence : envoyer des reçus de suppression, exécuter des audits aléatoires et exiger des attestations fournisseurs.
- Anticiper les arbitrages : certaines fonctionnalités et l’utilité ML diminueront ; vos risques et vos coûts aussi.