Aller au contenu

PD-276 — Scénarios de tests contractuels

1. Références

  • Spécification : PD-276-specification.md
  • Epic : PD-189 (Epic crypto-proof)

2. Matrice de couverture

ID Invariant ID Critère ID Test Couverture Commentaire
INV-276-01-zeroknowledge CA-276-04 TC-NOM-01 Oui Validation seule, sans dérivation serveur
INV-276-01-zeroknowledge CA-276-06 TC-INV-01 Oui Vérification contractuelle anti-dérivation
INV-276-02-argon2-minima CA-276-04 TC-NOM-01 Oui Minima exacts acceptés
INV-276-02-argon2-minima CA-276-04 TC-ERR-01 Oui Valeur sous minima rejetée
INV-276-02-argon2-minima CA-276-04 TC-ERR-02 Oui Itérations sous minima rejetées
INV-276-02-argon2-minima CA-276-04 TC-ERR-03 Oui Paramètre manquant rejeté
INV-276-02-argon2-minima CA-276-04 TC-ERR-04 Oui type != 2 rejeté
INV-276-03-argon2-bounds CA-276-04 TC-NOM-01 Oui Bornes basses exactes acceptées
INV-276-03-argon2-bounds CA-276-05 TC-NOM-02 Oui Bornes hautes exactes acceptées
INV-276-03-argon2-bounds CA-276-05 TC-ERR-05 Oui Valeur > max rejetée
INV-276-04-config-centralisee CA-276-06 TC-NOM-03 Oui Endpoint expose config unique et exacte
INV-276-05-metadata-binding CA-276-08 TC-NOM-04 Oui Tag créé avec longueur 32 bytes
INV-276-05-metadata-binding CA-276-07 TC-NOM-08 Oui Colonne/fait metadata_tag vérifiés
INV-276-05-metadata-binding CA-276-09 TC-NOM-06 Oui Phase 1 nullable
INV-276-05-metadata-binding CA-276-09 TC-NOM-07 Oui Phase 2 NOT NULL
INV-276-05-metadata-binding CA-276-13 TC-NOM-12 Oui LEGACY en phase 1 : lecture seule + warning
INV-276-06-separation-cles CA-276-08 TC-INV-02 Oui HKDF + contexte strict vérifié
INV-276-07-verify-before-access CA-276-08 TC-NOM-05 Oui Vérification préalable avec tag valide
INV-276-07-verify-before-access CA-276-08 TC-ERR-07 Oui Tag invalide => refus immédiat (HTTP 422, <100ms)
INV-276-07-verify-before-access CA-276-08 TC-NEG-01 Oui Substitution inter-device bloquée
INV-276-08-envelope-encryption CA-276-12 TC-INV-03 Oui (probatoire) Contrôles probatoires sur échantillons et scans
INV-276-09-prolog-facts CA-276-02 TC-NOM-08 Oui service(argon2, 'Argon2Service') présent
INV-276-09-prolog-facts CA-276-03 TC-NOM-08 Oui service_method(argon2, validateParams) présent
INV-276-09-prolog-facts CA-276-07 TC-NOM-08 Oui entity_column(...metadata_tag, bytea) présent
INV-276-09-prolog-facts CA-276-01 TC-NOM-09 Oui Audit final 24/24
INV-276-09-prolog-facts CA-276-01 TC-INV-04 Oui Faits émis/consommés alignés avec check_10/check_19/check_22
INV-276-10-non-regression CA-276-11 TC-NR-01 Oui 21 checks précédents inchangés (même statut OK/KO)
INV-276-10-non-regression CA-276-01 TC-NOM-09 Oui Score final sans baisse
INV-276-11-state-machine CA-276-09 TC-NOM-10 Oui Transition LEGACY -> BOUND autorisée
INV-276-11-state-machine CA-276-09 TC-NOM-13 Oui Transition LEGACY -> TAMPERED autorisée si incohérence détectée
INV-276-11-state-machine CA-276-09 TC-ERR-10 Oui Transition BOUND -> LEGACY interdite
INV-276-11-state-machine CA-276-08 TC-ERR-11 Oui État TAMPERED terminal
INV-276-11-state-machine CA-276-09 TC-NEG-02 Oui Downgrade sécurité interdit
INV-276-05-metadata-binding CA-276-10 TC-NOM-11 Oui down() restaure état contractuel

3. Scénarios de test – Flux nominaux

