vendredi 7 mars 2014

FAQ n°4 : Autour de quelques règles d'implémentation SEPAmail

Il n'y a pas (encore) d'implémentation de référence du protocole SEPAmail. Il n'y a pas non plus de cas d'usage et d'exemples de flux partagés par la communauté. J'ai ouvert un espace pour cela, mais il n'y a pas encore de soumission importante. Pour ceux qui veulent partager, c'est le projet SMITE, SEPAmail, I Want Test Examples.

L'implémentation SMART des quatre premiers adhérents s'est construite autour d'un produit similaire (SEPAplug®, édité par StreamMind®). L'interprétation des équipes de développement de StreamMind était donc un peu un standard de fait pendant l'expérimentation initiale.

Dès 2010, SEPAmail.eu m'a demandé de faire un contrôle de cohérence entre les documents spécifiant le protocole et les différentes expérimentations autour de RUBIS et de GEMME. Cela m'a permis de confronter les documents produit par le committer de l'époque (Olivier Jousselin) avec les différentes implémentations de composant logiciels.

Un comité Norme s'est constitué en 2011 pour publier le standard SEPAmail en partenariat avec le committer. Trois versions ont vu le jour (la version 1112, 1202 et la version stable 1206, relue et validée par une quarantaine d'acteurs dont les éditeurs de l'expérimentation et tous les contributeurs).

Aujourd'hui, voici la liste des documents de référence du standard :
Pour les adhérents, il y a aussi :
  • un recueil de règles opérationnelles (à demander à sepamail.eu) pour se connecter au réseau SEPAmail
  • un cahier de test de conformité (à demander à sepamail.eu) pour mettre en valider la conformité de sa plate-forme ou de son implémentation
Il y a aussi, pour coopérer sur le standard :

La lecture de ces documents est importante pour connaitre les questions, les remarques des implémenteurs, quand ceux-ci posent des questions à la communauté.

Voici quelques unes des questions les plus souvent posées.

Pourquoi l'identifiant d'un message (balise MsgId) devrait être déduit d'un identifiant de missive (balise MsvId) alors que le message est généré avant la missive ?

La règle issue de la directive d'implémentation des messages est celle-ci : "This identifier should be equal to the missive identifier (MsvId element, see related doc.), followed by an underscore ('_') and by a number, which must be unique in a given missive. In any case, the message identifier MUST be unique for a given sender."

Cette règle, si elle est interprétée de façon naturelle, pose problème. En effet :
  • elle fait confondre la couche message et missive
  • on dénature la notion d'identifiant en essayant d'y coller un concept de classification
  • on limite à des nombres un champ déjà bien réduit par le préfixe en limitant cela à des nombres et non n'importe quel caractère
La plupart de ceux qui ont implémenté le protocole SEPAmail sont restés perplexes devant cette règle puisque le message est, a priori, généré avant la missive.

La plupart s'en sont sortis en générant un identifiant de type Id1_Id2 pour le message et ils ont récupéré l'identifiant Id1 pour construire la missive.
Mais ceci n'est pas satisfaisant dans une logique de protocole en couche.
De plus, un certain nombre de règles implicites, pour le maitre d'ouvrage, se cachent alors derrière cette directive d'implémentation, que l'on peut résumer par les questions qu'il se pose naturellement:
  • l'identifiant du message devant contenir l'identifiant de la missive,  faut-il vérifier cette règle ? Et dans ce cas, pourquoi ne pas inclure une balise MsdId dans le message ?
  • quelle est la nature de la relation entre un message et une missive: 1-1, 1-n, n-m ?
  • est-ce à l'adhérent (le relais et/ou générateur) de gérer ces identifiants ou l'expéditeur de la missive ?
  • en construisant un identifiant signifiant, ne suis-je pas en train de donner involontairement de l'information sur mon système ?

Comment interpréter la directive d'implémentation de l'identifiant d'une missive (balise MsvId) ?

La directive d'implémentation de la missive pose le principe suivant "The format of this identifier is YYYYMMDDhhmmssxxx + "_" + sender_id. The first part is the creation date and time, including milliseconds The second part can be used freely by the sender."

