Retour au blog
SécuritéPour les développeurs7 min de lecture

Ce que nous avons appris en construisant un accès résilient aux données juridiques publiques françaises

Notre agent de recherche juridique a commencé à répondre avec assurance, sans aucune source citée. La cause n'était pas l'IA — c'était une dépendance externe devenue inaccessible. Voici le principe de résilience que nous avons appliqué, et l'infrastructure que nous avons construite autour.

Jérémie EscachCTOPublié le 16 juillet 2026

La semaine dernière, notre agent de recherche juridique a commencé à donner aux avocats des réponses bien construites et argumentées à leurs questions — sans aucune source citée. Aucune référence de jurisprudence, aucun numéro d'article, rien. Pour un outil de recherche juridique, une réponse sans source n'est pas seulement peu utile : c'est le seul mode de défaillance que nous ne pouvons tolérer.

La cause n'était ni le modèle d'IA, ni une régression de prompt. Elle se trouvait trois couches plus bas, dans le chemin réseau vers une dépendance externe — et elle nous a appris quelque chose qui valait la peine d'être documenté correctement.

Sur quoi nous nous appuyons

Nos agents Recherche Juridique et Veille Juridique s'appuient sur des données juridiques françaises officielles : Légifrance pour les lois, les codes et l'index de jurisprudence, et Judilibre pour les décisions de la Cour de cassation. Ce sont deux infrastructures publiques, maintenues pour l'ensemble de l'écosystème juridique français, et ce sont les bonnes sources sur lesquelles s'appuyer — utiliser quelque chose de moins officiel signifierait des garanties plus faibles sur l'exactitude et la fraîcheur des données, un compromis qu'un outil de recherche juridique ne peut pas se permettre.

S'appuyer sur une infrastructure publique de ce type est, tout bien considéré, une bonne décision. C'est aussi, inévitablement, une dépendance — et les dépendances doivent être conçues pour être robustes, pas simplement supposées toujours fonctionner.

L'investigation

Le symptôme ressemblait à un problème de modèle : un agent produisant un raisonnement juridique fluide, sans aucune source à l'appui. Le réflexe est de suspecter le prompt, l'étape de récupération de contexte, ou le modèle lui-même. Nous avons écarté les trois en premier — la logique d'appel d'outils de l'agent se déclenchait correctement, et la même requête fonctionnait normalement contre un jeu de test dans un environnement inférieur.

Restait le chemin réseau. Isoler la cause réelle a demandé quelques étapes méthodiques :

  1. Les identifiants d'abord. Nous avons confirmé que les identifiants d'API étaient valides, à jour et correctement scopés — des identifiants de production, testés directement contre le point de terminaison OAuth de PISTE, la passerelle derrière laquelle se trouvent Légifrance et Judilibre. Ils fonctionnaient immédiatement lorsqu'ils étaient testés depuis un réseau sans lien avec notre infrastructure.
  2. Mêmes identifiants, origine différente, résultat différent. Cette seule observation a écarté toute hypothèse liée aux identifiants eux-mêmes. Ce qui échouait dépendait de l'origine de la requête, pas de son contenu.
  3. Lire les en-têtes de réponse, pas seulement le code de statut. Les requêtes en échec revenaient en 403, mais avec des en-têtes x-iplb-* attachés — la signature d'un load balancer OVHcloud placé devant la couche API de PISTE. C'est le signal de diagnostic concret : cela signifie que le rejet se produit à la frontière réseau, avant même que la requête n'atteigne la logique d'authentification applicative. Un problème d'identifiants ou de scope se comporte différemment — il échoue de la même façon quelle que soit l'origine, et l'erreur est en général plus précise qu'un simple 403.

Si vous intégrez PISTE et rencontrez un 403 qui ne corrèle avec rien d'anormal dans votre requête, vérifier la présence de ces en-têtes est le moyen le plus rapide de confirmer que vous avez affaire à un contrôle d'accès au niveau réseau, et non à un bug dans votre propre code d'authentification. Nous n'avons trouvé cette information documentée nulle part de façon évidente en amont — c'est bon à savoir avant d'y faire transiter du trafic de production.

Rien de tout cela ne pointait vers un problème dans notre code, nos identifiants, ou les données elles-mêmes — c'était spécifique au chemin réseau que prenait notre trafic de production.

Le principe, pas seulement le correctif

Il est tentant de traiter cela comme un incident isolé avec un correctif isolé. Nous ne pensons pas que ce soit la bonne leçon à en tirer. La véritable leçon est plus générale, et s'applique à n'importe quelle dépendance externe, pas seulement à celle-ci :

N'importe quel chemin unique vers n'importe quel fournisseur unique — aussi officiel soit-il, aussi fiable soit-il en général — peut devenir indisponible spécifiquement pour vous, pour des raisons totalement indépendantes de votre code applicatif. Des changements de routage réseau, une infrastructure de frontière qui se comporte différemment selon les origines, des limites de débit appliquées de façon asymétrique, des particularités d'infrastructure régionale. Rien de tout cela n'est un défaut du fournisseur. C'est simplement ce qui arrive lorsqu'une requête doit traverser une infrastructure réelle entre deux systèmes réels.

