Résumé

  • Le numéro de séquence IMAP indique une position actuelle et se décale lorsqu’un message antérieur est expurgé. L’UID traverse les sessions, mais seulement dans une boîte et sous une valeur UIDVALIDITY donnée.
  • Quand UIDVALIDITY change, le serveur retire la garantie de continuité. Le client doit abandonner le cache et les commandes fondés sur les anciens UID plutôt que d’appliquer une intention correcte au mauvais message.

Une suppression exacte pouvait viser le mauvais courrier

Un téléphone a synchronisé une boîte de réception avant de perdre le réseau. Il retient qu’un contrat signé porte l’UID 7314. Pendant le trajet, son utilisateur demande de supprimer ce message. Au même moment, le service de messagerie restaure la boîte sur un stockage ancien qui sait conserver les courriers, mais pas les UID qu’IMAP leur avait attribués. La nouvelle base réutilise 7314 pour une autre pièce.

Au retour de la connexion, tout peut sembler normal. Le téléphone est authentifié. La commande est valide. Le serveur connaît bien un UID 7314. Si la restauration a gardé l’ancienne valeur UIDVALIDITY, le protocole présente une fausse continuité : la précision de la commande devient précisément ce qui rend l’erreur dangereuse.

La bonne réponse paraît brutale. Le serveur avance UIDVALIDITY ; le téléphone détruit l’état local de cette boîte et ne rejoue pas la suppression. Il faut resynchroniser. Ce coût visible évite une perte silencieuse.

Le rang se prête au calcul, pas à la mémoire

IMAP manipule d’abord des listes ordonnées. Dans une boîte de 40 messages, les numéros de séquence vont de 1 à 40. Ils servent à demander une plage, à compter les nouveaux arrivants et à suivre une sélection ouverte. Cette forme est compacte parce qu’elle décrit la position, non l’identité.

La différence apparaît à l’expurgation. Si le huitième message disparaît définitivement, l’ancien neuvième devient le huitième et toute la suite recule. RFC 2060 l’explique dans la spécification IMAP4rev1 de 1996 ; RFC 9051, qui définit IMAP4rev2 depuis 2021, maintient ce modèle.

Tant que le client reste connecté, les réponses du serveur lui permettent d’ajuster la correspondance. Un client déconnecté ne voit pas la série d’événements. À son retour, « message 8 » décrit la boîte présente. Rien ne prouve qu’il s’agit encore de l’objet observé avant le départ.

Cette limite n’est pas une faute d’IMAP. Une position relative est utile pour parcourir un ensemble. Elle devient dangereuse uniquement lorsqu’on lui attribue une permanence qu’elle n’a jamais promise.

En 1994, IMAP4 a séparé le message de sa place

RFC 1730 a publié IMAP4 en décembre 1994. Le protocole devait rendre une boîte distante aussi manipulable qu’une boîte locale et permettre au poste hors ligne de retrouver l’état du serveur. Il a donc ajouté l’UID : un entier de 32 bits, croissant dans chaque boîte, pas forcément contigu, qui persiste entre les sessions.

Le gain était considérable. Le client pouvait associer une copie, un indicateur « lu » ou une action en attente à l’UID sans comparer à nouveau tous les corps de message. L’UID apportait une mémoire au protocole.

Mais cette mémoire dépendait d’un stockage réel. Certains dépôts de courrier préexistants n’avaient aucun emplacement durable pour un UID IMAP. Un outil étranger à IMAP pouvait réordonner les fichiers. Une boîte supprimée pouvait être recréée plus tard sous le même nom. Une migration pouvait préserver le contenu et perdre les métadonnées d’identité.

Exiger que tous les systèmes garantissent une éternité impossible aurait réduit l’interopérabilité. Autoriser la réutilisation silencieuse aurait détruit la sécurité des opérations hors ligne. La solution fut de rendre la rupture observable.

UIDVALIDITY n’est pas un nom universel

Chaque boîte annonce une valeur UIDVALIDITY. Si les UID d’une session antérieure ne peuvent plus être maintenus, la valeur suivante doit être supérieure. Une date de création ou un compteur croissant peuvent la produire. Le choix interne varie ; l’obligation publique consiste à signaler une nouvelle génération.

Le vocabulaire prête à confusion. RFC 2683, recommandations d’implémentation publiées en 1999, insiste : UIDVALIDITY n’identifie pas la boîte. Deux boîtes distinctes peuvent afficher la même valeur. L’UID n’est unique qu’à l’intérieur de sa boîte. L’identité durable comprend donc le nom de boîte, UIDVALIDITY et l’UID.

Cette composition borne l’autorité de chaque nombre. « 7314 » ne signifie rien sans boîte. « UIDVALIDITY 98, UID 7314 » reste ambigu si l’on ignore s’il s’agit d’Inbox ou d’Archive. Ajouter des bits ne remplace pas le contexte.

Dans ce périmètre correct, la règle est forte. RFC 3501 puis RFC 9051 exigent que le triplet continue de désigner un seul message immuable sur ce serveur. Le corps, l’enveloppe, la date interne, la taille et la structure ne peuvent devenir ceux d’un autre courrier. Les drapeaux restent modifiables, car leur changement est une fonction normale. Après expurgation, l’UID ne peut pas être réattribué sous la même génération.

Le protocole a préféré une rupture déclarée

La norme encourage vivement la persistance. Changer UIDVALIDITY oblige les clients à reconstruire leur vue et peut déclencher beaucoup de trafic. Pourtant, elle conserve un langage pour les dépôts incapables de tenir la promesse. RFC 4315 définit UIDNOTSTICKY pour le cas hérité où les UID ne persistent pas, tout en déconseillant cette architecture aux nouveaux magasins de courrier.