TEST-ID: TC-NOM-01
Référence spec: INV-276-01, INV-276-02, INV-276-03, CA-276-04

GIVEN
  - Requête de validation KDF avec {memory=65536, iterations=3, parallelism=4, type=2, hashLength=32}
  - Contexte serveur en mode validation contractuelle
WHEN
  - La validation Argon2id est exécutée
THEN
  - La validation est acceptée
  - Aucun rejet de conformité n'est retourné
AND
  - Le journal d'audit trace une opération de validation (pas de dérivation de clé métier)
TEST-ID: TC-NOM-02
Référence spec: INV-276-03, CA-276-05

GIVEN
  - Requête de validation KDF avec bornes hautes exactes {memory=1048576, iterations=10, parallelism=16, type=2, hashLength=32}
WHEN
  - La validation Argon2id est exécutée
THEN
  - La validation est acceptée
AND
  - La réponse confirme la conformité aux bornes contractuelles
TEST-ID: TC-NOM-03
Référence spec: INV-276-04, CA-276-06

GIVEN
  - Appel autorisé au point d'accès de configuration Argon2id
WHEN
  - La configuration centralisée est récupérée
THEN
  - La réponse contient exactement: memory(default=65536,min=65536,max=1048576), iterations(default=3,min=3,max=10), parallelism(default=4,min=4,max=16), type(default=2,min=2,max=2), hashLength(default=32,min=32,max=32)
AND
  - La configuration est unique et cohérente avec le contrat de validation
TEST-ID: TC-NOM-04
Référence spec: INV-276-05, INV-276-06, CA-276-08

GIVEN
  - Métadonnées complètes {algorithm, version, envelope_type, device_id}
  - Enveloppe en création/rotation
WHEN
  - Le metadata binding est calculé et persisté
THEN
  - metadata_tag est présent
  - metadata_tag a une longueur de 32 bytes
AND
  - L'opération est auditée comme BOUND_TAG_VALID
TEST-ID: TC-NOM-05
Référence spec: INV-276-07, CA-276-08

GIVEN
  - Enveloppe persistée avec metadata_tag valide
WHEN
  - Un unwrap logique est demandé
THEN
  - Le système vérifie metadata_tag avant toute restitution exploitable
  - L'accès est autorisé après validation réussie
AND
  - Le journal d'audit trace la vérification préalable du tag
TEST-ID: TC-NOM-06
Référence spec: INV-276-05, CA-276-09

GIVEN
  - Schéma initial sans colonne metadata_tag
WHEN
  - Migration phase 1 exécutée
THEN
  - La colonne vault_secure.key_envelopes.metadata_tag existe en BYTEA NULL
AND
  - Aucun trigger existant ne change de comportement
TEST-ID: TC-NOM-07
Référence spec: INV-276-05, CA-276-09

GIVEN
  - Phase 1 appliquée
  - Backfill LEGACY terminé
WHEN
  - Migration phase 2 exécutée
THEN
  - metadata_tag devient NOT NULL
  - Les écritures avec metadata_tag absent sont rejetées
AND
  - Les services dépendants restent compatibles après bascule
TEST-ID: TC-NOM-08
Référence spec: INV-276-09, CA-276-02, CA-276-03, CA-276-07

GIVEN
  - Génération des faits Prolog de la branche candidate
WHEN
  - Les faits générés sont inspectés
THEN
  - service(argon2, 'Argon2Service') est présent
  - service_method(argon2, validateParams) est présent
  - entity_column(key_envelope, metadata_tag, bytea) est présent
AND
  - Aucun fait requis n'est manquant
TEST-ID: TC-NOM-09
Référence spec: INV-276-09, INV-276-10, CA-276-01, CA-276-11

GIVEN
  - Faits Prolog générés
  - Règles de contrôle inchangées
WHEN
  - L'audit Prolog est exécuté
THEN
  - Le résultat est 24/24 checks OK
  - Les 21 checks historiquement conformes restent conformes
AND
  - Le rapport d'audit est exporté comme preuve
TEST-ID: TC-NOM-10
Référence spec: INV-276-11, CA-276-09

GIVEN
  - Enveloppe en état LEGACY_NULL_TAG
WHEN
  - Backfill/rotation conforme est appliqué
THEN
  - Transition LEGACY_NULL_TAG -> BOUND_TAG_VALID autorisée
