PD-262 — Scenarios de tests contractuels¶
1. References¶
- Specification :
PD-262-specification.md - Epic :
EPIC-XX
2. Matrice de couverture¶
| ID Invariant | ID Critere | ID Test | Couverture | Commentaire |
|---|---|---|---|---|
| INV-262-01-fail-closed | CA-04, CA-13 | TC-NOM-04, TC-NOM-09, TC-ERR-02 | Oui | Detection positive et erreur detecteur forcent tampered=true (TC-NOM-09 fusionne ERR-01). |
| INV-262-02-native-authority | CA-01 | TC-INV-02, TC-NEG-03 | Oui | Verifie impossibilite JS d'inhiber/retarder lockout natif. |
| INV-262-03-trigger-coverage | CA-01, CA-02, CA-03 | TC-NOM-01, TC-NOM-02, TC-NOM-03 | Oui | Cold start, foreground, periodique couverts. |
| INV-262-04-single-lockout-state | CA-05 | TC-INV-04, TC-ERR-07 | Oui | Un seul etat lockout, causes distinctes en audit local uniquement. |
| INV-262-05-purge-on-detect | CA-07, CA-19 | TC-NOM-04, TC-ERR-05, TC-ERR-11 | Oui | Purge immediate + gestion purge partielle avec retries bornes. |
| INV-262-06-local-first | CA-10 | TC-NOM-05, TC-ERR-04 | Oui | Reseau non bloquant pour securite locale. |
| INV-262-07-release-gating | CA-11 | TC-NOM-06, TC-ERR-06 | Oui | Matrice environnements contractuelle + flag QA compile-time. |
| INV-262-08-transition-model | CA-05 | TC-NOM-11, TC-INV-08, TC-NR-01 | Oui | Transitions interdites bloquees. |
| INV-262-09-terminal-state | CA-06, CA-17, CA-18 | TC-NOM-08, TC-NR-02, TC-ERR-09, TC-ERR-10 | Oui | LOCKED_PERSISTENT terminal, y compris absence/corruption/interruption. |
| INV-262-10-envelope-encryption | CA-14 | TC-NOM-10, TC-INV-10 | Oui | Aucun secret temporaire en clair au repos. |
| INV-262-11-no-sensitive-telemetry | CA-09, CA-12 | TC-NOM-07, TC-INV-11, TC-NEG-01 | Oui | Telemetrie en allowlist stricte, sans materiau sensible. |
| INV-262-12-state-persistence | CA-06, CA-16 | TC-NOM-08, TC-ERR-08, TC-ERR-09, TC-ERR-10 | Oui | Lockout persiste et se reapplique au redemarrage. |
| n/a | CA-08, CA-15 | TC-NOM-12 | Oui | Blobs deja chiffres non wipes automatiquement, frontiere avec caches crypto respectee. |
3. Scenarios de test - Flux nominaux¶
TEST-ID: TC-NOM-01
Reference spec: INV-262-03, INV-262-07, CA-01
GIVEN
- Build RELEASE sur device iOS reel non compromis
- Journalisation locale active (horodatage monotonic)
WHEN
- Demarrage a froid de l'application
THEN
- Un controle anti-tampering est execute avant tout acces aux secrets applicatifs
- Etat final = MONITORED
AND
- tampered=false
- Trace locale contient trigger=cold_start puis resultat de controle
TEST-ID: TC-NOM-02
Reference spec: INV-262-03, CA-02
GIVEN
- Session active en MONITORED
- Application en background >= 5s
WHEN
- Retour foreground
THEN
- Un re-check anti-tampering est execute avant reprise des operations sensibles
AND
- Compteur de checks incremente de +1 par transition foreground
TEST-ID: TC-NOM-03
Reference spec: INV-262-03, CA-03
GIVEN
- Session active en MONITORED
- detection_interval_sec successivement configure a 45, 20, 75
WHEN
- Le scheduler periodique est lance
THEN
- Intervalle observe = 45s (defaut), puis 30s (clamp min), puis 60s (clamp max)
AND
- Mesure stable sur N>=10 intervalles par configuration
TEST-ID: TC-NOM-04
Reference spec: INV-262-01, INV-262-05, INV-262-08, CA-04, CA-07
GIVEN
- Device reel avec signal de compromission injecte: FRIDA_DETECTED
- Session MONITORED
WHEN
- Un controle anti-tampering s'execute
THEN
- Transition MONITORED -> TAMPERED_SESSION est observee
- tampered=true
- Lockout affiche en <=1s P95 (N>=100 executions)
AND
- Purge immediate executee (memoire sensible, tokens session/refresh, caches crypto, temporaires dechiffres, previews)
- Transition vers LOCKED_PERSISTENT observee
TEST-ID: TC-NOM-05
Reference spec: INV-262-06, CA-10
GIVEN
- Compromission detectee
- Reseau indisponible (mode offline)
WHEN
- Tentative d'emission ANTI_TAMPERING_LOCKOUT
THEN
- Lockout/purge restent effectifs sans delai additionnel
AND
- Aucun rollback securite
- Echec d'emission journalise localement
TEST-ID: TC-NOM-06
Reference spec: INV-262-07, CA-11
GIVEN
- Matrice: DEBUG, SIMULATOR, QA(device reel build flag OFF/ON), RELEASE, TESTFLIGHT, PRODUCTION
WHEN
- Initialisation du module anti-tampering
THEN
- DEBUG + SIMULATOR: module inactif
- RELEASE/TESTFLIGHT/PRODUCTION: module actif
- QA sur device reel: activation strictement conforme au build flag compile
AND
- Aucune mutation runtime (UserDefaults/remote config) ne modifie l'etat d'activation
``` <!-- FIX E-08 -->
```text
TEST-ID: TC-NOM-07
Reference spec: INV-262-11, CA-09, CA-12
GIVEN
- Evenement audit construit apres lockout
WHEN
- Validation schema stricte est appliquee
THEN
- Payload accepte uniquement si champs conformes a §3.3
- Aucun champ hors allowlist (§3.3) n'est present
AND
- Aucune donnee sensible (secret, dump memoire, token) n'apparait dans payload
TEST-ID: TC-NOM-08
Reference spec: INV-262-09, INV-262-12, CA-06, CA-16
GIVEN
- Etat LOCKED_PERSISTENT persiste localement (Keychain)
WHEN
- Redemarrage de l'application
THEN
- Lockout reapplique immediatement
- Aucune transition sortante autorisee
AND
- Etat terminal conserve sur redemarrages successifs
``` <!-- FIX E-04 -->
```text
TEST-ID: TC-NOM-09
Reference spec: INV-262-01, ERR-01, CA-13
GIVEN
- Detecteur force en erreur interne
WHEN
- Controle anti-tampering execute
THEN
- reason_code=DETECTOR_ERROR
- tampered=true
AND
- Lockout applique en fail-closed
- Aucune reprise normale possible
``` <!-- FIX E-10 -->
```text
TEST-ID: TC-NOM-10
Reference spec: INV-262-10, CA-14
GIVEN
- Artefacts cryptographiques temporaires existants (cle, fragment, DEK, ReKey)
WHEN
- Audit de stockage local au repos
THEN
- Aucun artefact temporaire en clair n'est observable
AND
- Chiffrement au repos verifiable (AES-256-GCM ou enveloppe HSM)
TEST-ID: TC-NOM-11
Reference spec: INV-262-08, CA-05
GIVEN
- Etat TAMPERED_SESSION etabli
WHEN
- Tentative explicite de transition vers MONITORED
THEN
- Transition refusee
AND
- Etat reste TAMPERED_SESSION puis LOCKED_PERSISTENT selon sequence
TEST-ID: TC-NOM-12
Reference spec: CA-08, CA-15
GIVEN
- Blobs locaux deja chiffres presents avant detection
- Caches crypto temporaires presents
WHEN
- Lockout et purge sont declenches
THEN
- Les blobs chiffres ne sont pas wipes automatiquement
- Les caches crypto sont purges
AND
- Les donnees persistantes restent inexploitables sans secrets purges
``` <!-- FIX E-03 -->
## 4. Scenarios de test - Cas d'erreur
```text
TEST-ID: TC-ERR-02
Reference spec: ERR-02, INV-262-01
GIVEN
- Budget cold start controle force au depassement >1500ms P95
WHEN
- Controle cold start execute
THEN
- Fail-closed active
- Lockout applique
AND
- Journalisation locale du timeout presente
TEST-ID: TC-ERR-03
Reference spec: ERR-03, CA-12
GIVEN
- Payload audit avec au moins un champ invalide §3.3
WHEN
- Envoi audit tente
THEN
- Envoi rejete
- Lockout conserve
AND
- Log local de rejet present
TEST-ID: TC-ERR-04
Reference spec: ERR-04, INV-262-06
GIVEN
- Backend indisponible
WHEN
- Emission d'evenement lockout
THEN
- Lockout conserve
- Aucun retry bloquant UX
AND
- Securite locale inchangee
TEST-ID: TC-ERR-05
Reference spec: ERR-05, INV-262-05, CA-19
GIVEN
- Un sous-ensemble purge est inaccessible
WHEN
- Purge initiale executee apres detection
THEN
- Lockout maintenu
- Retry purge locale enclenche
AND
- Aucune reprise etat nominal
``` <!-- FIX E-11 -->
```text
TEST-ID: TC-ERR-06
Reference spec: ERR-06, INV-262-07
GIVEN
- Tentative d'activation QA via runtime (UserDefaults/remote config) ou flag QA active en simulateur
WHEN
- Module initialise
THEN
- Anti-tampering reste inactif en simulateur
- Toute mutation runtime est ignoree
AND
- Incoherence journalisee
``` <!-- FIX E-08 -->
```text
TEST-ID: TC-ERR-07
Reference spec: ERR-07, INV-262-04
GIVEN
- Detection concurrente de plusieurs causes
WHEN
- Lockout est declenche
THEN
- Un seul lockout unique est cree
- Cause primaire retenue
AND
- Causes secondaires stockees uniquement en audit local si disponible
TEST-ID: TC-ERR-08
Reference spec: ERR-08, INV-262-12
GIVEN
- Donnee locale de lockout corrompue
WHEN
- Application redemarre
THEN
- Comportement fail-closed
- Etat interprete comme LOCKED_PERSISTENT
AND
- Aucune transition vers etat nominal
```text TEST-ID: TC-ERR-09 Reference spec: ERR-09, CA-17, INV-262-09, INV-262-12
GIVEN - App deja initialisee - Donnee lockout absente au boot - first_launch_clean absent WHEN - Application demarre THEN - Etat force a LOCKED_PERSISTENT (fail-closed) AND - Lockout immediat, aucune transition sortante ```
```text TEST-ID: TC-ERR-10 Reference spec: ERR-10, CA-18, INV-262-09, INV-262-12
GIVEN - Detection compromission en cours - Process tue entre TAMPERED_SESSION et LOCKED_PERSISTENT WHEN - Application redemarre THEN - Etat reconstruit en LOCKED_PERSISTENT AND - Lockout immediat, aucune reprise nominale ```
```text TEST-ID: TC-ERR-11 Reference spec: ERR-05, CA-19, INV-262-05
GIVEN - Purge echoue de facon repetee WHEN - Mecanisme de retry purge s'execute THEN - Maximum 3 retries sont executes - Intervalle de 1s respecte entre retries AND - Apres 3 echecs: abandon retry, lockout maintenu, purge incomplete loggee ```
5. Tests d'invariants (non negociables)¶
| Invariant | Test(s) dedies | Observable | Commentaire |
|---|---|---|---|
| INV-262-01-fail-closed | TC-NOM-04, TC-NOM-09, TC-ERR-02 | tampered=true, lockout, reason_code | Couvre detection + panne detecteur + timeout budget. |
| INV-262-02-native-authority | TC-INV-02, TC-NEG-03 | Lockout natif applique malgre tentative JS | Autorite native verifiee en adversarial. |
| INV-262-03-trigger-coverage | TC-NOM-01, TC-NOM-02, TC-NOM-03 | Traces trigger cold/fg/periodique | Couverture complete des contextes d'execution. |
| INV-262-04-single-lockout-state | TC-INV-04, TC-ERR-07 | Etat unique tampered=true | Distinction causes reservee a l'audit. |
| INV-262-05-purge-on-detect | TC-NOM-04, TC-ERR-05, TC-ERR-11 | Effacement cibles purge + retry borne | Pas de reprise normale en purge partielle. |
| INV-262-06-local-first | TC-NOM-05, TC-ERR-04 | Lockout indep. reseau | Best effort strictement non bloquant. |
| INV-262-07-release-gating | TC-NOM-06, TC-ERR-06 | Matrice environnement conforme | Simulateur toujours inactif + flag QA compile-time. |
| INV-262-08-transition-model | TC-NOM-11, TC-INV-08 | Rejet transitions interdites | Pas de downgrade etat compromis. |
| INV-262-09-terminal-state | TC-NOM-08, TC-NR-02, TC-ERR-09, TC-ERR-10 | Etat terminal conserve | Sorties LOCKED_PERSISTENT -> * interdites. |
| INV-262-10-envelope-encryption | TC-NOM-10, TC-INV-10 | Aucun secret temporaire en clair | Controle au repos local obligatoire. |
| INV-262-11-no-sensitive-telemetry | TC-NOM-07, TC-INV-11, TC-NEG-01 | Payload en allowlist + sans secret | Zero dump memoire/secret telemetrie. |
| INV-262-12-state-persistence | TC-NOM-08, TC-ERR-08, TC-ERR-09, TC-ERR-10 | Lockout persistant au redemarrage | Corruption/absence/interruption traitees fail-closed. |
5.1 Scenarios dedies invariants (Given / When / Then)¶
```text TEST-ID: TC-INV-02 Reference spec: INV-262-02-native-authority
GIVEN - Couche JS instrumentee pour retarder/inhiber l'affichage lockout - Couche native detecte une compromission valide WHEN - Decision lockout est prise cote natif THEN - Lockout est applique sans attendre JS AND - Toute tentative JS de bypass est sans effet observable ```
```text TEST-ID: TC-INV-04 Reference spec: INV-262-04-single-lockout-state
GIVEN - Plusieurs causes de compromission detectees sur la meme session WHEN - Etat de securite est calcule THEN - Un seul etat fonctionnel tampered=true est expose AND - La distinction des causes reste limitee au champ audit (reason_code primaire + secondaires locales) ```
```text TEST-ID: TC-INV-08 Reference spec: INV-262-08-transition-model
GIVEN - Etat courant = TAMPERED_SESSION WHEN - Une transition vers MONITORED est demandee THEN - Transition est refusee AND - Seule transition autorisee reste vers LOCKED_PERSISTENT ```
```text TEST-ID: TC-INV-10 Reference spec: INV-262-10-envelope-encryption
GIVEN - Artefacts cryptographiques temporaires presents sur stockage local WHEN - Verification de conformite chiffrement au repos est executee THEN - Tous les artefacts temporaires sont chiffres (AES-256-GCM ou enveloppe HSM) AND - Aucun secret temporaire en clair n'est lisible ```
```text TEST-ID: TC-INV-11 Reference spec: INV-262-11-no-sensitive-telemetry
GIVEN - Payload telemetrie lockout pret a emission WHEN - Controle allowlist des champs est applique THEN - Seuls les champs de §3.3 sont conserves AND - Tout champ sensible (dump memoire, secret, token) est absent/rejete ```
6. Tests de non-regression¶
| Test ID | Objet | Observable | Commentaire |
|---|---|---|---|
| TC-NR-01 | Interdiction TAMPERED_SESSION -> MONITORED | Transition rejetee | Verrouille toute regression de downgrade. |
| TC-NR-02 | Persistance lockout multi-redemarrages | Lockout immediat a chaque reboot | Protege l'etat terminal. |
| TC-NR-03 | Budget lockout <=1s P95 | P95 mesure <=1s | Evite derive de latence securite. |
| TC-NR-04 | Intervalle periodique clamp [30..60] | Intervalles observes aux bornes | Empeche regressions scheduler. |
| TC-NR-05 | Validation schema payload stricte | Rejet des champs/regex invalides | Evite fuite et rupture backend. |
| TC-NR-06 | Independance reseau | Meme lockout online/offline | Garantit local-first. |
6.1 Scenario detaille non-regression¶
```text TEST-ID: TC-NR-02 Reference spec: INV-262-09, INV-262-12, CA-06
GIVEN - lockout_persistent_flag=true en Keychain - Application redemarree N fois (N>=5) WHEN - Chaque boot est execute en conditions nominales (sans reinstallation) THEN - Lockout est affiche immediatement a chaque redemarrage AND - Aucune transition sortante de LOCKED_PERSISTENT n'est observable ```
7. Tests negatifs et adversariaux¶
| Test ID | Entree invalide / abus | Resultat attendu | Observable |
|---|---|---|---|
| TC-NEG-01 | Payload avec champ supplementaire (memory_dump) | Rejet evenement + lockout conserve | Log local rejet schema |
| TC-NEG-02 | reason_code hors enum / casse invalide | Rejet evenement | Validation regex KO |
| TC-NEG-03 | Tentative JS de neutraliser callback lockout | Echec tentative, lockout natif maintenu | Traces natives prioritaire |
| TC-NEG-04 | Ports Frida invalides (0, 70000) | Ports invalides ignores, decision non degradee | Journal validation port |
| TC-NEG-05 | detection_interval_sec non numerique | Valeur par defaut/clamp applique | Config effective observee |
| TC-NEG-06 | Corruption volontaire stockage lockout | Fail-closed en LOCKED_PERSISTENT | Etat terminal au boot |
| TC-NEG-07 | Injection concurrence multi-causes rapide | Un seul lockout cree | Unicite etat + cause primaire |
8. Observabilite requise pour les tests¶
- Etat systeme : machine d'etats (
MONITORED,TAMPERED_SESSION,LOCKED_PERSISTENT) et horodatages de transition. - Reponse API : statut tentative audit backend (succes/echec/rejet schema), sans coupler securite locale.
- Journal d'audit : traces locales structurees (trigger, reason_code, decision, purge, transition, resultat emission).
- Evenement signe / horodate : horodatage ISO-8601 UTC obligatoire ; signature NON SPECIFIEE dans la specification.
- Export probatoire : export immuable des journaux locaux + captures payload reseau + mesures temporelles (P95).
- Journal retry purge : compteur retries, intervalle observe, motif d'abandon apres 3 echecs.
- Observabilite persistance lockout : lecture metadonnees Keychain (
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly) et marqueurfirst_launch_clean.
9. Regles non testables¶
| Regle | Raison | Impact |
|---|---|---|
| "Ecran lockout non contournable" au sens absolu universel | L'absence de contournement pour toutes techniques futures est non prouvable exhaustivement; testable seulement sur corpus d'attaques defini | Majeur |
| Exhaustivite de la purge ("tous emplacements de caches/temporaires") | La liste exhaustive/versionnee des emplacements n'est pas contractualisee (Q-05) | Majeur |
| Niveau de detail des causes secondaires en audit local | Format/structure non contractualises (Q-04) | Mineur |
| Signature cryptographique de l'evenement audit | Exigee par template d'observabilite mais non definie dans la spec contractuelle | Mineur |
Chemin documentaire final {DOMAINE}/{PD-262-nom} | Metadata manquante (Q-02), bloque uniquement la publication de l'artefact | Mineur |
10. Verdict QA¶
- ⚠️ Testable partiellement (avec reserves listees)
Les exigences fonctionnelles et de securite sont majoritairement testables de facon deterministe. Les reserves portent sur l'exhaustivite formelle de purge, la non-contournabilite absolue et des zones non contractualisees (causes secondaires, signature evenement, metadata de chemin).