Ce compromis est important. La compatibilité n’est pas obtenue en abaissant secrètement l’invariant. Le serveur peut reconnaître une limite, à condition de l’annoncer de façon à retirer toute validité aux références antérieures.

RFC 2683 relate le risque concret : un client qui ignore le changement peut supprimer le mauvais message. Il peut aussi déplacer, copier, marquer ou ouvrir la mauvaise pièce. Plus son mécanisme de répétition hors ligne est automatique, plus il doit être strict sur la génération.

Perdre le cache protégeait l’intention

RFC 4549 décrit en 2006 la synchronisation des clients déconnectés. Avant d’exécuter une action en attente, le client ouvre la boîte et compare UIDVALIDITY à sa copie locale. En cas de différence, il doit vider le cache de cette boîte, supprimer les actions qui citaient les anciens UID et les considérer comme échouées.

La procédure refuse un raccourci séduisant : reconnaître les messages par leur objet, leur date ou une ressemblance de corps. Ces attributs aident à rechercher ; ils ne prouvent pas qu’une commande préparée pour un objet peut gouverner l’autre. Un cache contient non seulement des données, mais aussi des décisions. Après la rupture de génération, ces décisions n’ont plus de cible démontrée.

L’invalidation reste limitée à la boîte concernée. RFC 2683 déconseille d’ailleurs un compteur UID unique pour tout un serveur. Un espace global s’épuise plus vite et peut transformer le problème d’une boîte en remise à zéro générale. L’échelle locale réduit la portée d’une défaillance tout en conservant l’utilité du numéro.

Même un lien devait porter son test de vieillissement

RFC 2192 a défini en 1997 le schéma d’URL IMAP. Un lien vers un message pouvait inclure la boîte, UIDVALIDITY et l’UID. Le logiciel chargé d’ouvrir ce lien devait comparer la valeur enregistrée à celle du serveur afin de déterminer si l’URL était devenue périmée.

UIDVALIDITY n’est donc pas une date d’expiration du courrier. Il ne certifie ni l’auteur ni l’intégrité cryptographique. Il accompagne une référence pour révéler que l’espace d’identité auquel elle appartenait n’existe plus.

La nuance est décisive : le mécanisme ne promet pas qu’une référence réussira toujours. Il promet qu’une rupture connue ne sera pas maquillée en succès.

QRESYNC accélère seulement la bonne génération

Les boîtes volumineuses et les connexions mobiles ont rendu la resynchronisation coûteuse. RFC 7162 associe CONDSTORE, qui suit les modifications de métadonnées, à QRESYNC, qui signale notamment les messages expurgés par VANISHED. Dans le meilleur cas, un client rattrape les changements en un aller-retour.

Le premier état fourni à QRESYNC est pourtant le dernier UIDVALIDITY connu. S’il ne correspond pas, le serveur ignore les séquences de modification et la liste des UID qui suivent. Une chronologie fine des changements ne vaut rien lorsqu’elle décrit une autre génération d’objets.

Le protocole fixe ainsi un ordre de preuve. D’abord : sommes-nous encore dans le même espace d’identité ? Ensuite seulement : qu’est-ce qui a changé ? La performance ne peut pas inverser ces questions.

UIDONLY a poussé plus loin le choix de l’identité

En mai 2024, RFC 9586 a publié l’extension expérimentale UIDONLY. Une fois activée, elle interdit les numéros de séquence dans les commandes et les réponses de la session. Les variantes fondées sur les UID et la réponse VANISHED remplacent la carte des positions mouvantes.

L’objectif est aussi économique : client et serveur peuvent réduire les ressources nécessaires pour maintenir la correspondance entre séquences et UID. Le document ne rend pas l’extension obligatoire et ne mesure pas son déploiement. Il montre néanmoins que, trente ans après RFC 1730, la conception d’IMAP continue de distinguer les coordonnées éphémères des identifiants persistants.

UIDONLY n’abolit pas UIDVALIDITY. Un UID reste local à une boîte et à sa génération. Enlever la position relative rend l’adresse plus claire ; cela ne la rend pas souveraine hors de son périmètre.

La stabilité exigeait le droit de déclarer l’instabilité

L’élégance d’IMAP tient moins à la permanence de l’UID qu’à la répartition des responsabilités. Le serveur contrôle le stockage et sait si les UID ont survécu. Il doit déclarer la génération. Le client contrôle son cache et ses intentions différées ; il doit leur retirer toute autorité lorsque la génération ne correspond plus.

Le protocole commun reste mince. Il n’impose ni moteur de stockage, ni méthode de sauvegarde, ni base locale. Il fixe ce qui ne doit pas être confondu, le signal d’une rupture et la réaction sûre. Les systèmes gardent leur liberté d’implémentation, mais cette liberté n’autorise pas un ancien nombre à commander un nouvel objet.

L’UID traverse les sessions précisément parce qu’UIDVALIDITY peut dire quand cette traversée s’est terminée.

Sources et limites

RFC 1730 fournit la définition de 1994 ; RFC 2060, RFC 3501 et RFC 9051 précisent les séquences, les UID et le triplet d’identité. RFC 2683 documente les risques d’implémentation, RFC 2192 les liens périmables, RFC 4315 UIDNOTSTICKY, RFC 4549 le comportement hors ligne, RFC 7162 QRESYNC et RFC 9586 l’extension expérimentale UIDONLY. Ces textes ne permettent pas d’affirmer le taux de déploiement actuel, le comportement d’un produit donné, l’authenticité d’un message ou une méthode universelle de calcul d’UIDVALIDITY.