AND
  - La transition est tracée dans le journal d'état
TEST-ID: TC-NOM-11
Référence spec: CA-276-10

GIVEN
  - Migration phase 1 + phase 2 déjà appliquées
WHEN
  - down() est exécuté
THEN
  - La contrainte NOT NULL est supprimée
  - La colonne metadata_tag est supprimée
AND
  - Le schéma revient à l'état contractuel antérieur
TEST-ID: TC-NOM-12
Référence spec: CA-276-13, Q-276-02

GIVEN
  - Système en phase 1
  - Enveloppe LEGACY avec metadata_tag IS NULL
WHEN
  - Requête de lecture de l'enveloppe
THEN
  - L'accès lecture seule est autorisé
  - Aucun flux d'écriture/modification n'est autorisé sur cette enveloppe sans rotation
AND
  - Un warning d'audit indique "LEGACY access in phase1; rotation recommended, not forced"
TEST-ID: TC-NOM-13
Référence spec: INV-276-11, CA-276-09

GIVEN
  - Enveloppe en état LEGACY_NULL_TAG
  - Incohérence de binding détectée (tag invalide calculé lors d'un contrôle d'intégrité)
WHEN
  - Le moteur de vérification évalue l'accès
THEN
  - Transition LEGACY_NULL_TAG -> TAMPERED_TAG_INVALID autorisée
  - L'accès est refusé avec HTTP 422
AND
  - L'état TAMPERED est tracé comme terminal
TEST-ID: TC-INV-01
Référence spec: INV-276-01, CA-276-06

GIVEN
  - Exécution d'un flux de validation Argon2id avec mot de passe fourni par le client
WHEN
  - Le flux complet de validation est audité
THEN
  - Aucune sortie de dérivation de clé serveur n'est produite
  - Aucun artefact de clé dérivée n'est persistant en base
AND
  - Le service se limite à une décision conformité (accept/reject)
TEST-ID: TC-INV-02
Référence spec: INV-276-06, CA-276-08

GIVEN
  - Création d'une enveloppe avec metadata binding
WHEN
  - Les traces de calcul de binding sont inspectées
THEN
  - Le contexte HKDF utilisé est exactement "ProbatioVault::MetadataBinding::v1"
  - La dérivation emploie K_binding et non K_master_user directement
AND
  - Toute dérivation sans ce contexte est rejetée comme non conforme
TEST-ID: TC-INV-03
Référence spec: INV-276-08, CA-276-12

GIVEN
  - Jeux d'artefacts cryptographiques temporaires (clé, fragment, DEK, ReKey) créés en environnement de test
WHEN
  - Les enregistrements persistés sont contrôlés via scans probatoires
THEN
  - Aucun secret temporaire n'apparaît en clair dans l'échantillon contrôlé
  - Les champs cryptographiques observés sont chiffrés (AES-256-GCM ou enveloppe HSM)
AND
  - Toute occurrence en clair détectée entraîne un échec bloquant
TEST-ID: TC-INV-04
Référence spec: H-276-02, INV-276-09

GIVEN
  - Sortie du générateur de faits Prolog de la candidate
  - Cartographie des dépendances checks -> faits
WHEN
  - Vérification de consommation ciblée est exécutée
THEN
  - check_10 consomme service(argon2, 'Argon2Service')
  - check_19 consomme entity_column(key_envelope, metadata_tag, bytea)
  - check_22 consomme service_method(argon2, validateParams)
AND
  - Aucun autre fait non prévu n'est requis pour ces 3 checks

4. Scénarios de test – Cas d’erreur

TEST-ID: TC-ERR-01
Référence spec: E-01, INV-276-02, CA-276-04

GIVEN
  - Requête KDF avec memory=65535
WHEN
  - Validation serveur
THEN
  - Rejet explicite de validation
  - Aucun changement d'état persistant
TEST-ID: TC-ERR-02
Référence spec: E-01, INV-276-02, CA-276-04

GIVEN
  - Requête KDF avec iterations=2
WHEN
  - Validation serveur
THEN
  - Rejet explicite de validation
  - Aucune opération métier poursuivie
TEST-ID: TC-ERR-03
Référence spec: E-03, INV-276-02, CA-276-04

GIVEN
  - Requête KDF sans hashLength
WHEN
  - Validation serveur
THEN
  - Rejet explicite pour paramètre manquant
  - Aucune persistance de requête invalide
