Aller au contenu

Projet indépendant de R&D · Cologne

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_id d'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.

OPA est un moteur de politiques, pas une autorité de régulation

Open Policy Agent évalue des règles que quelqu'un a écrites sur une entrée que quelqu'un a fournie. Il découple la décision de son application, et c'est ce qui permet de gérer les règles comme des données. Il ne sait pas ce qu'exige une réglementation, et une règle écrite en Rego est exactement aussi juste que la lecture du texte qu'elle encode. La réponse du moteur est une preuve qu'une règle a été appliquée, jamais une preuve que la règle était juste.

  • Chaque règle a besoin d'un propriétaire, d'une source et d'une revue, comme toute autre interprétation d'un texte.
  • Enregistrer la révision avec chaque décision, pour qu'une correction ultérieure de la règle puisse être distinguée des décisions prises sous l'ancienne.
  • Une suite de tests qui réussit pour une politique prouve que la règle se comporte comme son auteur l'entendait, et ne dit rien de la justesse de sa lecture du texte.

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.

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.

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.

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.

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.

COADF Engineering Companion 1.0 · non normatif · se rapporte à COADF Core 2.2

Droits de publication réservés. Aucune licence publique n'est accordée à ce jour pour le COADF Engineering Companion 1.0 ni pour ses exemples de référence.

Statut de propriété intellectuelle et de publication