REVIEWITDocumentation
Cette page est générée depuis REVIEWIT_SignOff_Artifact/SPEC-Verification-v1.md — elle ne se corrige pas à la main.Corriger le contrat corrige la page. La modifier ici serait perdu à la prochaine génération.GÉNÉRÉE LE 5 septembre 2026 · REVIEWIT-SignOff-Verification/1 · 242451e5
Référence généréeÀ jour · générée le 5 septembre 2026

Vérifier une preuve hors ligne

01Ce que ce document permet #sec_e0af9bcf

REVIEWIT produit, à chaque signature, une attestation scellée dont on peut extraire un paquet de vérification : un fichier qui contient tout ce qu'il faut pour refaire la démonstration ailleurs.

Ce document est la spécification complète de ce format. Il est publié pour une raison précise : permettre à un tiers de vérifier une preuve sans nous, et même sans nous croire. Il décrit assez exactement la canonicalisation, la construction des arbres et la vérification des preuves d'inclusion pour qu'un auditeur, une direction des systèmes d'information ou un cabinet indépendant puisse écrire son propre vérificateur et obtenir le même verdict que le nôtre.

C'est la forme la plus haute de la garantie que REVIEWIT annonce. Une plateforme qui dirait « faites-nous confiance, c'est scellé » demanderait exactement ce que ce document rend inutile.

02À qui il s'adresse #sec_c1bc9732

À un lecteur technique : la personne qui vérifiera une preuve, ou celle qui écrira l'outil qui la vérifie. Il n'est pas nécessaire pour lire un rapport d'audit, ni pour utiliser REVIEWIT.

Un auditeur qui souhaite seulement obtenir un verdict n'a pas à lire ce texte : l'écran « Vérifier une preuve » du Workspace Center et l'outil en ligne de commande appliquent ce contrat, sans écart. Ce document existe pour ceux qui refusent de s'en remettre à l'un ou à l'autre — et ils ont raison de le pouvoir.

03Ce qu'il vous faut #sec_48297a56

Quatre éléments, et ils ne viennent pas du même endroit :

  1. Le paquet de vérification — le fichier lui-même. Il vous est remis avec la preuve qu'on vous oppose, ou vous le téléchargez depuis REVIEWIT.
  2. Un vérificateur — celui que vous écrivez à partir du présent document, ou celui que REVIEWIT met à disposition. Les deux doivent rendre le même verdict ; s'ils divergent, c'est un défaut, et il nous concerne.
  3. Le trousseau public de l'autorité — servi par ce portail à l'adresse /.well-known/seal-keyring.json , et remis avec l'annexe sécurité de votre contrat. Il porte les clés publiques avec lesquelles se contrôle la signature du sceau, et seulement elle . Tout le reste — l'empreinte, les racines de Merkle, le chaînage, la preuve d'inclusion — se vérifie sans aucune clé, depuis le seul fichier.
  4. L'empreinte de la clé racine — portée par l'annexe sécurité signée avec votre contrat. C'est elle, et elle seule, qui établit que le trousseau que vous avez téléchargé est bien le nôtre (§8.3).

04Ce que le fichier seul établit, et ce qu'il n'établit pas #sec_192edcae

Sans trousseau, un paquet reste entièrement vérifiable dans sa cohérence interne : que le manifeste produit bien l'empreinte annoncée, que les listes produisent bien les racines attestées, qu'un élément donné figure bien dans le périmètre scellé.

Ce que le fichier seul n'établit pas , c'est que ce contenu a été scellé par nous. Un paquet peut se déclarer scellé sans l'être : cette déclaration ne vaut rien tant que la signature de l'autorité n'a pas été contrôlée avec sa clé publique. Un vérificateur conforme doit donc distinguer ces deux constats et ne jamais présenter le second comme acquis à partir du premier.

051. Canonicalisation, version 1 #sec_53b1cef4

Un document canonique est un JSON UTF-8 sans BOM, sans espace ni retour à la ligne, tel que :

  1. les clés d'un objet sont triées par ordre ordinal des points de code ;
  2. les chaînes sont normalisées Unicode NFC ; seuls " , \ et les caractères de contrôle sont échappés ; le non-ASCII n'est pas échappé ;
  3. les seuls nombres sont des entiers signés sur 64 bits ; aucun flottant ; une proportion s'exprime pour dix mille ;
  4. les instants sont en temps universel, au format yyyy-MM-ddTHH:mm:ss.ffffffZ — six décimales, la septième tronquée ; les dates civiles au format yyyy-MM-dd ;
  5. une valeur non applicable est absente ; il n'existe ni null , ni chaîne vide tenant lieu d'absence ;
  6. les suites d'octets sont en hexadécimal minuscule .