TEST-ID: TC-ERR-04
Référence spec: E-04, INV-276-02, CA-276-04

GIVEN
  - Requête KDF avec type=1
WHEN
  - Validation serveur
THEN
  - Rejet explicite de conformité
  - La requête n'atteint pas les flux de chiffrement métier
TEST-ID: TC-ERR-05
Référence spec: E-02, INV-276-03, CA-276-05

GIVEN
  - Requête KDF avec memory=1048577 (au-delà du max)
WHEN
  - Validation serveur
THEN
  - Rejet explicite hors bornes max
  - Aucune mutation d'état métier
TEST-ID: TC-ERR-06
Référence spec: E-05, INV-276-05, CA-276-09

GIVEN
  - Système en phase finale (NOT NULL actif)
  - Tentative d'écriture d'enveloppe sans metadata_tag
WHEN
  - Persistance de l'enveloppe
THEN
  - Rejet de non-conformité de données
  - Aucun enregistrement invalide n'est créé
TEST-ID: TC-ERR-07
Référence spec: E-06, INV-276-07, CA-276-08

GIVEN
  - Enveloppe existante avec metadata_tag altéré
WHEN
  - Accès unwrap logique
THEN
  - Refus immédiat d'accès (HTTP 422, décision < 100 ms)
  - Aucune donnée exploitable n'est restituée
TEST-ID: TC-ERR-08
Référence spec: E-07, INV-276-09, CA-276-01

GIVEN
  - Génération des faits avec omission d'un fait requis
WHEN
  - Audit Prolog exécuté
THEN
  - Audit non conforme (<24/24)
  - Livraison refusée
TEST-ID: TC-ERR-09
Référence spec: E-08, INV-276-10, CA-276-11

GIVEN
  - Build candidate avec baisse d'un check historiquement conforme
WHEN
  - Exécution audit comparatif baseline vs candidate
THEN
  - Régression détectée
  - Livraison refusée
TEST-ID: TC-ERR-10
Référence spec: INV-276-11, CA-276-09

GIVEN
  - Enveloppe en état BOUND_TAG_VALID
WHEN
  - Tentative de transition vers LEGACY_NULL_TAG
THEN
  - Transition rejetée
  - Aucun downgrade sécurité n'est appliqué
TEST-ID: TC-ERR-11
Référence spec: INV-276-11, CA-276-08

GIVEN
  - Enveloppe en état TAMPERED_TAG_INVALID
WHEN
  - Tentative de transition vers tout autre état
THEN
  - Transition interdite (état terminal)
  - Remédiation manuelle explicitement requise hors flux nominal

5. Tests d’invariants (non négociables)

Invariant Test(s) dédiés Observable Commentaire
INV-276-01-zeroknowledge TC-NOM-01, TC-INV-01 Validation acceptée/rejetée sans artefact de dérivation serveur Contrôle de séparation validation vs dérivation
INV-276-02-argon2-minima TC-NOM-01, TC-ERR-01, TC-ERR-02, TC-ERR-03, TC-ERR-04 Minima respectés, sous-minima rejetés Couverture complète des paramètres minimums
INV-276-03-argon2-bounds TC-NOM-02, TC-ERR-05 Bornes max appliquées Vérifie anti-dérive numérique
INV-276-04-config-centralisee TC-NOM-03 Valeurs d'endpoint exactes au contrat Cohérence client/serveur
INV-276-05-metadata-binding TC-NOM-04, TC-NOM-06, TC-NOM-07, TC-ERR-06, TC-NOM-12 metadata_tag présent, 32 bytes, puis obligatoire ; politique LEGACY phase 1 validée Couvre création, migration et transitoire
INV-276-06-separation-cles TC-INV-02 Usage HKDF avec contexte strict Contrôle crypto contractuel
INV-276-07-verify-before-access TC-NOM-05, TC-ERR-07, TC-NEG-01 Vérification préalable et refus sur invalidité (HTTP 422, <100ms) Défense anti-substitution
INV-276-08-envelope-encryption TC-INV-03 Absence de secrets en clair dans contrôles probatoires Couverture probatoire (statut explicite)
INV-276-09-prolog-facts TC-NOM-08, TC-NOM-09, TC-ERR-08, TC-INV-04 Faits requis présents, audit 24/24, consommation check_10/check_19/check_22 vérifiée Passage checks 10/22/19 + robustesse hypothèse H-276-02
INV-276-10-non-regression TC-NOM-09, TC-ERR-09, TC-NR-01 21 checks antérieurs stables avec même statut OK/KO avant/après Blocage livraison en baisse
INV-276-11-state-machine TC-NOM-10, TC-NOM-13, TC-ERR-10, TC-ERR-11, TC-NEG-02 Transitions autorisées/interdites observables État terminal explicitement verrouillé, LEGACY->TAMPERED couvert