Ceci pose des problèmes à l'implémentation, notamment car cela induit en première lecture une liaison à la date de génération de l'identifiant  avec une limitation sur le nombre d'identifiants que l'on peut créer.

Certains verront donc le besoin d'implémenter une règle de vérification des dates.

Ces problématiques d'implémentation sont venues de longues discussions sur le (soi-disant) besoin d'un identifiant unique de bout en bout pour les missives comme pour les messages. Naturellement, le problème n'est pas simple et je vous renvoie sur la notion d'uuid pour en comprendre la portée et les normes concernées.

Selon moi, ces problèmes ont été réglés en pratique il y a déjà longtemps par les MTA (Mail Transfert Agent) et les clients de messagerie. Un récepteur ne pouvant garantir qu'un émetteur sache identifier de façon unique un message, identifie pour lui-même tout ce qu'il reçoit. Nous devrions donc utiliser les solutions déjà trouvées par d'autres et qui, aujourd'hui, fonctionnent bien.

Un implémenteur peut donc générer son propre identifiant de missive et de message à la réception et ajouter celui-ci dans l'entête de la missive et du message.

Ma proposition, pour respecter la version 1206 du standard (et ne pas initier des complications dans l'implémentation) est de supposer que la "creation date and time" soit celle de SEPAmail (et non autre chose), c'est à dire le 1er avril 2008 vers 13h14 pour tous, comme cela, on en sera quitte pour un poisson d'avril. Je propose donc d'utiliser le préfixe 20080401131415926.

Pourquoi une missive doit absolument contenir un message de type SEPAmail ?

La missive peut contenir dans son corps (balise MsvBdy) zéro ou un message quelconque SEPAmail, comme indiqué dans la directive d'implémentation de la missive SEPAmail.

Il n'est donc pas possible d'inclure plusieurs messages.
Il n'est donc pas possible d'inclure autre chose qu'un message SEPAmail.
La liste des messages SEPAmail est définie dans les schémas.

En 2008, le premier schéma de missive SEPAmail permettait de contenir dans le corps de la missive n'importe quelle donnée (anyType). Ceci avait le charme de permettre de vérifier la validité d'une missive sans celle du contenu de la missive.
Pour l'expérimentation au sein des systèmes d'information bancaires, un responsable de la sécurité a demandé de définir tous les types des données et de ne faire qu'une validation globale de la missive contenant le message.
Les schémas ont donc été changés en conséquence. Les avantages sont ceux mis en avant par le responsable de la sécurité. Comme SEPAmail cherchait à l'époque à privilégier le mode unitaire et ne pas rester dans le mode batch qui est la norme bancaire d'échange d'information, le nombre de messages par missive a été limité à un message au plus.

Les inconvénients de ce choix sont nombreux s'il est respecté à la lettre: confusion de la couche missive et message, impossibilité de chiffrer le message facilement au sein d'une missive en clair, schéma xml très volumineux, balise racine du message xml non équivalente à la balise interne de la missive, etc...

Une proposition d'implémentation intéressante est, à mon avis, d'utiliser un schéma simplifié (par une transformation xsl ?) pour la missive et de bien distinguer les deux couches missive et message, comme on distingue déjà la couche enveloppe.

Pourquoi inclure tous les schémas XML dans le schéma de la missive ?

Un implémenteur m'a demandé pourquoi inclure tous les schémas xsd dans la missive et non seulement ceux dont on a besoin.
Pour bien comprendre de quoi on parle, je vous propose de regarder (attention à la limite mémoire de votre navigateur) ce schéma vectoriel représentant cette inclusion.

Quand un schéma est simple, la validation d'un flux xml est très rapide. Quand il est compliqué, cette validation peut être couteuse en ressource machine ou en mécanisme de cache. Le bon exemple est celui de la validation d'une missive d'acquittement qui ne nécessite aucun schéma de messages à inclure.

La question est donc licite et connue de tous les programmeurs avec l'inclusion des librairies au sein de leur programme.

Avec la solution préconisée du changement de schéma pour la missive (confère la question précédente), on peut implémenter une validation beaucoup plus efficace. C'est donc, selon moi, une réponse élégante à ce vrai problème.

Comment comprendre les espaces de noms SEPAmail ?

Ce sujet revient souvent sur le devant de la scène, notamment car le XML n'est vraiment pas human-readable.

Pour comprendre vite, disons simplement que SEPAmail définit un espace de nom principal décliné en plusieurs schémas (un pour la missive, un pour le message générique, un par type de message, quatre pour les types partagés par les schémas précédents) et fait référence aux espaces de nom de l'iso 20022 (des pain, des camt) et de la signature de xml (dsig).

Pour comprendre dans le détail, regardons la définition de la balise racine du schéma lié à la missive :

<schema
    targetNamespace="http://xsd.sepamail.eu/1206/"
    elementFormDefault="qualified"
    xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:sem="http://xsd.sepamail.eu/1206/"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#">


qui s'interprète comme suit :
  • targetNameSpace définit l'espace de nom du schéma,
  • elementFormDefault précise que tous les sous-éléments sont qualifiés par défaut au sein de l'espace de nom SEPAmail (l'équivalent n'a pas été fait pour les attributs)
  • xmlns="http://www.w3.org/2001/XMLSchema" est la référence à l'espace de nom définissant les schémas XML; cette déclaration pourrait donc être en première ligne
  • xmlns:sem="http://xsd.sepamail.eu/1206/" permet de définir le préfixe sem pour l'espace de nom SEPAmail
  • xmlns:ds="http://www.w3.org/2000/09/xmldsig#" permet de définir le préfixe ds pour l'espace de nom lié à la signature DSIG
On a ensuite :

<import>
    namespace="http://www.w3.org/2000/09/xmldsig#"
    schemalocation="xmldsig-core-schema.xsd">
</import>
<include schemalocation="type_sepa.xsd" />
<include schemalocation="type_sepamail_general.xsd" />
<include schemalocation="type_sepamail_missive.xsd" />
<include schemalocation="sepamail_message.xsd" />


qui s'interprète comme suite :
  • importation de l'espace de nom lié à XMLDSIG, qui permet la canonisation et la signature de flux XML (standard W3C)
  • inclusion du fichier interne à l'espace de nom SEPAmail type_sepa qui comprend les types dérivés de l'iso20022 pour SEPAmail
  • inclusion du fichier interne à l'espace de nom SEPAmail type_sepamail_missive qui comprend les types liés à la couche missive
  • inclusion du fichier interne à l'espace de nom SEPAmail type_sepamail_message qui comprend les types liés à la couche message
  • inclusion du fichier interne à l'espace de nom SEPAmail sepamail_message qui comprend les types de messages SEPAmail
Pour bien comprendre les entêtes des schémas et des flux xml associés, il faut donc maîtriser l'usage des attributs targetNamespace, schemalocation, namespace, elementFormDefault et avoir compris que la référence unique d'un espace de nom est une uri qui n'a pas besoin d'exister, bref une étiquette unique.

Je conseille d'installer localement un atelier xml avec les schémas et d'essayer de valider des flux pour bien comprendre les implications des espaces de noms.

Je conseille aussi d'inclure dans les flux xml la référence aux espaces de nom dans la première balise utilisant l'espace et d'utiliser des préfixes courts mais signifiants.

A la lecture de la question précédente, vous aurez compris que je conseille également une inclusion minimaliste selon les besoins réels de validation des flux.

Pourquoi RUBIS et GEMME ne font pas l'objet d'une SMIRK, comme Jade, Diamond, la missive, le message, la cryptographie etc. ?

La question m'a été posée récemment.
RUBIS et GEMME ne font pas l'objet d'une SMIRK comme JADE ou DIAMOND alors que cela pourrait (et devrait à mon sens) être le cas.


Cela serait un bon exercice de réduire la description de RUBIS et de GEMME à un ensemble de définition et de règles, comme pour JADE.



1 commentaire:

Unknown a dit…

Sur le dernier point, je suis parfaitement d'accord : tout devrait être formulé sous forme de SMIRK, du moins à un certain niveau.

Et d'ailleurs, il devrait aussi exister une "meta-SMIRK", définissant le contenu d'une SMIRK, son parcours, ses états ...