Un document contenant un null , un flottant ou une clé dupliquée n'est pas un document canonique et est refusé.

062. Hachage #sec_9d21b1bf

SHA-256 , identifiant "SHA-256" porté dans cryptography.hash du manifeste.

073. Schéma d'arbre, version 1 #sec_3b2d707a

ÉlémentDéfinition
Préfixes de domainefeuille 0x00 , nœud 0x01 , arbre vide 0x02 , racine 0x03
FeuilleH(0x00 ‖ aléa ‖ contenu) — l'aléa fait 32 octets, propre à chaque feuille
NœudH(0x01 ‖ gauche ‖ droite)
Niveau impairle nœud orphelin est promu tel quel au niveau supérieur, jamais dupliqué
Engagementobjet canonique `{"domain":{"empty":2,"leaf":0,"node":1,"root":3},"hash":"SHA-256","leafCount":n,"schema":1,"tree":"scope""decisions"}`
Racine publiéeH(0x03 ‖ engagement ‖ racine brute) pour n ≥ 1
Racine du lot videH(0x02 ‖ engagement) avec leafCount = 0

Ordre des feuilles. Clé composite (SHA-256(identité), identité) , comparée octet par octet en lexicographique non signé, le second terme ne départageant que les égalités du premier. Deux identités identiques dans un lot sont un refus.

Deux arbres. scope : le contenu de la feuille est l'identité stable canonique {"criterion":…,"object":…,"type":…} . decisions : le contenu est la décision canonique (§5). Même ordre, même position pour un même item.

Aléas. Dérivés par SEAL de la génération cryptography.secretGeneration , par (arbre, position). Le secret ne figure dans aucun paquet.

084. Preuve d'inclusion #sec_b535f3ee

{"commitment":{…},"content":hex,"path":[{"side":"left"|"right","sibling":hex} | {"promoted":true} …],"position":p,"root":hex,"salt":hex,"schema":1}

Vérification : recalculer la feuille, remonter le chemin en exigeant à chaque niveau exactement ce que la structure impose — un frère du bon côté quand index a un voisin, une promotion quand index est le dernier d'un niveau impair —, puis H(0x03 ‖ engagement ‖ nœud) et comparer à la racine attestée. Un chemin plus court ou plus long que la structure est un refus.

095. Manifeste, version 1 #sec_9dbbc182

Blocs de l'objet racine (clés triées) : actors , context , cryptography , decisions , governance , header , qualification , scope , snapshot , statement .

  • header : attestation , canonicalization (1), complementRank , lot , originLot (absent pour le lot initial), schema (1).
  • decisions[i] : actor , decidedAt , exceptionUntil , identity , justification , origin ( human | defaultRule | systemClosure | nonDecidedUncovered ), previous , rule ( id , motive , version — présent si et seulement si l'origine n'est pas humaine), verdict .
  • qualification : closure , conflictOfInterest , coverage ( complete ), decisionMode , origins (quatre décomptes, calculés).
  • governance.indicators : les quatre entiers avec collected:true , ou {"collected":false} .
  • cryptography : hash , preflight ( {"state":"unavailable"} ou référence), secretGeneration , trees.scope et trees.decisions ( commitment , root ).

Forme scellée. L'empreinte scellée — celle que l'ancrage porte — est SHA-256 de la forme canonique où scope et decisions sont remplacés par leur engagement {"count":n,"hash":SHA-256(liste canonique)} . Les listes ne voyagent que dans le paquet complet ; les racines de Merkle les engagent déjà.

106. Paquets #sec_de906bc8

ChampCompletPonctuel
specificationREVIEWIT-SignOff-Verification/1idem
kindcompleteponctual
attestationforme scelléeforme scellée
digestSHA-256(attestation)idem
scope.items , decisionslistes complètes, en ordre canonique—
salts.scope , salts.decisionstous les aléas, par position—
proof—une preuve, avec l'aléa de la seule feuille dévoilée
sealing{"state":"unanchored"} ; ou anchored avec domain , segment , rank , anchoredAt , seal:"pending" ; ou sealed avec en plus seal.reference , seal.sealedAtidem

117. Procédure #sec_9a00ec24

  1. Relire le paquet comme document canonique (§1) ; refuser sinon.
  2. Vérifier specification .
  3. Recalculer SHA-256(attestation) et le comparer à digest , et à l'empreinte tenue par ailleurs le cas échéant.
  4. Vérifier header.schema , header.canonicalization , cryptography.hash .
  5. Complet : vérifier les engagements des deux listes ; vérifier qu'à chaque position la décision porte l'identité de l'item ; reconstruire chaque arbre depuis la liste et les aléas (§3) et comparer racine et leafCount à cryptography.trees .
  6. Ponctuel : vérifier que la preuve vise la racine et le leafCount attestés pour son arbre ; vérifier la preuve (§4).
  7. Lire sealing.state et le restituer tel quel : cette version ne vérifie ni l'ancrage ni le sceau, et un paquet unanchored n'est pas opposable.