6. Tests de non-régression

Test ID Objet Observable Commentaire
TC-NR-01 Stabilité des 21 checks historiquement conformes Comparatif baseline/candidate avec statut exact OK/KO identique pour chaque check Bloquant si régression
TC-NR-02 Stabilité des triggers existants de key_envelopes Même comportement avant/après migration, adossé à baseline instrumentée Toute divergence = anomalie bloquante
TC-NR-03 Compatibilité phase transitoire LEGACY Lecture seule autorisée, écriture non autorisée, warning loggé en phase 1 Valide migration progressive déterministe
TC-NR-04 Réversibilité migration répétable Séquence up/down/up sans dérive de schéma Garantit rollback opérable

7. Tests négatifs et adversariaux

Test ID Entrée invalide / abus Résultat attendu Observable
TC-NEG-01 Substitution inter-device (device_id modifié) Refus immédiat d'accès (HTTP 422, <100ms) Erreur sécurité + absence de restitution
TC-NEG-02 Tentative downgrade BOUND vers LEGACY Rejet de transition interdite Machine à états inchangée
TC-NEG-03 metadata_tag longueur != 32 bytes Rejet de persistance/validation Erreur de conformité de données
TC-NEG-04 Paramètres Argon2 mixtes (min ok + 1 champ hors borne) Rejet systématique Validation atomique de tous les champs
TC-NEG-05 Réponse endpoint config altérée par surcouche locale Non-conformité détectée en test contrat Écart entre contrat attendu et payload
TC-NEG-06 Exécution audit avec règles Prolog modifiées Test invalide, campagne rejetée Contrôle d'intégrité des règles

8. Observabilité requise pour les tests

  • État système : schéma SQL (information_schema/catalogue), état machine (LEGACY_NULL_TAG, BOUND_TAG_VALID, TAMPERED_TAG_INVALID), statut de migration (phase1, phase2).
  • Réponse API : code HTTP (E-06 = 422), code erreur contractuel, payload de validation Argon2, payload endpoint configuration, absence de données exploitables sur refus sécurité.
  • Journal d’audit : événement horodaté de validation Argon2, vérification metadata_tag avant accès, rejet tampering/substitution, transition d'état, résultat audit Prolog.
  • Événement signé / horodaté : entrée d'audit immuable pour opérations sécurité critiques (unwrap refusé, régression détectée, migration structurante).
  • Export probatoire : rapport d'audit Prolog complet (24/24), trace baseline vs candidate, preuve de présence des faits requis, rapport de migration up/down.
  • Mesure temporelle : horodatage t_req/t_decision pour prouver la borne de rejet immédiat < 100 ms sur refus de binding.

9. Règles non testables et exigences probatoires

Règle Raison Impact
INV-276-08 « Aucun secret temporaire en clair en base » (preuve absolue) Une preuve exhaustive d'absence totale sur tous chemins d'exécution n'est pas démontrable par une campagne de tests finie; seuls des contrôles probatoires (scans + échantillonnage + audit) sont automatisables. Majeur (traité via CA-276-12 probatoire)
E-06 mapping sécurité Ambiguïté levée : code contractuel fixé à HTTP 422 ; test pleinement automatisable (incluant borne <100ms). Clos
Politique LEGACY phase 1 Ambiguïté levée : lecture seule autorisée + warning + rotation recommandée non forcée ; oracle de test unique défini. Clos

10. Verdict QA

  • ✅ Testable contractuellement, avec une exigence explicitement probatoire (CA-276-12 / INV-276-08) et non interprétée comme preuve exhaustive.
  • Couverture contractuelle complète des invariants et critères fournie ; ambiguïtés Q-276-02 et Q-276-03 levées, référence épique alignée sur PD-189.
  • Vérification renforcée de robustesse Prolog : alignement strict des 3 faits nouveaux avec check_10, check_19, check_22, et protocole baseline OK/KO avant/après déploiement pour les 21 checks historiques.