Notes techniques
De courtes corrections d'erreurs de catégorie fréquentes.
Non normatif
- Version du Companion
- 1.0
- Se rapporte à COADF Core
- 2.2
- Statut
- À jour
- Dernière relecture
Chaque note corrige une erreur de catégorie : deux choses qui se ressemblent et n'offrent pas la même chose.
OpenTelemetry n'est pas une piste d'audit
OpenTelemetry enregistre et propage le contexte d'exécution : quels appels une requête a effectués, combien de temps ils ont pris, où ils ont échoué. Il est conçu pour être échantillonné, filtré et transformé en chemin vers un backend, et une trace qui n'est pas échantillonnée n'est pas exportée ; le processeur de filtrage du Collector écarte par configuration la télémétrie correspondante. Son identité est une exécution, portée dans l'en-tête W3C traceparent. Une piste d'audit répond à une autre question, sur une autre unité : ce qui est arrivé à une transaction métier, qui a agi et sur quelle preuve, de façon complète et sans modification ultérieure.
- Ne jamais échantillonner ni filtrer des entrées d'audit, ni les faire passer par un pipeline de télémétrie.
- Corréler les deux : enregistrer le
trace_idd'audit sur les spans comme attribut. Ne pas réutiliser un identifiant de trace distribuée comme identité d'audit. - Classifier ce qui sert à la corrélation. Un attribut de span quitte le stockage d'audit pour des exportateurs, des fournisseurs et une durée de conservation qui lui est propre : une référence opaque, jamais une donnée personnelle ni un secret.
- S'attendre à ce qu'une transaction métier s'étende sur plusieurs traces distribuées : la requête de réception, un job asynchrone, une décision prise des jours plus tard.
- OpenTelemetry: Sampling · documentation officielle · Vérifié le 2026-09-11
- OpenTelemetry: Transforming telemetry · documentation officielle · Vérifié le 2026-09-11
- W3C: Trace Context, the traceparent header · spécification · W3C Recommendation, Level 1 · Vérifié le 2026-09-11
Les politiques d'admission Kubernetes ne remplacent pas la validation dans l'application
Le contrôle d'admission intercepte les requêtes adressées au serveur d'API Kubernetes après l'authentification et l'autorisation, avant que l'objet ne soit persisté. Il voit des Deployments, des Pods et des ConfigMaps, et les requêtes qui les lisent le contournent entièrement. Il ne voit jamais les requêtes HTTP que traite un service, les messages qu'il consomme ni les réponses que renvoie un modèle. Il juge les requêtes à leur arrivée, ce que Kubernetes explicite pour un plugin d'admission : quand une LimitRange est ajoutée, les pods qui existent déjà restent inchangés.
- Utiliser l'admission pour les propriétés des charges de travail : images épinglées par digest, révisions nommées, identifiants d'accès absents là où ils doivent être absents.
- Garder la validation à la frontière dans l'application, sur chacun de ses points d'entrée.
- Auditer séparément les objets existants, comme le fait l'audit de Gatekeeper ; l'admission ne voit jamais que des changements.
- Kubernetes: Admission control: what are they · documentation officielle · Kubernetes 1.37 · Vérifié le 2026-09-11
- Kubernetes: Limit Ranges: admission-time validation · documentation officielle · Kubernetes 1.37 · Vérifié le 2026-09-11
- Open Policy Agent Gatekeeper: Gatekeeper: audit · documentation officielle · Gatekeeper 3.23 · Vérifié le 2026-09-11
L'event sourcing n'est pas nécessaire pour une preuve en ajout seul
L'event sourcing fait d'un journal d'événements en ajout seul le système de référence, et en dérive l'état. On obtient ainsi par construction un historique complet, à un prix considérable : chaque modèle de lecture est une projection, et chaque changement de la forme d'un événement est une migration de l'historique. Une piste d'audit en ajout seul à côté d'un état ordinaire donne ce que demande COADF P-4 (un historique auquel on ajoute sans jamais le réécrire, reconstructible en une requête) sans changer la manière dont le reste du système conserve son état. Des privilèges par opération et des triggers de refus suffisent pour en construire une dans PostgreSQL.
- Choisir l'event sourcing pour les raisons propres au domaine, pas pour obtenir une piste d'audit.
- Une table en ajout seul, avec un rôle limité à l'insertion, des triggers de refus et des écritures idempotentes, réalise une preuve en ajout seul sans event sourcing, dans le périmètre de confiance propre à la base de données.
- Dans les deux cas, l'entrée est écrite dans la même transaction que le changement qu'elle enregistre.
- PostgreSQL Global Development Group: Privileges · documentation officielle · PostgreSQL 18 · Vérifié le 2026-09-11
Les microservices ne sont pas nécessaires à l'isolation probabiliste
La frontière probabiliste est une propriété des chemins de code : aucun chemin ne permet à une sortie de modèle de devenir un objet faisant autorité sans une étape explicite et enregistrée. Une frontière de module que le build impose maintient cette propriété à l'intérieur d'un seul processus, avec des contrats d'import en Python ou des règles d'architecture écrites comme tests unitaires en Java. Une frontière réseau ajoute une application par l'infrastructure, et avec elle le versionnement des contrats, les défaillances partielles, les nouvelles tentatives et la propagation du contexte d'un saut à l'autre, qui sont autant de nouveaux endroits où la propriété peut se perdre.
- Déployer le composant probabiliste séparément quand la montée en charge, l'isolation d'une bibliothèque de fournisseur ou une livraison indépendante l'exige, et non parce qu'un principe l'exigerait.
- Imposer la frontière de module par un test d'architecture, dans un cas comme dans l'autre.
- Quand la frontière est un réseau, valider de nouveau du côté qui reçoit.
- import-linter: Contract types · documentation officielle · import-linter 2.15 · Vérifié le 2026-09-11
- ArchUnit: ArchUnit user guide · documentation officielle · ArchUnit 1.5 · Vérifié le 2026-09-11
Le typage statique ne remplace pas la validation à l'exécution aux frontières externes
Un système de types vérifie le code par rapport à lui-même. À une frontière externe, les données viennent de l'extérieur du code : un modèle, un client, une file. Les annotations de type de TypeScript sont effacées avant l'exécution du programme et JSON.parse est typé comme renvoyant any ; l'environnement d'exécution Python n'impose pas les annotations de type ; et un type Java décrit ce qu'on a demandé à un désérialiseur de produire, pas ce que l'expéditeur a envoyé. Le type est une promesse que la frontière doit tenir, à l'exécution, avec un schéma.
- Dériver le type statique du schéma d'exécution partout où le langage le permet.
- Valider de chaque côté qui reçoit, pas seulement au point d'entrée web.
- Tenir les conversions de type forcées hors du code de frontière : un cast est l'endroit où le système de types cesse de vérifier.
- TypeScript: The Basics: erased types · documentation officielle · Vérifié le 2026-09-11
- TypeScript: lib.es5.d.ts: JSON.parse · dépôt du projet · Vérifié le 2026-09-11
- Python Software Foundation: typing: support for type hints · documentation du langage · Python 3.14 · Vérifié le 2026-09-11
Un pipeline de CI au vert ne prouve pas qu'un contrôle suffit à l'architecture
Un pipeline au vert prouve que les contrôles qu'il a exécutés ont réussi. Il ne dit rien des contrôles ignorés et signalés comme réussis, des sélections qui ne correspondaient à aucun test, des fences placés sur le mauvais chemin, ni des propriétés pour lesquelles personne n'a écrit de contrôle. Le modèle de rapport de contrôles de COADF énonce la même règle depuis l'autre côté : un contrôle n'est déclaré appliqué que si sa preuve a été exécutée dans l'exécution identifiée et a réussi.
- Enregistrer, pour chaque exécution, quels contrôles ont été exécutés et combien d'assertions ont tourné.
- Prouver les dents de chaque fence sur son vrai chemin, et le prouver de nouveau quand le chemin change.
- Examiner ce qui n'est pas contrôlé avec autant de sérieux que ce qui l'est.
- GitHub: Control jobs with conditions · documentation officielle · Vérifié le 2026-09-11
