Aller au contenu

PD-85 — Expression de besoin

1. Contexte et motivation

Un utilisateur victime de cyberharcèlement, revenge porn, menaces ou chantage en ligne se trouve dans une situation de détresse juridique : ses preuves sont dispersées dans ProbatioVault, leur chronologie est floue, et il ne sait pas comment les présenter à un commissariat, un procureur ou un avocat.

ProbatioVault scelle déjà chaque document avec une force probante garantie (ProofEnvelope RFC PV-PROOF-001 v1.1.0, ancrage blockchain, horodatage TSA RFC 3161). Mais cette force probante est fragmentée : chaque preuve existe indépendamment. Il manque le produit fini — un dossier probatoire consolidé, auto-porteur, vérifiable indépendamment, prêt à être remis en main propre.

PD-85 répond au moment charnière : "Je vais porter plainte → je veux un dossier probatoire prêt à déposer."

Pourquoi maintenant

  • PD-84 (offre gratuite B2C-Mineurs) a posé les fondations : dossiers, quotas, catégorie B2C_EVIDENCE_MINOR. L'export est la fonctionnalité verrouillée en gratuit qui justifie le passage Premium.
  • PD-282 (ProofEnvelope seal eIDAS) a finalisé le format d'enveloppe auto-vérifiable. PD-85 agrège ces enveloppes sans en définir de nouveau format.
  • Le cadre juridique français (art. 1366 Code civil, art. 226-1 et suivants Code pénal) rend l'auto-portance du dossier critique : un fichier ZIP dont l'intégrité est vérifiable par un tiers indépendant a une valeur probante supérieure à des captures d'écran.

2. Objectif

Permettre à un utilisateur (ou son représentant légal) de générer un dossier probatoire complet sous forme de ZIP structuré, contenant :

  • Les preuves sélectionnées (fichiers originaux chiffrés côté serveur, déchiffrés côté client)
  • Les ProofEnvelope complètes associées (RFC PV-PROOF-001 v1.1.0)
  • Un manifest global d'intégrité
  • Une chronologie consolidée
  • Un guide de procédure juridique

Périmètre de PD-85 (backend) : validation de cohérence des ProofEnvelope, génération du manifest, chronologie JSON, cohérence RFC, fourniture des URLs signées pour téléchargement, guide statique et README de vérification.

Périmètre de PD-283 (app) : téléchargement des fichiers chiffrés, déchiffrement local (Zero-Knowledge), assemblage du ZIP, calcul du hash SHA3-256 final. PD-283 est une sous-story distincte ; PD-85 ne couvre que le backend.

3. Périmètre V1 — Must-have

3.1 Endpoint d'export

Un endpoint unique POST /exports/complaint-file qui :

  • Accepte une liste de proofIds (export partiel ou total)
  • Vérifie que chaque ProofEnvelope référencée est complète (INV-02 FiveSectionsComplete)
  • Vérifie l'absence de ReKey actif (INV-03 NoActiveReKeys)
  • Vérifie l'absence de secrets (INV-09 NoSecretsInProof)
  • Vérifie la validité de l'envelopeSeal (INV-11 EnvelopeSealValid)
  • Retourne un manifest structuré + les URLs signées pour chaque fichier

3.2 Manifest global (manifest.json)

Document JSON décrivant le contenu du dossier :

Champ Description
exportId UUID unique de l'export
exportedAt Timestamp RFC 3339 UTC
exportedBy UUID de l'utilisateur (+ rôle si représentant légal)
proofCount Nombre de preuves incluses
proofs[] Liste ordonnée : proofId, documentType, originalFilename, sha3_256, proofEnvelopeRef, sealedAt
integrityHash SHA3-256 du manifest lui-même (hors ce champ)
version Version du format manifest (ex: 1.0.0)

3.3 Chronologie consolidée (chronology.json)

Agrégation ordonnée par timestamp de tous les événements probatoires liés aux preuves sélectionnées :

  • Scellement initial du document
  • Ancrage blockchain (tx_id, block)
  • Horodatage TSA
  • Événements de re-scellement éventuels

Format JSON exploitable par l'app pour générer un rendu visuel (PDF basique V1, timeline riche V2).

3.4 Guide de procédure (guide_plainte_france.pdf)

Template statique V1 couvrant :

  • Marche à suivre pour déposer plainte (commissariat, gendarmerie, procureur)
  • Références juridiques (art. 1366 CC, art. 226-1 CP)
  • Comment présenter le dossier ProbatioVault
  • Contacts utiles (3018, e-Enfance, CNIL)

Ce fichier est un asset statique servi par le backend, pas un document généré dynamiquement.

