PD-276 — PV Envelope : Implémenter Argon2id (RFC 9106) et Metadata Binding¶
1. Contexte¶
L'audit de vérification formelle PV Envelope (Prolog, 24 checks BLOQUANTS) identifie 3 écarts non conformes :
| Check | ID Prolog | Statut | Domaine |
|---|---|---|---|
| 10 | check_9106_argon2_type | KO | RFC 9106 — Argon2Service absent |
| 22 | check_argon2_config | KO | RFC 9106 — Configuration durcie non vérifiable |
| 19 | check_metadata_binding | KO | Point 2 — Colonne metadata_tag/metadata_hash absente |
Les 21 autres checks passent à 100%. La conformité actuelle est à 88% (21/24).
Objectif : Atteindre 24/24 OK (100%) sur pv_envelope_compliance.pl.
2. Architecture Zero-Knowledge (existante)¶
Le modèle PV Envelope repose sur une architecture Zero-Knowledge :
Client (App) :
Password → Argon2id(t=3, m=64MiB, p=4) → K_encryption
K_encryption → AES-256-KW → wrap(K_master_user) → encrypted_envelope
Serveur (Backend) :
Reçoit srpSalt + srpVerifier pré-calculés par le client
Stocke envelopes chiffrées (BYTEA) — JAMAIS accès au password ni à K_encryption
Valide les paramètres SRP (salt, verifier, type KDF = 'Argon2id')
Le serveur n'exécute JAMAIS Argon2id — seul le client dérive K_encryption. Le serveur expose un Argon2Service pour : - Valider que les paramètres KDF déclarés par le client respectent les minimaux OWASP 2024 - Permettre la vérification formelle (check Prolog service(argon2, _)) - Fournir les paramètres de configuration durcis via API
3. Besoins fonctionnels¶
BF-01 : Argon2Service (serveur — validation uniquement)¶
Créer un Argon2Service dans le module crypto qui : - Expose une méthode deriveKey() pour valider/vérifier les paramètres Argon2id côté serveur - Expose les paramètres OWASP 2024 minimaux comme configuration vérifiable : - memory ≥ 64 MiB (65536 KiB) - iterations (time_cost) ≥ 3 - parallelism ≥ 4 - type = 2 (Argon2id) - hashLength = 32 bytes (256 bits) - Valide les paramètres envoyés par le client lors de l'enregistrement/rotation - Rejette toute configuration inférieure aux minimaux
BF-02 : Configuration Argon2id exposée¶
La configuration Argon2id DOIT être : - Centralisée (pas de constantes dispersées) - Vérifiable par le check Prolog check_argon2_config - Exposable via endpoint (pour synchronisation client/serveur) - Compatible avec les paramètres adaptatifs côté client (device-dependent)
BF-03 : Metadata Binding (HMAC anti-substitution)¶
Ajouter un mécanisme de binding cryptographique entre les métadonnées de l'enveloppe et l'enveloppe elle-même : - Colonne metadata_tag (BYTEA) sur key_envelopes - HMAC-SHA256 calculé sur : algorithm || version || envelope_type || device_id - Clé HMAC = K_binding dérivée via HKDF : HKDF(K_master_user, context="ProbatioVault::MetadataBinding::v1") - Vérification du tag à chaque accès (unwrapEnvelope) — rejet si tag invalide - Prévention de substitution : un attaquant ne peut pas déplacer une enveloppe d'un device à un autre
BF-04 : Migration base de données¶
Migration TypeORM pour ajouter la colonne metadata_tag à vault_secure.key_envelopes : - Type : BYTEA (32 bytes HMAC-SHA256) - Nullable initialement (migration progressive des envelopes existantes) - NOT NULL après migration complète (migration en 2 temps)
BF-05 : Mise à jour du fact generator Prolog¶
Mettre à jour _generated-facts.pl (ou le script qui le génère) pour émettre : - service(argon2, 'Argon2Service'). - service_method(argon2, deriveKey). - entity_column(key_envelope, metadata_tag, bytea).
4. Critères d'acceptation¶
CA-01 : Vérification formelle 24/24¶
swipl -l _generated-facts.pl -l pv_envelope_compliance.pl -g "run_audit." -t "halt."
# Résultat attendu : 24/24 OK
CA-02 : Argon2Service fonctionnel¶
- Le service est injectable dans le module crypto
deriveKey()accepte les paramètres client et les valide- Les paramètres inférieurs aux minimaux OWASP sont rejetés avec erreur explicite
- Tests unitaires couvrent les cas limites (paramètres minimaux, insuffisants, absents)
CA-03 : Metadata Binding vérifié¶
- Toute enveloppe créée après migration contient un
metadata_tagvalide unwrapEnvelope()vérifie le tag avant de retourner la clé- Un tag invalide (tampered) provoque un rejet immédiat (erreur 403/security)
- Tests unitaires couvrent : création, vérification, tampering
CA-04 : Non-régression¶
- Les 21 checks existants restent OK
- Les tests existants (AES-KW, HKDF, KeyEnvelope) ne régressent pas
- Le pipeline CI/CD reste vert
CA-05 : Migration réversible¶
- La migration TypeORM est réversible (
down()implémenté) - Fonctionne sur PostgreSQL 16+
5. Contraintes techniques¶
CT-01 : Pas de Argon2id serveur-side¶
Le serveur NE DOIT PAS exécuter Argon2id pour dériver des clés — architecture Zero-Knowledge. Le Argon2Service côté serveur est un service de validation/configuration uniquement.
CT-02 : Séparation de clés (NIST SP 800-108)¶
K_binding DOIT être dérivée via HKDF avec un contexte dédié (ProbatioVault::MetadataBinding::v1), jamais réutiliser K_master_user directement.
CT-03 : Compatibilité Prolog¶
Les 3 checks KO Prolog DOIVENT passer SANS modifier les fichiers .pl de vérification (seuls _generated-facts.pl et le code backend changent).
CT-04 : Aucune lib Argon2 côté serveur¶
Le serveur n'a pas besoin d'installer argon2/argon2id (lib native) puisqu'il ne hash pas. La validation des paramètres est purement logique.
6. Hors scope¶
- Refactoring des 21 checks OK existants
- Tests vectors RFC 3394/5869 (checks de complétude non bloquants)
- Cron de rotation des enveloppes
- Implémentation Argon2id côté client (déjà fait dans
ProbatioVault-app) - Paramètres Argon2 adaptatifs par device (check de complétude, non bloquant)
7. Références¶
- RFC 9106 : https://www.rfc-editor.org/rfc/rfc9106
- OWASP Argon2 : https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
- Règles Prolog :
docs/normes/pv-envelope/formal/pv_envelope_compliance.pl - Audit synthèse :
docs/normes/AUDIT-SYNTHESIS.md - Architecture PV Envelope :
docs/normes/pv-envelope/ - Module crypto existant :
src/modules/crypto/
8. Learnings injectés¶
| Source | Learning | Impact sur PD-276 |
|---|---|---|
| PD-81 | SLA temporels obligatoires pour specs crypto | Documenter les durées de validation/timeout Argon2 |
| PD-55 | Gate 3 crypto nécessite ~3 itérations (formalisme RFC) | Anticiper le formalisme RFC 9106 dès la spec |
| PD-37 | Independent verification needs standalone tools | Le Prolog EST l'outil standalone de vérification |