L'implication pour la conception : une dépendance rigide à un seul chemin pour atteindre un fournisseur critique est un point de défaillance unique, même si ce fournisseur affiche par ailleurs une excellente disponibilité. Si le comportement de votre produit se dégrade silencieusement dès que ce chemin unique traverse une mauvaise journée, vous n'avez pas construit de la résilience — vous avez construit une fonctionnalité qui fonctionne la plupart du temps.

Nous appliquons ce principe largement sur la plateforme : les appels LLM passent par une couche d'adaptateurs neutre vis-à-vis du fournisseur, précisément pour qu'aucun fournisseur de modèle unique ne soit une dépendance rigide ; le système de checkpointing est interchangeable entre plusieurs backends de stockage pour la même raison. Cet incident a été l'occasion d'appliquer la même exigence aux API de données externes, pas seulement aux composants que nous maîtrisons de bout en bout.

Le correctif — un second chemin, pas un contournement

Le correctif est un second chemin réseau dédié vers les mêmes API officielles, utilisé uniquement lorsque le chemin principal est dégradé. Nous l'avons construit comme un relais isolé et minimal — un serveur léger et séparé dont le seul rôle est de faire transiter le trafic — connecté via un tunnel chiffré et dédié.

Deux contraintes de conception ont compté davantage que la mécanique elle-même :

  • Désactivé par défaut, purement additif. Le chemin principal reste inchangé et demeure celui utilisé par défaut pour chaque requête. Le second chemin existe uniquement comme filet de secours, activé derrière un indicateur de configuration explicite. Rien ne change au fonctionnement normal.
  • Aucune visibilité sur le contenu, par construction. Le relais opère uniquement au niveau du transport. Le TLS s'établit de bout en bout entre nos serveurs et le fournisseur de données juridiques — le relais ne le termine jamais, ne l'inspecte jamais, et ne le pourrait techniquement pas. La seule chose qui traverse ce relais est du trafic chiffré ; la seule chose qu'un opérateur de ce relais pourrait observer, ce sont des métadonnées de connexion (horodatage, volumes échangés, paires IP/port) — jamais une requête, un jeton, ou le moindre octet de donnée client. Nous avons traité cette pièce d'infrastructure avec la même exigence que toute autre pièce touchant, même indirectement, à une requête issue d'un document client : minimiser ce qu'elle peut voir, par conception, pas par simple politique.

Nous avons validé le correctif comme nous validons toute chose avant de la considérer terminée : reproduire l'échec sur le chemin principal, confirmer le succès sur le chemin secondaire, et confirmer — de bout en bout, à l'intérieur du service réellement en production — que la chaîne complète fonctionne, pas seulement le maillon réseau isolé.

Ce que nous en retenons

L'échec intéressant, ici, n'a jamais été "une API a eu une mauvaise journée". Les API ont des mauvaises journées ; ce n'est pas une nouvelle. L'échec intéressant, c'est que notre propre architecture n'avait qu'un seul moyen d'atteindre une dépendance critique, et aucun filet de secours quand ce moyen unique s'est dégradé. C'est un manque de conception, et les manques de conception se corrigent d'une façon qui est en réalité satisfaisante : pas en espérant que la dépendance se comporte mieux la prochaine fois, mais en s'assurant que votre produit ne dépend d'aucun chemin en particulier pour faire transiter la donnée.

C'est l'exigence que nous appliquons désormais à chaque dépendance externe — pas seulement à celles qui ont déjà causé un incident.

Questions fréquentes

Votre agent de recherche juridique utilise-t-il des sources de données juridiques officielles ?

Oui. Nos agents Recherche Juridique et Veille Juridique interrogent directement Légifrance (lois, codes, index de jurisprudence) et Judilibre (décisions de la Cour de cassation) — les sources de données publiques officielles maintenues pour l'écosystème juridique français. Nous ne faisons ni scraping ni usage de miroirs non officiels.

Cet incident a-t-il exposé des données clients ?

Non. Le problème de connectivité affectait uniquement notre capacité à joindre une API externe de données juridiques — il n'a jamais touché aux documents, requêtes ou identifiants des clients. Le correctif de résilience décrit ici a été conçu avec la même exigence : le chemin réseau ajouté ne peut voir que des métadonnées de connexion chiffrées, jamais de contenu.

Pourquoi ne pas simplement éviter toute dépendance à des bases de données juridiques externes ?

Parce que construire ou maintenir un miroir complet et à jour des lois, codes et jurisprudence françaises serait plus lent, moins précis et moins fiable que d'utiliser directement les sources officielles. La bonne réponse n'est pas d'éviter la dépendance — c'est de s'assurer qu'aucun chemin unique vers elle ne peut mettre le produit à l'arrêt.

Comment distinguer une restriction d'IP sur PISTE d'un problème d'identifiants ?

Deux signaux. D'abord, testez les mêmes identifiants depuis un réseau différent : s'ils fonctionnent là-bas mais échouent depuis votre origine de production, le problème est lié à la provenance de la requête, pas à son contenu. Ensuite, regardez les en-têtes de la réponse en échec : les API adossées à PISTE (Légifrance, Judilibre) sont derrière un load balancer OVHcloud, et un 403 accompagné d'en-têtes x-iplb-* indique que la requête a été rejetée à cette frontière réseau, avant même d'atteindre la logique d'authentification applicative. Un problème d'identifiants ou de scope se comporte différemment : il échoue de façon identique quelle que soit l'origine, et l'erreur est en général plus précise qu'un simple 403.