3.5 README de vérification (README_VERIFICATION.txt)

Document texte expliquant à un tiers (avocat, OPJ, expert) comment vérifier indépendamment :

  • L'intégrité du manifest (recalcul SHA3-256)
  • La validité de chaque ProofEnvelope (structure, envelopeSeal)
  • La vérification de l'ancrage blockchain (tx_id publique)
  • La validité de l'horodatage TSA (RFC 3161)

V1 : instructions textuelles. V2 (PD post-MVP) : script de vérification automatisé.

3.6 Sélection de preuves (export partiel)

L'utilisateur doit pouvoir sélectionner un sous-ensemble de ses preuves scellées. Cas d'usage : 200 preuves dans le coffre, plainte concernant 12 incidents spécifiques.

  • L'API accepte une liste explicite de proofIds
  • Si la liste est vide ou absente : erreur 400 (pas d'export total implicite par sécurité)
  • Chaque proofId doit appartenir à l'utilisateur appelant (contrôle RLS)

3.7 Validation ProofEnvelope pré-export

Avant de retourner les données, le backend vérifie systématiquement pour chaque preuve :

Vérification Invariant Comportement si échec
5 sections complètes INV-02 Rejet de la preuve, erreur partielle
Pas de ReKey actif INV-03 Rejet de la preuve
Pas de secrets INV-09 Rejet de la preuve
EnvelopeSeal valide INV-11 Rejet de la preuve
Matériel vérification offline INV-12 Rejet de la preuve

Si toutes les preuves demandées sont rejetées : erreur 422 avec détail par preuve. Si certaines preuves sont rejetées : réponse partielle avec liste des rejets et motifs.

4. Hors périmètre V1 — Reporté en V2

Fonctionnalité Raison du report Story V2
Script de vérification automatisé Complexité (validation RFC 3161, chaînes cert, OCSP/CRL, Merkle, HSM) — remplacé par README_VERIFICATION.txt À créer
Chronologie PDF riche Timeline graphique, résumé juridique, annotations — nécessite moteur de rendu PDF côté app PD-283 V2
Export ZIP côté serveur Violation Zero-Knowledge — le serveur ne doit jamais voir les documents en clair Définitivement exclu
Multi-langue du guide V1 français uniquement (juridiction cible) À créer
Notification automatique à l'avocat Partage sécurisé avec tiers — nécessite mécanisme de délégation À créer

5. Use cases principaux

UC-01 : Export nominal (adulte, Premium)

  1. L'utilisateur Premium sélectionne 5 preuves scellées dans son dossier
  2. L'app appelle POST /exports/complaint-file avec les 5 proofIds
  3. Le backend vérifie la cohérence RFC de chaque ProofEnvelope
  4. Le backend génère le manifest.json et chronology.json
  5. Le backend retourne le manifest + les URLs signées (S3 pré-signées, expiration courte)
  6. L'app télécharge les fichiers chiffrés via les URLs
  7. L'app déchiffre localement (Zero-Knowledge)
  8. L'app assemble le ZIP structuré avec le guide et le README
  9. L'app calcule le hash SHA3-256 final du ZIP
  10. L'utilisateur reçoit le ZIP prêt à transmettre

Identique à UC-01, avec ajouts : - Le représentant légal initie l'export pour le compte du mineur - Le manifest inclut le Mandate Evidence (preuve de mandat parental) - Le manifest inclut le Dual Validation Evidence (double validation mineur/tuteur) - Si un accès judiciaire a été déclenché : inclusion du ReKey Lifecycle Evidence

UC-03 : Export partiel avec preuves rejetées

  1. L'utilisateur sélectionne 10 preuves
  2. 2 preuves échouent à la validation (section manquante, ReKey actif)
  3. Le backend retourne un manifest pour les 8 preuves valides
  4. La réponse inclut un tableau rejectedProofs avec motif par preuve
  5. L'app informe l'utilisateur et propose de continuer avec les preuves valides

UC-04 : Export bloqué (utilisateur gratuit)

  1. L'utilisateur gratuit tente d'exporter
  2. Le backend vérifie le plan_type via CapabilityState
  3. Retour 403 avec message explicite : export réservé au plan Premium
  4. L'app affiche le bouton grisé avec CTA Premium (conformément à PD-84)

UC-05 : Export bloqué (toutes preuves invalides)

  1. L'utilisateur sélectionne 3 preuves
  2. Les 3 échouent à la validation (ex: ReKey actif sur toutes)
  3. Retour 422 avec détail des rejets
  4. L'app affiche les motifs et conseille d'attendre la fin des opérations en cours

UC-06 : Export avec limite de taille

  1. L'utilisateur sélectionne des preuves dont le total dépasse 1 GB
  2. Le backend détecte le dépassement lors du calcul du manifest
  3. Retour 413 avec le total estimé et la limite
  4. L'app propose de réduire la sélection

6. Architecture haut niveau

6.1 Flux de données

┌──────────┐     POST /exports/complaint-file      ┌──────────────┐
│          │ ──────────────────────────────────────> │              │
│   App    │                                        │   Backend    │
│ (PD-283) │ <────────────────────────────────────── │   (PD-85)    │
│          │     { manifest, chronology, signedUrls }│              │
│          │                                        │              │
│          │     GET signedUrl (x N preuves)         │   S3 WORM   │
│          │ ──────────────────────────────────────> │              │
│          │ <────────────────────────────────────── │              │
│          │     fichiers chiffrés                   │              │
└──────────┘                                        └──────────────┘
     │ Déchiffrement local (K_doc)
     │ Assemblage ZIP
     │ Hash SHA3-256
  ZIP final

6.2 Responsabilités

Composant Responsabilité Justification
Backend (PD-85) Validation RFC, manifest, chronologie, URLs signées, guide statique Cohérence probatoire, contrôle d'accès
App (PD-283) Téléchargement, déchiffrement, assemblage ZIP, hash final Zero-Knowledge : le serveur ne voit jamais le clair
S3 WORM Stockage des fichiers chiffrés Immuabilité (PD-4, PD-44)

6.3 Contrat API

Request :

POST /exports/complaint-file
Authorization: Bearer <token>

{
  "proofIds": ["uuid-1", "uuid-2", "uuid-3"],
  "includeGuide": true,
  "includeChronology": true
}

Response 200 :

{
  "exportId": "uuid-export",
  "manifest": {
    "exportId": "uuid-export",
    "exportedAt": "2026-03-08T14:30:00.000Z",
    "exportedBy": "uuid-user",
    "proofCount": 3,
    "proofs": [
      {
        "proofId": "uuid-1",
        "documentType": "IMAGE",
        "originalFilename": "capture-harcelement-01.png",
        "sha3_256": "abc123...",
        "proofEnvelopeRef": "envelope-uuid-1",
        "sealedAt": "2026-02-15T10:00:00.000Z"
      }
    ],
    "integrityHash": "def456...",
    "version": "1.0.0"
  },
  "chronology": {
    "events": [
      {
        "timestamp": "2026-02-15T10:00:00.000Z",
        "type": "DOCUMENT_SEALED",
        "proofId": "uuid-1",
        "details": { "anchorTxId": "0x...", "tsaToken": "..." }
      }
    ]
  },
  "signedUrls": [
    {
      "proofId": "uuid-1",
      "url": "https://s3.../...",
      "expiresAt": "2026-03-08T15:00:00.000Z"
    }
  ],
  "guideUrl": "https://s3.../guide_plainte_france.pdf",
  "readmeVerification": "...(contenu texte inline)...",
  "rejectedProofs": []
}

Codes d'erreur :

Code Condition
400 proofIds vide ou absent
403 Utilisateur en plan FREE
404 proofId inexistant ou n'appartenant pas à l'utilisateur
413 Taille totale des preuves > MAX_BACKEND_EXPORT (1 GB)
422 Toutes les preuves demandées sont rejetées

7. Invariants et contraintes

7.1 Invariants hérités (RFC PV-PROOF-001)

ID Règle Impact PD-85
INV-02 FiveSectionsComplete Export bloqué si non respecté
INV-03 NoActiveReKeys Export bloqué si ReKey en cours
INV-07 ImmutableAfterFinalize Aucune altération post-export autorisée
INV-09 NoSecretsInProof Vérification automatique avant inclusion
INV-11 EnvelopeSealValid Validation obligatoire du sceau HSM
INV-12 OfflineVerificationMaterialSufficient Matériel de vérification offline complet

7.2 Invariants propres à PD-85

ID Règle Justification
INV-85-01 Le backend ne déchiffre JAMAIS un document exporté Zero-Knowledge constitutionnel
INV-85-02 Chaque export génère un exportId unique (UUID v4) Traçabilité, non-répudiation
INV-85-03 Le manifest inclut un integrityHash SHA3-256 calculé sur le manifest complet (hors ce champ) Auto-vérifiabilité
INV-85-04 Les URLs signées expirent en ≤ 30 minutes Fenêtre d'exposition minimale
INV-85-05 L'export est journalisé dans l'audit log WORM Traçabilité complète
INV-85-06 Un export ne modifie aucune ProofEnvelope existante Immutabilité des preuves (INV-07)
INV-85-07 Taille maximale d'un export : 1 GB (somme des fichiers chiffrés) UX + contraintes réseau mobile

7.3 Contraintes produit

  • Objectif UX : taille ZIP < 100 MB pour un usage courant (recommandation, pas blocage)
  • Limite technique : MAX_BACKEND_EXPORT = 1 GB (blocage serveur)
  • Expiration URLs : ≤ 30 minutes (configurable via variable d'environnement)
  • Pas de stockage serveur du ZIP : le ZIP n'est assemblé que côté client

8. Cas spécifique B2C-Mineurs

8.1 Preuves additionnelles

Lorsque le compte est de type MINOR ou que l'export est initié par un LEGAL_GUARDIAN :

Élément additionnel Condition d'inclusion Description
Mandate Evidence Toujours (si mandat parental existe) Preuve du lien tuteur-mineur
Dual Validation Evidence Toujours (si double validation a eu lieu) Traces de la double validation mineur/représentant
ReKey Lifecycle Evidence Si accès judiciaire déclenché Historique des opérations de ReKey pour accès judiciaire

8.2 Règles spécifiques

  • Le représentant légal peut exporter pour le compte du mineur sans que le mineur initie l'action
  • Le mineur peut exporter avec validation du représentant légal (double validation PD-84)
  • Le manifest indique explicitement qui a initié l'export (exportedBy) et en quelle qualité (role)
  • Les preuves additionnelles B2C-Mineurs sont incluses automatiquement si elles existent — pas de sélection manuelle

9. Dépendances

9.1 Dépendances amont (requises)

Story Composant Statut Impact
PD-282 ProofEnvelope seal eIDAS DONE Format d'enveloppe, envelopeSeal, verificationMaterial
PD-84 Offre gratuite B2C-Mineurs DONE Modèle de données (ProbatoryFolder, CapabilityState), contrôle Premium
PD-60 Document upload DONE Documents scellés disponibles
PD-63 Document download DONE Téléchargement sécurisé
PD-79 Extension catégorie documentaire DONE Catégorie B2C_EVIDENCE_MINOR
PD-55 Worker ancrage blockchain DONE Ancrage Merkle + tx blockchain
PD-39 TSA RFC3161 DONE Horodatage certifié
PD-4 OVH Buckets WORM DONE Stockage S3 des fichiers chiffrés
PD-44 Object Lock WORM DONE Immuabilité des fichiers
PD-46 Secure download DONE URLs pré-signées S3

9.2 Dépendances aval (consommatrices)

Story Composant Description
PD-283 App — assemblage ZIP local Consomme l'API PD-85, déchiffre et assemble le ZIP

9.3 RFC et normes

Référence Usage
RFC PV-PROOF-001 v1.1.0 Format ProofEnvelope
RFC 3161 Horodatage TSA
RFC 8785 (JCS) Canonicalisation JSON pour vérification
Art. 1366 Code civil Valeur probante de l'écrit électronique

10. Critères d'acceptation préliminaires

Fonctionnels

  • POST /exports/complaint-file retourne un manifest valide pour une liste de preuves valides
  • L'export partiel fonctionne (sélection de N preuves parmi M)
  • Les preuves invalides sont rejetées individuellement avec motif explicite
  • L'export est bloqué pour les utilisateurs en plan FREE (403)
  • L'export est bloqué si toutes les preuves sont invalides (422)
  • L'export est bloqué si la taille dépasse 1 GB (413)
  • Le manifest inclut un integrityHash SHA3-256 vérifiable
  • La chronologie est ordonnée par timestamp et couvre tous les événements probatoires
  • Le guide statique et le README de vérification sont inclus dans la réponse

Sécurité

  • Le backend ne déchiffre aucun document (Zero-Knowledge)
  • Les URLs signées expirent en ≤ 30 minutes
  • Le contrôle RLS empêche l'export de preuves d'un autre utilisateur
  • L'export est journalisé dans l'audit log WORM
  • Aucune ProofEnvelope n'est modifiée par l'opération d'export
  • Les invariants INV-02, INV-03, INV-09, INV-11, INV-12 sont vérifiés avant inclusion

B2C-Mineurs

  • Le représentant légal peut exporter pour le compte d'un mineur
  • Les preuves additionnelles (Mandate, Dual Validation, ReKey) sont incluses automatiquement
  • Le manifest indique l'identité et le rôle de l'exporteur

Non-fonctionnels

  • Temps de réponse de l'API < 5s pour 50 preuves (P95)
  • L'export de 100 preuves ne dépasse pas 10s (P95)
  • Le format du manifest est versionné (version: "1.0.0") pour évolutions futures