PD-264 — Spécification canonique contractuelle¶
1. Références¶
- Story : PD-264
- Epic : PD-187 — BLOCKCHAIN
- Sous-epic : Horodatage qualifié RFC 3161 — conformité et interopérabilité
- Projet : ProbatioVault-backend
- Domaine : blockchain / crypto-proof
- Besoin source :
PD-264 — Expression de besoin - Dépendance amont : PD-55 (DONE) — worker ancrage blockchain, entités TSA, module NestJS, processeur Bull
- Normes et exigences :
- RFC 3161 §2.2 (nonce dans
TimeStampReq) - RFC 3161 §2.4.2 (vérification du nonce dans
TimeStampResp) - RFC 3161 §4.6 (protection anti-rejeu)
- Outil d'interopérabilité cible :
openssl ts -verify - Vérification formelle cible : Prolog RFC 3161 = 18/18
2. Objectif¶
- Rendre le mécanisme nonce RFC 3161 obligatoire, vérifiable et traçable pour chaque jeton d'horodatage accepté.
- Supprimer la non-conformité formelle actuelle (17/18) en atteignant 18/18.
- Garantir le rejet systématique de toute réponse TSA :
- sans nonce ;
- avec nonce différent de la requête ;
- avec nonce déjà utilisé.
- Maintenir l'interopérabilité ASN.1/DER des jetons produits avec les outils standards.
3. Description fonctionnelle¶
- Le système gère un cycle probatoire RFC 3161 incluant les états métier suivants :
REQUEST_EMITTED: requête TSA construite avec nonce.RESPONSE_RECEIVED: réponse TSA reçue, en attente de validation.RESPONSE_ACCEPTED: réponse valide et conforme, autorisée à entrer dans le flux probatoire.RESPONSE_REJECTED: réponse invalide/non conforme, exclue du flux probatoire.TOKEN_PERSISTED: jeton accepté persisté en base append-only.-
Règles fonctionnelles :
-
Garde d'entrée d'automate : la validation fail-closed du nonce côté requête est un prérequis d'entrée dans le cycle d'états. Une requête sans nonce n'entre jamais dans l'automate ;
TC-264-01valide cette garde d'entrée (et non une transition interne). -
Chaque requête RFC 3161 inclut un nonce binaire de 128 bits (obligation fail-closed, sans distinction production/non-production).
-
Chaque réponse TSA est validée strictement avant toute écriture probatoire.
-
La comparaison nonce requête/réponse DOIT utiliser une primitive de comparaison en temps constant (ex :
crypto.timingSafeEqual). - Une réponse sans nonce est rejetée.
- Une réponse avec nonce déjà existant est rejetée.
- Une réponse rejetée n'est ni persistée ni propagée au journal append-only ni incluse dans l'agrégation Merkle.
- Transitions d'états autorisées :
REQUEST_EMITTED -> RESPONSE_RECEIVEDRESPONSE_RECEIVED -> RESPONSE_ACCEPTEDRESPONSE_RECEIVED -> RESPONSE_REJECTEDRESPONSE_ACCEPTED -> TOKEN_PERSISTED- Transitions inverses (obligatoires) :
RESPONSE_ACCEPTED -> RESPONSE_RECEIVED: INTERDITE (validation définitive).RESPONSE_REJECTED -> RESPONSE_RECEIVED: INTERDITE (réponse rejetée non rejouable).TOKEN_PERSISTED -> RESPONSE_ACCEPTED: INTERDITE (immutabilité post-insertion).RESPONSE_ACCEPTED -> RESPONSE_REJECTED: INTERDITE (pas de downgrade après acceptation).RESPONSE_REJECTED -> RESPONSE_ACCEPTED: INTERDITE (nouvelle tentative requiert nouvelle requête et nouveau nonce).- Comportement au retour/downgrade :
- Données existantes conservées sans altération.
- Aucun déverrouillage fonctionnel rétroactif.
- Aucun changement de quota applicable (non pertinent pour ce module).
3bis. Diagrammes Mermaid¶
Diagramme d'états — Cycle probatoire RFC 3161¶
Ce diagramme représente les 5 états métier et les transitions autorisées du cycle nonce. Les transitions inverses sont toutes INTERDITES (INV-264-12).
stateDiagram-v2
[*] --> REQUEST_EMITTED : Requête TSA construite\n(nonce 128 bits obligatoire — INV-264-01)
REQUEST_EMITTED --> RESPONSE_RECEIVED : Réponse TSA reçue
RESPONSE_RECEIVED --> RESPONSE_ACCEPTED : Nonce présent (INV-264-02)\n+ égalité stricte (INV-264-03)\n+ temps constant (INV-264-04)\n+ unicité globale (INV-264-05)
RESPONSE_RECEIVED --> RESPONSE_REJECTED : Nonce absent / mismatch / doublon\n(INV-264-07)
RESPONSE_ACCEPTED --> TOKEN_PERSISTED : Persistance atomique DB\n(INV-264-06, INV-264-13)
TOKEN_PERSISTED --> [*] : Jeton probatoire immutable\n(INV-264-08)
note right of RESPONSE_REJECTED
Aucune écriture DB,
aucun append audit/Merkle
(INV-264-06, INV-264-07)
end note
note right of RESPONSE_ACCEPTED
Validation définitive —
retour INTERDIT (INV-264-12)
end note Diagramme de séquence — Flux nominal requête-validation-persistance¶
Ce diagramme représente les interactions entre services lors du flux nominal, incluant la génération CSPRNG, l'appel TSA, la validation nonce et la persistance.
sequenceDiagram
participant W as Worker Ancrage<br/>(PD-55)
participant N as Module Nonce<br/>(PD-264)
participant TSA as TSA RFC 3161<br/>(externe)
participant DB as PostgreSQL<br/>(timestamp_tokens)
participant M as Agrégation Merkle<br/>(post-commit)
W->>N: buildRequest(hash)
activate N
N->>N: CSPRNG 128 bits (INV-264-01)
N-->>W: TimeStampReq + nonce
deactivate N
W->>TSA: POST TimeStampReq
activate TSA
TSA-->>W: TimeStampResp
deactivate TSA
W->>N: validateResponse(req, resp)
activate N
N->>N: Vérifier présence nonce (INV-264-02)
N->>N: timingSafeEqual(req.nonce, resp.nonce) (INV-264-04)
N->>N: Vérifier conformité ASN.1/DER (INV-264-09)
alt Nonce valide
N->>DB: CHECK unicité nonce (INV-264-05)
activate DB
DB-->>N: OK (unique)
deactivate DB
N->>DB: BEGIN TX — INSERT token (INV-264-06, INV-264-13)
activate DB
DB-->>N: COMMIT
deactivate DB
N-->>W: RESPONSE_ACCEPTED → TOKEN_PERSISTED
W->>M: Append post-commit (async, idempotent)
else Nonce absent / mismatch / doublon
N-->>W: RESPONSE_REJECTED (INV-264-07)
Note over W,DB: Aucune écriture DB ni append Merkle
end
deactivate N 4. Périmètre (inclus / exclu)¶
- Inclus :
- Activation contractuelle du nonce dans le flux RFC 3161 du module
tsa/. - Validation stricte présence/égalité/unicité du nonce avant toute persistance.
- Contrat de stockage du nonce en binaire brut 16 octets.
- Contrat d'unicité DB sur nonce (défense en profondeur anti-rejeu).
- Contrat de conformité ASN.1/DER et d'interopérabilité de vérification.
- Contrat de tests CI (mock TSA) + nightly (TSA qualifiée réelle).
- Exclu (hors périmètre) :
- Client QTSA complet (appel HTTP TSA externe) au-delà du besoin nonce.
- Rotation/révocation certificats TSA.
- Intégration d'une nouvelle TSA externe.
- Changement de rétention des jetons (10 ans, défini PD-55).
5. Modèle de données (entités, champs, index, contraintes)¶
- Entité concernée :
timestamp_tokens -
Champs contractuels minimaux :
-
nonce: BYTEA, taille exacte 16 octets, contrainte DDLNOT NULLen base pour tout token accepté ; migration requise de la colonne héritée PD-55 (VARCHAR(64)nullable) versBYTEA NOT NULL(16 octets). tsa_token: artefact RFC 3161 binaire (structure DER valide requise pour acceptation).created_atet identifiants probatoires : inchangés par PD-264 (hérités).- Contraintes :
- Contrainte d'immutabilité post-insertion maintenue (héritage PD-55).
-
Contrainte d'unicité sur
nonce(index unique). -
Contrainte DDL complémentaire recommandée : vérification taille
octet_length(nonce) = 16côté base. - Rejet métier si
nonceabsent, taille invalide, mismatch, doublon. - États de validation (métier) :
RESPONSE_ACCEPTEDetRESPONSE_REJECTEDsont mutuellement exclusifs.- Données manquantes explicitement identifiées :
- Le nom exact de la contrainte/index existant et la convention de nommage SQL ne sont pas fournis.
- Le schéma SQL complet de
timestamp_tokensn'est pas fourni dans le besoin. - Ces éléments sont requis pour une traçabilité DDL exhaustive, mais n'affectent pas les obligations contractuelles ci-dessus.
6. Invariants (INV-264-XX)¶
- INV-264-01 — Nonce obligatoire (fail-closed) Toute requête RFC 3161 contient un nonce de 128 bits. Aucune exception de mode d'exécution n'est autorisée.
- INV-264-02 — Présence nonce en réponse Toute réponse TSA acceptée contient un nonce non nul.
- INV-264-03 — Égalité stricte Toute réponse TSA acceptée vérifie
nonce_response == nonce_requesten binaire.
- INV-264-04 — Comparaison à primitive temps constant La vérification d'égalité nonce requête/réponse DOIT utiliser une primitive de comparaison en temps constant (ex :
crypto.timingSafeEqual). - INV-264-05 — Unicité globale Un nonce accepté n'existe qu'une seule fois dans
timestamp_tokens. - INV-264-06 — Validation avant écriture Aucune écriture DB, journal append-only ou inclusion Merkle ne se produit avant validation complète du nonce.
- INV-264-07 — Rejet strict des réponses non conformes Toute réponse sans nonce, avec mismatch ou nonce déjà utilisé est rejetée.
- INV-264-08 — Immutabilité post-insertion Le nonce persisté ne peut pas être modifié après insertion.
- INV-264-09 — Conformité ASN.1/DER Tout token accepté est structurellement conforme RFC 3161 §2.4.2.
- INV-264-10 — Interopérabilité Tout token accepté est vérifiable avec
openssl ts -verify. - INV-264-11 — Invariant de sécurité formel Pour toute réponse acceptée : présence nonce, égalité binaire, unicité en store.
- INV-264-envelope-encryption — NON APPLICABLE dans le contexte PD-264 Le nonce RFC 3161 de PD-264 n'est pas un secret cryptographique ; aucun artefact secret temporaire (clé, fragment, DEK, ReKey) n'est produit par ce périmètre. Le nonce est uniquement manipulé en mémoire transitoire pendant la validation puis persisté comme donnée probatoire.
- INV-264-12 — Interdiction des transitions inverses Les transitions
RESPONSE_ACCEPTED -> RESPONSE_RECEIVED,RESPONSE_REJECTED -> RESPONSE_RECEIVED,TOKEN_PERSISTED -> RESPONSE_ACCEPTED,RESPONSE_ACCEPTED -> RESPONSE_REJECTEDetRESPONSE_REJECTED -> RESPONSE_ACCEPTEDsont strictement interdites.
- INV-264-13 — Atomicité ACCEPTED -> PERSISTED (scope borné) La transition
RESPONSE_ACCEPTED -> TOKEN_PERSISTEDDOIT être atomique uniquement sur la persistance DB (INSERTtimestamp_tokens) via transaction englobante. Les opérations append-only journal et agrégation Merkle sont post-commit, asynchrones et idempotentes (retry-safe). En cas de crash avant commit : aucun token persisté. En cas de crash après commit mais avant append/Merkle : le token persisté reste valide et le rattrapage est assuré par le worker de réconciliation PD-55.
7. Critères d'acceptation (CA-264-XX)¶
- CA-264-01 : Une requête RFC 3161 sans nonce est refusée (fail-closed, tous modes).
- CA-264-02 : Une réponse TSA sans nonce est rejetée.
- CA-264-03 : Une réponse TSA avec nonce différent de la requête est rejetée.
- CA-264-04 : Une réponse TSA avec nonce identique et inédit est acceptable (sous réserve des autres validations RFC).
- CA-264-05 : Une tentative d'acceptation d'un nonce déjà persisté est rejetée (unicité effective).
- CA-264-06 : Aucun enregistrement DB n'est créé quand la validation nonce échoue.
- CA-264-07 : Aucun append audit/Merkle n'est produit quand la validation nonce échoue.
- CA-264-08 : Le nonce persisté est en binaire brut de 16 octets.
- CA-264-09 : Le token accepté est vérifiable via
openssl ts -verify. - CA-264-10 : La suite de vérification formelle Prolog passe de 17/18 à 18/18.
- CA-264-11 : CI rapide exécute des tests déterministes avec mock TSA conforme RFC.
- CA-264-12 : Nightly exécute une vérification sur TSA qualifiée réelle et archive le token probatoire.
8. Contraintes non fonctionnelles (performance, sécurité, conformité)¶
- Sécurité :
- Génération nonce via CSPRNG uniquement.
- Interdiction de générateurs pseudo-aléatoires non cryptographiques.
- Comparaison nonce via primitive de comparaison en temps constant.
-
Défense en profondeur : validation applicative + contrainte d'unicité DB.
-
Protocole statistique TC-264-07 (obligation de moyen) :
- Méthode : comparaison des distributions égal/mismatch avec Welch t-test bilatéral + Mann-Whitney U.
- Seuil :
alpha = 0.01(par test, décision conjointe). - Taille d'échantillon :
N = 100000mesures par classe (égal et mismatch), après warm-up de5000itérations. - Critère d'acceptation :
p_ttest >= 0.01ETp_mwu >= 0.01ET|Cliff's delta| < 0.147(effet négligeable).
-
Procédure d'escalade TC-264-07 :
- En cas d'échec statistique (
p < 0.01ou|Cliff's delta| >= 0.147), le test est relancé une seule fois sur infrastructure stable (CPU isolé/pinning). - En cas de second échec : ESCALADE obligatoire ; l'implémentation DOIT être auditée pour identifier une fuite temporelle potentielle.
- Ce contrôle est bloquant pour Gate 8 (non bloquant pour Gate ⅗).
- En cas d'échec statistique (
- Conformité :
- Alignement strict RFC 3161 (§2.2, §2.4.2, §4.6).
- Conformité formelle Prolog attendue : 18/18.
- Interopérabilité obligatoire avec
openssl ts -verify. - Qualité :
- Aucune régression CI (Sonar QG non dégradé, exigences de couverture projet respectées).
- Temporalité / SLA :
- Aucune transition temporelle identifiée (pas de TTL, expiration, deadline ou window dans le périmètre nonce).
- Robustesse :
- Le rejet nonce est déterministe, traçable et sans effet de bord persistant.
9. Hypothèses¶
- PD-55 reste disponible et valide comme fondation technique (module TSA, worker, entités, trigger d'immutabilité).
- Le flux probatoire conserve l'ordre logique : requête -> validation -> persistance -> agrégation Merkle -> ancrage blockchain.
- Les environnements CI et nightly disposent des prérequis cryptographiques/outils nécessaires pour les vérifications contractuelles.
- Les conventions de nommage DB/index seront définies selon standards projet.
- L'implémentation fournit une transaction englobante pour garantir l'atomicité de
RESPONSE_ACCEPTED -> TOKEN_PERSISTEDsur la seule persistance DB ; append-only et Merkle sont traités post-commit via mécanismes idempotents et réconciliation PD-55. - Aucune question ouverte bloquante n'existe côté PO à date.
10. Liens documentaires / Dépendances¶
- Dépendance story : PD-55 (DONE).
- Document source : PD-264 — Expression de besoin.
- Références normatives : RFC 3161 (§2.2, §2.4.2, §4.6).
- Vérification externe :
openssl ts -verify. - Contraintes organisationnelles : Sprint PD Sprint 9 (2026-02-20 au 2026-03-16).
- Exigences de test :
- CI standard : mock TSA conforme RFC.
- Nightly probatoire : TSA qualifiée réelle + archivage artefact.