Un paquet est valide quand tous les contrôles exécutés réussissent. Cela n'établit pas qu'il est scellé.

128. Trousseau public et ancrage par clé racine #sec_71a42b6e

Le sceau d'un paquet se vérifie avec la clé publique de l'autorité , publiée dans un trousseau : un fichier JSON, indépendant des paquets, que le tiers détient.

{
  "keys": [ { "kid": "signing:1", "alg": "ecdsa-p256-sha256", "spki": "<DER SubjectPublicKeyInfo, base64>" } ],
  "attestation": {
    "version": "seal.keyring.v1",
    "count": 1,
    "digest": "<hex>",
    "alg": "ecdsa-p256-sha256",
    "rootKid": "keyring-root:1",
    "rootSpki": "<DER SubjectPublicKeyInfo de la racine, base64>",
    "signature": "<base64>"
  }
}

Le paquet nomme sa clé, le trousseau la fournit. sealing.seal.keyId désigne l'entrée à employer. Une entrée n'est jamais retirée d'un trousseau : la retirer rendrait invérifiables toutes les preuves qu'elle a scellées.

8.1 Empreinte du contenu

Retenir les entrées portant à la fois kid , alg et spki — une entrée incomplète ne confère aucune clé et n'entre pas dans le calcul. Les trier par kid , en comparaison ordinale sur les points de code. Former une ligne par entrée, kid | alg | spki suivie d'un saut de ligne U+000A . L'empreinte est le SHA-256 de la concaténation UTF-8 de ces lignes, en hexadécimal minuscule.

La date de création d'une entrée, si elle figure, n'entre pas dans le calcul : c'est un instantané d'affichage.

8.2 Vecteur signé par la racine

seal.keyring.v1|<nombre d'entrées retenues>|<empreinte du contenu>

Signé en forme texte, encodé en UTF-8, par la clé racine, selon attestation.alg . Les suites admises sont celles du sceau : ecdsa-p256-sha256 (signature ASN.1 DER, RFC 3279) et rsa-pkcs1-sha256 . Un algorithme inconnu est un refus, jamais une admission.

8.3 Ce que le tiers détient, et pourquoi la racine

L'ancre du dispositif est l' empreinte de la clé racine — SHA-256 de son SubjectPublicKeyInfo DER, en hexadécimal minuscule — portée par l'annexe sécurité que le client signe avec son contrat.

Elle porte sur la racine , jamais sur le fichier. Un trousseau grandit : chaque rotation de clé de scellement y ajoute une entrée. Une empreinte du fichier se périmerait donc à la première rotation, et un auditeur détenant le bon fichier, périmé, verrait tomber une preuve authentique. La racine, elle, ne change pas ; l'annexe signée n'est jamais rouverte.

8.4 Procédure de vérification d'un trousseau

  1. Recalculer l'empreinte du contenu (§8.1) et le nombre d'entrées retenues, et les comparer à attestation.digest et attestation.count . Recalculer d'abord, vérifier la signature ensuite : contrôler la signature sur l'empreinte déclarée laisserait passer un trousseau dont on a changé les clés en conservant le bloc signé.
  2. Vérifier attestation.signature sur le vecteur (§8.2) avec attestation.rootSpki .
  3. Comparer l'empreinte de attestation.rootSpki à celle que porte l'annexe.

Six issues, et une seule est opposable :

IssueCe qui est établi
Trousseau ancréSignature vérifiée et racine conforme à l'annexe. Seul état opposable.
Signé, racine non contrôléeAucune empreinte d'annexe fournie : cohérence interne seulement — n'importe qui peut signer un trousseau avec sa propre racine.
Signé par une autre racineLe fichier n'est pas celui que l'annexe désigne.
AltéréLe contenu ne produit plus l'empreinte attestée.
Attestation invalideLa racine déclarée n'a pas signé ce contenu.
Non ancréAucun bloc attestation — un trousseau antérieur au dispositif. Ce n'est pas une faute ; c'est un fichier sans ancre.

Un trousseau non ancré permet toujours de contrôler un sceau. Ce qu'il ne permet pas, c'est d'établir d'où vient la clé publique employée — et une signature vérifiée avec une clé de provenance inconnue n'établit rien.

Esc
↑↓ naviguer↵ ouvrirVoir tous les résultats →