diff --git a/deltas/0.2.4/pre.009-fix.001.md b/deltas/0.2.4/pre.009-fix.001.md new file mode 100644 index 0000000..0b03c45 --- /dev/null +++ b/deltas/0.2.4/pre.009-fix.001.md @@ -0,0 +1,199 @@ + + + +# Delta `0.2.4-pre.009-fix.001` — enrichissement du prompt `0.2.5` Wallet + +## Type + +Fix **documentation-only**. + +Aucun changement Rust, Cargo, runtime, test, fixture HTTP ou contrat `0.2.4` n'est introduit. + +Le `workspace.package.version` reste : + +```text +0.2.4-pre.9 +``` + +Le delta historique : + +```text +deltas/0.2.4/pre.009.md +``` + +reste inchangé. + +## Motif + +Après validation de la candidate `0.2.4-pre.009`, le brainstorming préparatoire à `0.2.5 — Wallet foundation` a précisé des exigences importantes qui doivent être présentes dans le prompt de reprise avant l'ouverture de la nouvelle release. + +Le prompt précédent couvrait déjà : + +```text +audit crypto actuel +KDF / AEAD / CSPRNG +format versionné +persistence atomique +secret memory handling +signature +import/export +``` + +mais ne formalisait pas encore suffisamment : + +```text +interopérabilité externe obligatoire du .kspwallet +threat model de bruteforce offline +absence de secret KSP/pepper propriétaire nécessaire à la récupération +Pubkey/alias/notes invisibles wallet verrouillé +alias interne indépendant du filename +notes protégées +sémantique exacte du format_version +paramètres KDF sérialisés +distinction éventuelle format_version / payload_version +deux capacités indépendantes VIEW / OWNER +architecture key slots / key wrapping +rotation indépendante des passwords sans changement de keypair +OWNER capable de recréer VIEW sans ancien password VIEW +question du read-only cryptographique de VIEW +test vectors publics pour implémentations externes +``` + +## Prompt mis à jour + +`prompts/010-V0_2_5_START_PROMPT.md` passe : + +```text +version 1 -> version 2 +``` + +### Interopérabilité + +Le `.kspwallet` doit être complètement spécifiable en dehors de `ksp-wallet-lib`. + +La sécurité ne doit pas dépendre : + +```text +du secret du format +d'un pepper global KSP +d'une donnée cachée dans le binaire +``` + +Une future spécification `KSPWALLET_V1` et des vecteurs de test publics doivent permettre l'écriture d'un déchiffreur compatible externe. + +### Threat model + +Le prompt impose désormais l'audit explicite de l'attaque offline : + +```text +copie du fichier +-> essais de passwords sans serveur/rate-limit +-> KDF coûteux mais password faible toujours attaquable +``` + +et sépare les garanties apportées par : + +```text +crypto du fichier +capabilities/types KSP +filesystem +éventuelle ancre de confiance externe +``` + +### Metadata protégée + +Sans VIEW ou OWNER, le fichier ne doit pas exposer par défaut : + +```text +Pubkey +alias +notes +``` + +L'alias reste indépendant du filename. + +Les notes sont des metadata protégées, lisibles par VIEW/OWNER et administrables par OWNER. + +### Versionnement + +`format_version` est explicitement défini comme une version du **format**, non comme un compteur d'éditions. + +Il ne change pas pour : + +```text +rotation password +modification alias +modification notes +réécriture atomique sans changement de format +``` + +Un éventuel `payload_version` doit être séparé uniquement si le schéma protégé nécessite réellement une évolution indépendante. + +### Capacités VIEW / OWNER + +Le modèle cible devient : + +```text +VIEW: + lire Pubkey/alias/notes + +OWNER: + tout VIEW + signer + modifier alias/notes + gérer VIEW + changer OWNER +``` + +Invariants : + +```text +VIEW et OWNER indépendants +OWNER ne dépend jamais de VIEW +VIEW compromis != secret Solana compromis +VIEW compromis != OWNER compromis +OWNER peut recréer/supprimer VIEW sans ancien VIEW password +rotation VIEW/OWNER != changement de keypair +``` + +Le prompt demande d'étudier une architecture de : + +```text +content keys +key wrapping +key slots indépendants +``` + +plutôt qu'un double chiffrement naïf. + +### Read-only de VIEW + +L'API KSP doit obligatoirement rendre VIEW read-only. + +Le gate `pre.001` doit aussi décider si V1 renforce cette propriété cryptographiquement contre un détenteur VIEW malveillant. + +La préférence est de viser cette propriété si elle reste propre, interopérable et raisonnablement simple, avec une autorité metadata OWNER distincte de la keypair Solana sauf justification contraire. + +Le prompt conserve explicitement la limite suivante : + +```text +aucune information de confiance stockée uniquement dans le fichier +ne peut empêcher un attaquant ayant accès en écriture +de remplacer entièrement ce fichier par un autre fichier valide +``` + +## Fichiers + +Modifié : + +```text +prompts/010-V0_2_5_START_PROMPT.md +``` + +Ajouté : + +```text +deltas/0.2.4/pre.009-fix.001.md +``` + +Aucun autre fichier n'est modifié. diff --git a/prompts/010-V0_2_5_START_PROMPT.md b/prompts/010-V0_2_5_START_PROMPT.md index 154d4d9..a1c683f 100644 --- a/prompts/010-V0_2_5_START_PROMPT.md +++ b/prompts/010-V0_2_5_START_PROMPT.md @@ -1,5 +1,5 @@ - + # Prompt de démarrage `0.2.5` — Wallet foundation @@ -33,7 +33,7 @@ La première tranche est : 0.2.5-pre.001 ``` -et commence obligatoirement par **audit actuel + reprise de l'héritage utile + brainstorming + sizing** avant toute implémentation cryptographique ou format lourd. +et commence obligatoirement par **audit actuel + reprise de l'héritage utile + brainstorming + threat model + sizing** avant toute implémentation cryptographique ou format lourd. ## 2. Mission de `0.2.5` @@ -54,17 +54,24 @@ Le Wallet doit fournir au minimum les capacités conceptuelles suivantes : ```text création ouverture / déverrouillage -identité publique / Pubkey +identité publique après autorisation protection du secret signature -changement de mot de passe sans changement de keypair +capacité VIEW indépendante +capacité OWNER indépendante +changement/rotation des mots de passe sans changement de keypair +alias interne indépendant du filename +notes internes protégées persistence atomique / no-clobber -projection publique sûre +projection sûre selon capacité import/export extensible +interopérabilité externe documentée du format natif ``` La release doit aboutir à une bibliothèque utilisable **sans Config, sans Transport, sans Tauri et sans execution policy**. +Le format `.kspwallet` ne doit pas dépendre de l'existence future de KSP pour rester récupérable. Une implémentation externe conforme doit pouvoir le lire/déchiffrer avec les bons secrets d'accès à partir d'une spécification publique et de vecteurs de test. + ## 3. Frontières architecturales déjà décidées La direction attendue reste : @@ -109,7 +116,21 @@ Les décisions suivantes ne doivent pas être rouvertes sans raison nouvelle et 7. Wallet n'a pas besoin de Transport pour son cœur ; 8. l'import/export doit rester extensible, mais seules les conversions réellement nécessaires doivent être implémentées ; 9. les futurs scénarios doivent pouvoir utiliser de vrais `.kspwallet`, y compris des wallets dédiés Devnet/tests ; -10. Wallet Desk arrive séparément en `0.2.6`. +10. Wallet Desk arrive séparément en `0.2.6` ; +11. le format `.kspwallet` doit être **documenté et implémentable en dehors de KSP** ; la sécurité ne doit jamais dépendre de la confidentialité du format ; +12. aucun secret global KSP, `pepper` propriétaire ou donnée cachée dans le logiciel ne doit être nécessaire pour récupérer un `.kspwallet` autonome ; +13. la Pubkey, l'alias et les notes ne sont **pas lisibles wallet verrouillé** par défaut ; +14. l'alias est une identité humaine interne au wallet et reste indépendant du nom du fichier ; +15. les notes sont des metadata internes protégées et peuvent être ajoutées/modifiées/supprimées par la capacité OWNER ; +16. le `format_version` décrit **la version du format**, pas un compteur d'éditions, de changements de mot de passe ou de metadata ; +17. les paramètres cryptographiques nécessaires au déchiffrement doivent être sérialisés dans le fichier afin que les anciens wallets restent lisibles après durcissement futur des paramètres par défaut ; +18. le modèle cible possède deux capacités indépendantes : + - `VIEW` : lecture Pubkey/alias/notes ; + - `OWNER` : toutes les capacités VIEW + signature + administration du wallet ; +19. `OWNER` ne doit jamais dépendre de `VIEW` : la perte du password VIEW ne doit pas empêcher l'ouverture, la signature ou l'administration avec OWNER ; +20. un compromis du password VIEW ne doit pas permettre d'obtenir le secret Solana ni une clé permettant de dériver/déverrouiller la capacité OWNER ; +21. la rotation d'un password VIEW ou OWNER ne doit pas modifier la keypair Solana ; +22. OWNER doit pouvoir remplacer/supprimer/recréer la capacité VIEW sans connaître l'ancien password VIEW. Références KSP à relire avant le plan : @@ -127,7 +148,7 @@ docs/validation/002-V0_2_0_SERIES_PLANNING.md docs/IDEAS.md ``` -## 5. `pre.001` — audit officiel actuel + brainstorming + sizing +## 5. `pre.001` — audit officiel actuel + brainstorming + threat model + sizing `pre.001` ne doit pas démarrer directement par le chiffrement du fichier. @@ -135,7 +156,7 @@ Il doit d'abord produire un plan Wallet dédié et répondre explicitement aux q ### 5.1 Héritage bot3/bot2 -Réauditer les implémentations historiques réellement disponibles de Wallet afin de classer chaque idée en : +Réaduiter les implémentations historiques réellement disponibles de Wallet afin de classer chaque idée en : ```text réutiliser conceptuellement @@ -162,7 +183,41 @@ Examiner notamment, lorsqu'ils existent dans les sources historiques : Ne pas copier automatiquement une dépendance, un format ou une primitive cryptographique uniquement parce qu'elle existait dans bot3. -### 5.2 Primitives Solana actuelles +### 5.2 Threat model du `.kspwallet` + +Le plan doit documenter explicitement au minimum les scénarios suivants : + +```text +attaquant obtient une copie du fichier .kspwallet +attaquant peut lancer des essais de password hors ligne sans limite serveur +attaquant connaît intégralement la spécification du format +attaquant connaît les algorithmes et paramètres KDF/AEAD stockés dans le fichier +attaquant connaît seulement le password VIEW +attaquant connaît seulement le password OWNER +attaquant peut modifier partiellement le fichier +attaquant peut remplacer totalement le fichier sur le filesystem +``` + +Conclusions à préserver : + +- le format ouvert/documenté n'est pas une faiblesse de sécurité ; +- un wallet protégé uniquement par password reste attaquable **offline** par dictionnaire/bruteforce ; +- le KDF rend chaque tentative coûteuse mais ne transforme pas un mauvais password en secret à forte entropie ; +- le salt doit empêcher la réutilisation efficace de précalculs entre wallets, pas être traité comme un secret ; +- aucun rate-limit applicatif KSP ne protège un fichier déjà volé ; +- la résistance au remplacement total d'un fichier ne peut pas être promise uniquement par une information de confiance stockée dans ce même fichier ; +- les garanties de `VIEW read-only` doivent distinguer clairement la sécurité de l'API KSP de la résistance cryptographique à un détenteur VIEW malveillant. + +Le plan doit déterminer quelles garanties sont assurées : + +```text +par la cryptographie du fichier +par les types/capabilities de ksp-wallet-lib +par les permissions/persistence filesystem +par une éventuelle ancre de confiance externe future +``` + +### 5.3 Primitives Solana actuelles Réaduiter les crates low-level Solana réellement nécessaires pour : @@ -182,60 +237,281 @@ Objectifs : L'audit doit vérifier les versions réellement actuelles au moment de la session, pas recopier les versions historiques bot3. -### 5.3 Protection cryptographique du fichier +### 5.4 Protection cryptographique du fichier Comparer les primitives cryptographiques maintenues et adaptées au besoin réel du `.kspwallet`. Le plan doit décider explicitement, avec justification : ```text -KDF mot de passe +KDF password AEAD / chiffrement authentifié CSPRNG +key wrapping / envelope encryption gestion salt / nonce paramètres KDF sérialisés -versionnement du format +format_version +payload_version si distinct et justifié stratégie de migration zeroization / secret memory handling +authentification OWNER des metadata si VIEW doit être cryptographiquement read-only ``` Ne pas inventer de cryptographie KSP. -Ne pas figer dans ce prompt un choix tel qu'Argon2id, scrypt, AES-GCM ou XChaCha20-Poly1305 sans réaudit actuel ; `pre.001` doit sélectionner les primitives selon sécurité, maintenance, portabilité, dépendances et compatibilité Rust réellement observées. +La shortlist à réauditer inclut au minimum : -### 5.4 Modèle de fichier `.kspwallet` +```text +KDF: + Argon2id favori actuel à confirmer + scrypt alternative memory-hard + PBKDF2 compatibilité/legacy, pas favori sans raison + +AEAD: + XChaCha20-Poly1305 + AES-256-GCM-SIV + autres alternatives seulement si elles apportent un avantage documenté + +Secret memory: + zeroize + secrecy ou types KSP simples basés sur zeroize +``` + +Cette shortlist n'est pas un verrouillage. `pre.001` doit vérifier l'état réel des crates, audits, maintenance, risques de nonce, portabilité, interopérabilité et dépendances avant décision. + +Le KDF ne doit pas recevoir des paramètres copiés arbitrairement d'un RFC ou d'un ancien projet. Les paramètres de création par défaut doivent être benchmarkés sur les machines cibles et conçus pour pouvoir être durcis plus tard sans rendre les wallets existants illisibles. + +### 5.5 Architecture de clés et capacités `VIEW` / `OWNER` + +Le design ne doit pas chiffrer naïvement « tout le wallet avec deux passwords successifs ». + +Le plan doit étudier une architecture de **content keys + key slots**, conceptuellement de la forme : + +```text +password VIEW + -> KDF VIEW + -> VIEW key slot + -> accès metadata seulement + +password OWNER + -> KDF OWNER + -> OWNER key slot + -> root/owner capability + -> accès metadata + -> accès secret Solana + -> signature + -> administration / rotations +``` + +Invariants obligatoires : + +```text +VIEW et OWNER ont des KDF/salts indépendants +OWNER ne dépend jamais de VIEW +VIEW compromis != secret Solana compromis +VIEW compromis != OWNER compromis +OWNER peut recréer/supprimer VIEW sans ancien password VIEW +rotation VIEW != rechiffrement ou changement de keypair obligatoire +rotation OWNER != changement de keypair +``` + +Le plan doit décider si les key slots sont sérialisés sous une structure générique telle que : + +```text +key_slots: + - role: view + - role: owner +``` + +afin de conserver une extensibilité future sans implémenter dès V1 des rôles tels que recovery/hardware/automation. + +#### `VIEW` réellement read-only + +Dans l'API publique KSP, `VIEW` est obligatoirement read-only : + +```text +VIEW: + lire Pubkey + lire alias + lire notes + +VIEW -X-> signer +VIEW -X-> modifier alias/notes +VIEW -X-> changer passwords +VIEW -X-> exporter le secret +``` + +Cependant une clé symétrique permettant de déchiffrer un compartiment peut généralement aussi servir à produire un nouveau ciphertext valide pour ce même compartiment. + +`pre.001` doit donc trancher explicitement le niveau recherché : + +```text +A. read-only garanti seulement par les capabilities/types KSP +B. read-only également renforcé cryptographiquement contre un détenteur VIEW malveillant +``` + +La préférence de conception est **B si elle peut être réalisée proprement et interopérablement sans complexité disproportionnée**. + +Si B est retenu, étudier une authentification des metadata contrôlée par OWNER, idéalement avec une autorité de contrôle distincte de la keypair Solana sauf justification contraire. Ne pas réutiliser automatiquement la clé de signature blockchain comme clé d'administration du format. + +La documentation doit rester honnête : même une metadata correctement authentifiée ne peut pas, à elle seule, empêcher quelqu'un ayant accès en écriture au filesystem de remplacer entièrement le fichier par un autre fichier valide. + +### 5.6 Modèle de fichier `.kspwallet` Le plan doit définir les invariants du format avant l'API de persistence. -Le format doit pouvoir identifier sans ambiguïté au minimum : +Le format doit séparer conceptuellement : ```text -format/version KSP -algorithmes/paramètres nécessaires au déchiffrement -salt/nonce ou équivalents -payload protégé -metadata publique strictement autorisée -intégrité/authenticité +enveloppe publique minimale +key slots / paramètres nécessaires au déverrouillage +compartiment metadata protégé +compartiment secret protégé ``` +L'enveloppe publique verrouillée ne doit exposer par défaut que ce qui est strictement nécessaire à l'interprétation/déverrouillage, par exemple : + +```text +magic +format_version +suite/identifiants crypto +paramètres KDF +salts +nonces ou équivalents +wrapped keys / key slots +ciphertexts +``` + +Ne doivent pas être lisibles sans VIEW ou OWNER : + +```text +Pubkey +alias +notes +secret Solana +``` + +Le compartiment metadata déverrouillé par VIEW ou OWNER doit pouvoir contenir au minimum : + +```text +Pubkey +alias optionnel +notes optionnelles +``` + +L'alias : + +```text +est indépendant du filename +peut être modifié par OWNER +peut être absent +``` + +Les notes : + +```text +peuvent être ajoutées/modifiées/supprimées par OWNER +sont lisibles par VIEW et OWNER +ne doivent jamais être exposées wallet verrouillé +doivent avoir des limites de taille explicites +``` + +Le compartiment secret n'est accessible qu'à OWNER et contient le matériau nécessaire aux opérations de signature. + Questions à trancher : - JSON, binaire ou enveloppe hybride ; - magic/version ; - représentation de la Pubkey ; -- metadata publique lisible wallet verrouillé ou non ; -- place de l'alias ; +- encodages exacts des salts/nonces/ciphertexts ; +- schéma des key slots ; - champs obligatoires/optionnels ; -- limites de taille ; +- limites de taille globales et par champ ; - politique unknown-version ; - politique unknown-field ; - migrations futures ; -- checksum séparé utile ou redondant avec AEAD ; -- compatibilité endianness/encodage si format binaire. +- checksum séparé utile ou redondant avec AEAD/authentification ; +- compatibilité endianness/encodage si format binaire ; +- canonicalisation nécessaire si des signatures/authentifications couvrent des structures sérialisées. -Le format doit être documentable et testable sans exposer le secret. +### 5.7 Versionnement et migration -### 5.5 Secret en mémoire +Le plan doit distinguer clairement : + +```text +format_version +``` + +de tout historique de modification. + +`format_version` signifie : + +```text +comment parser/interpréter ce fichier +``` + +et **ne doit pas être incrémenté** pour : + +```text +changement de password +changement d'alias +ajout/modification/suppression de note +réécriture atomique sans changement de schéma/crypto +``` + +Étudier séparément un éventuel : + +```text +payload_version +``` + +uniquement si l'évolution du contenu protégé justifie une frontière distincte de l'enveloppe. + +La stratégie doit permettre par exemple : + +```text +wallet ancien: + paramètres KDF plus faibles mais sérialisés + +nouveau défaut KSP: + paramètres KDF plus forts + +=> les deux restent lisibles +``` + +Toute migration automatique future doit être explicite, testable et atomique. + +### 5.8 Interopérabilité externe obligatoire + +Le `.kspwallet` ne doit pas être un format « lisible seulement par ksp-wallet-lib ». + +La release doit prévoir une spécification indépendante du code, par exemple : + +```text +docs/formats/KSPWALLET_V1.md +``` + +avec au minimum : + +- grammaire/structure exacte ; +- suites crypto et paramètres ; +- encodages ; +- dérivation/wrapping ; +- données authentifiées ; +- ordre/canonicalisation lorsque pertinent ; +- règles de parsing/rejet ; +- limites ; +- comportement unknown-version ; +- procédure VIEW ; +- procédure OWNER ; +- procédure de rotation ; +- vecteurs de test. + +Des **test vectors publics déterministes** doivent permettre à une implémentation externe en Rust, Python, Go, C ou autre de vérifier qu'elle dérive/déchiffre exactement les mêmes données. + +Le test vector peut naturellement contenir un password connu et un secret explicitement test-only ; il ne doit jamais être présenté comme wallet sûr de production. + +### 5.9 Secret en mémoire Définir explicitement l'ownership du secret déverrouillé. @@ -246,35 +522,44 @@ Au minimum : - éviter `Copy` et les clones implicites de secret ; - zeroization des buffers possédés lorsque raisonnablement possible ; - durée de vie du secret déverrouillé explicitement contrôlée ; -- distinction nette public metadata / encrypted payload / unlocked secret ; -- aucune conservation du mot de passe en clair au-delà du besoin cryptographique. +- distinction nette metadata / encrypted payload / unlocked secret ; +- aucune conservation du password en clair au-delà du besoin cryptographique ; +- VIEW ne doit jamais matérialiser le secret Solana ; +- le déverrouillage OWNER doit éviter l'exposition du secret brut aux consommateurs qui n'ont besoin que de `sign()`. Le plan doit être honnête sur les limites réelles de zeroization dans Rust et des allocations/transcodages choisis ; ne pas promettre une garantie que la stack ne peut pas fournir. -### 5.6 Persistence +### 5.10 Persistence et opérations d'administration Définir la stratégie : ```text create -open/read +open VIEW +open OWNER atomic replace no-clobber create -change password +rotate VIEW password +remove VIEW capability +create/recreate VIEW capability +rotate OWNER password +modify alias +add/update/delete notes permissions filesystem recovery after interrupted write ``` -Le changement de mot de passe doit : +La rotation de password doit : - conserver la même identité/keypair ; - produire un nouveau matériau de protection approprié ; - ne pas dégrader l'atomicité ; -- ne jamais laisser un fichier partiellement remplacé comme nouveau wallet valide. +- ne jamais laisser un fichier partiellement remplacé comme nouveau wallet valide ; +- permettre à OWNER de gérer VIEW sans connaître l'ancien VIEW password. Le plan doit distinguer comportement portable et durcissement spécifique Unix si nécessaire. -### 5.7 Import/export extensible +### 5.11 Import/export extensible Établir une architecture ouverte qui permette d'ajouter des formats sans enum central fermé imposant de modifier le cœur à chaque intégration. @@ -295,20 +580,25 @@ Cette liste est une **liste d'audit**, pas un engagement d'implémentation compl Ne pas ajouter des dépendances « au cas où ». -### 5.8 Sizing +### 5.12 Sizing Évaluer séparément : ```text crate/API foundation +threat model format wire -crypto/KDF/AEAD +interop/test vectors +KDF/AEAD/key wrapping +VIEW/OWNER key slots +authentification cryptographique metadata si retenue persistence signing -change-password +password/key-slot rotation +metadata alias/notes import/export security tests -docs/USAGE +docs/USAGE + format specification ``` Si le scope ne paraît plus clôturable proprement dans la session, découper **avant** l'implémentation lourde plutôt que réduire silencieusement les garanties de sécurité. @@ -320,13 +610,35 @@ Les noms exacts sont décidés pendant le plan, mais les responsabilités doiven Il doit exister des contrats clairs pour : ```text -wallet public identity/info wallet locked/encrypted representation -wallet unlocked/signing capability -create/open/save/change-password +wallet VIEW capability +wallet OWNER capability +wallet metadata/info après autorisation +create/open/save +rotate/remove/create key slots import/export/inspect ``` +La séparation conceptuelle minimale attendue est : + +```text +WalletView + -> pubkey() + -> alias() + -> notes() + +WalletOwner + -> tout WalletView + -> sign(...) + -> update_alias(...) + -> add/update/delete_note(...) + -> rotate_view_password(...) + -> disable/recreate_view(...) + -> rotate_owner_password(...) +``` + +Les noms ne sont pas imposés, les capacités oui. + Ne pas exposer directement un champ `secret: Vec` comme API publique de commodité. Une API explicitement dangereuse d'export du secret ne doit exister que si un format d'export retenu l'exige réellement et avec une sémantique qui évite l'exposition accidentelle. @@ -344,7 +656,9 @@ format invalide version non supportée paramètres crypto invalides authentification/déchiffrement échoué -password invalide ou secret non déverrouillable +VIEW password invalide/non déverrouillable +OWNER password invalide/non déverrouillable +capability insuffisante I/O no-clobber / destination existante persistence atomique @@ -373,8 +687,9 @@ KDF input Les événements utiles peuvent inclure : ```text -opération create/open/import/export/change-password/sign +opération create/open-view/open-owner/import/export/rotate/sign format/version non secrète +type de capability sans password succès/échec catégorisé durée destination/path seulement selon politique sûre retenue @@ -383,7 +698,8 @@ destination/path seulement selon politique sûre retenue Ne jamais logger : ```text -mot de passe +password VIEW +password OWNER secret seed private key @@ -391,6 +707,7 @@ signature payload arbitraire contenu complet du wallet ciphertext complet nonce/salt si le log n'en a aucun besoin opérationnel +alias/notes par défaut ``` Même `trace` ne constitue pas une exception. @@ -402,27 +719,63 @@ Les tests déterministes doivent couvrir au minimum les domaines suivants. ### Format - round-trip du format natif ; -- magic/version corrects ; +- magic/format_version corrects ; - unknown version rejetée ; - fichier tronqué/reformaté rejeté ; - champs/tailles invalides rejetés ; - corruption/tampering détectée ; -- absence du secret en clair dans le fichier. +- absence du secret, de la Pubkey, de l'alias et des notes en clair dans le fichier verrouillé ; +- paramètres KDF/crypto nécessaires au déverrouillage présents et cohérents ; +- vecteurs de test externes reproductibles. -### Mot de passe / crypto +### VIEW / OWNER -- bon mot de passe ouvre le wallet ; -- mauvais mot de passe échoue sans fuite ; -- changement de mot de passe conserve la Pubkey/keypair ; -- ancien mot de passe ne déverrouille plus le nouveau fichier ; -- nouveau mot de passe fonctionne ; -- salt/nonce/paramètres ne sont pas accidentellement réutilisés lorsque le design impose leur renouvellement. +- VIEW correct lit Pubkey/alias/notes ; +- VIEW ne peut pas signer via l'API ; +- VIEW ne peut pas modifier alias/notes via l'API ; +- VIEW ne peut pas administrer les key slots ; +- VIEW ne peut pas obtenir le secret Solana ; +- OWNER lit tout ce que VIEW lit ; +- OWNER signe ; +- OWNER modifie alias/notes ; +- OWNER peut changer VIEW sans ancien VIEW password ; +- OWNER peut supprimer puis recréer VIEW ; +- OWNER fonctionne même si VIEW est perdu/inconnu ; +- compromise/knowledge de VIEW ne permet pas d'ouvrir OWNER ; +- VIEW et OWNER utilisent salts/KDF material indépendants. + +Si le read-only cryptographique est retenu : + +- un détenteur VIEW ne peut pas produire une modification de metadata acceptée comme authentique par la vérification prévue ; +- les limites face au remplacement total du fichier sont documentées et testées seulement dans la mesure réellement possible. + +### Password / crypto + +- bon VIEW password ouvre VIEW seulement ; +- bon OWNER password ouvre OWNER ; +- mauvais password échoue sans fuite ; +- rotation VIEW conserve Pubkey/keypair ; +- rotation OWNER conserve Pubkey/keypair ; +- anciens passwords ne déverrouillent plus les key slots remplacés ; +- nouveaux passwords fonctionnent ; +- salt/nonce/paramètres ne sont pas accidentellement réutilisés lorsque le design impose leur renouvellement ; +- les paramètres KDF enregistrés permettent de rouvrir un wallet après changement des defaults KSP. + +### Metadata + +- alias indépendant du filename ; +- alias absent/présent/modifié ; +- notes absentes/présentes ; +- ajout/modification/suppression de notes ; +- limites de taille ; +- metadata non visible sans VIEW/OWNER ; +- metadata conservée lors d'une rotation OWNER/VIEW sauf modification explicite. ### Secret / diagnostics -- `Debug`/snapshots/projections publiques ne contiennent pas le secret ; -- erreurs n'échoent pas password/secret ; -- logs de test ne contiennent pas de secret ; +- `Debug`/snapshots/projections VIEW/OWNER ne contiennent pas le secret ; +- erreurs n'échoent pas passwords/secret ; +- logs de test ne contiennent pas de secret ni metadata non autorisée ; - types secrets n'acquièrent pas `Copy` par accident ; - zeroization testable lorsqu'elle est réellement observable sans faux sentiment de sécurité. @@ -431,7 +784,7 @@ Les tests déterministes doivent couvrir au minimum les domaines suivants. - create ; - destination existante/no-clobber ; - write atomique ; -- remplacement lors du changement de mot de passe ; +- remplacement lors des rotations/admin changes ; - échec intermédiaire ne détruisant pas le wallet précédent, dans la mesure testable par la couche ; - permissions/durcissement filesystem retenus. @@ -439,8 +792,9 @@ Les tests déterministes doivent couvrir au minimum les domaines suivants. - Pubkey dérivée correcte ; - signature produite et vérifiable ; -- changement de mot de passe ne change pas la signature déterministe d'un même message si la primitive de signature est déterministe ; -- le consumer peut signer sans extraction publique du secret brut. +- rotations VIEW/OWNER ne changent pas la signature déterministe d'un même message si la primitive de signature est déterministe ; +- VIEW ne peut pas signer ; +- le consumer OWNER peut signer sans extraction publique du secret brut. ### Import/export @@ -471,6 +825,18 @@ Ne jamais utiliser : Si une fixture déterministe est nécessaire, son caractère test-only doit être évident et elle ne doit jamais être utilisable comme secret de production recommandé. +Les test vectors d'interopérabilité peuvent publier volontairement : + +```text +password VIEW connu +password OWNER connu +secret test-only connu +Pubkey/alias/notes attendus +bytes/JSON .kspwallet attendus +``` + +uniquement lorsqu'ils sont explicitement réservés aux tests et documentés comme tels. + ## 11. Dépendances Toutes les dépendances tierces communes sont déclarées au `Cargo.toml` racine sous `[workspace.dependencies]`. @@ -500,6 +866,8 @@ features par défaut unsafe/transitifs importants zeroize support format/compatibilité +audit de sécurité disponible +interopérabilité externe duplications cargo tree ``` @@ -517,22 +885,36 @@ Ne pas bloquer naïvement un runtime async avec une dérivation de clé coûteus Ce choix doit rester compatible avec l'usage futur Tauri sans introduire Tauri dans Wallet. -## 13. Publication sûre / identité publique +## 13. Projection après autorisation -Wallet doit pouvoir fournir une représentation sûre destinée aux consommateurs qui n'ont besoin que de l'identité publique. +Wallet doit pouvoir fournir une représentation sûre destinée aux consommateurs autorisés qui n'ont besoin que des metadata. -Cette représentation peut contenir les metadata explicitement retenues telles que : +Wallet verrouillé : + +```text +ne révèle pas Pubkey +ne révèle pas alias +ne révèle pas notes +``` + +Avec VIEW ou OWNER : ```text Pubkey alias -format/version -état locked/unlocked si pertinent +notes +format/version si pertinent +état/capability sans secret ``` -mais jamais le secret ou des dérivés inutiles de secret. +Avec OWNER seulement : -La terminologie « publication » signifie ici **exposition sûre de l'identité publique**, pas envoi réseau ni publication blockchain. +```text +capacité de signature +administration metadata/key slots +``` + +La terminologie « identité publique » signifie que la Pubkey elle-même n'est pas un secret blockchain, mais le fichier `.kspwallet` ne doit pas la révéler à un lecteur non authentifié par défaut. ## 14. Hors périmètre `0.2.5` @@ -554,8 +936,12 @@ mobile app cloud key management custody service trading +recovery slot réellement implémenté +hardware/automation key slot réellement implémenté ``` +Les futurs rôles/key slots peuvent être anticipés structurellement sans être implémentés en V1. + Les pistes d'import/export peuvent être étudiées sans rendre leurs applications/providers propriétaires du cœur Wallet. ## 15. Relation avec `0.2.6 — Wallet Desk` @@ -570,13 +956,14 @@ Config -> ksp-app-wallet-desk ``` -Le premier flux réseau attendu est notamment : +Le premier flux réseau attendu peut devenir : ```text -ouvrir/sélectionner un .kspwallet --> obtenir sa Pubkey publique +sélectionner un .kspwallet +-> déverrouiller VIEW ou OWNER +-> obtenir la Pubkey -> getBalance via Transport HTTP --> afficher identité + solde +-> afficher identité + alias/notes + solde selon capability ``` Aucune logique réseau nécessaire à ce flux ne doit remonter dans `ksp-wallet-lib`. @@ -586,20 +973,20 @@ Aucune logique réseau nécessaire à ce flux ne doit remonter dans `ksp-wallet- Prévision initiale à réévaluer par `pre.001` : ```text -pre.001 audit bot3 + dépendances/crypto actuelles + brainstorming + format/API + sizing -pre.002 crate foundation + contrats public/secret + erreurs + canaries architecture -pre.003 enveloppe .kspwallet + versionnement + KDF/AEAD + fixtures déterministes -pre.004 create/open + persistence atomique/no-clobber + durcissement filesystem retenu -pre.005 signature + projection publique + changement de mot de passe +pre.001 audit bot3 + crypto/deps actuelles + threat model + VIEW/OWNER + format/API + sizing +pre.002 crate foundation + capabilities VIEW/OWNER + erreurs + canaries architecture +pre.003 enveloppe/key slots .kspwallet + format/version + KDF/AEAD/wrapping + test vectors +pre.004 compartiments metadata/secret + create/open VIEW/OWNER + persistence atomique/no-clobber +pre.005 signature + administration alias/notes + rotations VIEW/OWNER + read-only cryptographique si retenu pre.006 architecture import/export + premier(s) format(s) réellement retenu(s) -pre.007 security/compliance audit + README/USAGE + graphes + tests complémentaires +pre.007 security/interoperability/compliance audit + format spec + README/USAGE + graphes pre.008 clôture candidate + documentation finale + prompt 0.2.6 — Wallet Desk rel.001 publication strictement publicationnelle ``` Cette prévision est **souple**. -Si un fil cryptographique ou de persistence exige une correction, ajouter une prerelease/fix plutôt que compresser les validations. +Si l'architecture VIEW/OWNER, l'authentification metadata ou la persistence exige une tranche supplémentaire, ajouter une prerelease/fix plutôt que compresser les validations. Si `pre.001` conclut qu'un format/import particulier doit être reporté, le report doit être explicite et ne doit pas affaiblir les garanties du format natif. @@ -619,107 +1006,12 @@ Pendant le développement : cargo test -p ksp-wallet-lib ``` -Aux checkpoints justifiés et à la clôture : - -```bash -cargo test --workspace -``` - -Réaduiter les graphes Cargo de Wallet et de ses consumers lorsqu'ils apparaissent. - -## 18. Discipline des deltas - -Les deltas historiques sont immuables. - -Utiliser : +Les checkpoints de clôture doivent également réauditer : ```text -deltas/0.2.5/pre.001.md -deltas/0.2.5/pre.002.md -... -deltas/0.2.5/pre.NNN-fix.NNN.md -deltas/0.2.5/rel.001.md +cargo tree / duplications crypto +frontières de dépendances +absence d'accès environnement direct +absence de secrets dans logs/errors/debug +interop test vectors ``` - -La dernière prerelease doit préparer une candidate complètement validable. - -`rel.001` doit rester strictement publicationnelle : - -```text -version stable -ROADMAP -CHANGELOG stable -statut final du plan/validation -commit rel -tag stable -``` - -Aucune nouvelle capacité Wallet fonctionnelle ne doit être ajoutée à `rel.001`. - -## 19. Livrables de `pre.001` - -Avant toute implémentation lourde, produire au minimum : - -1. le plan détaillé `0.2.5` ; -2. l'audit des règles/frontières KSP ; -3. l'audit des implémentations historiques Wallet utiles ; -4. l'audit des primitives Solana/key/signature actuelles ; -5. l'audit comparatif des primitives KDF/AEAD/RNG ; -6. la proposition de format `.kspwallet` ; -7. le modèle de secret en mémoire ; -8. la stratégie de persistence/atomicité ; -9. la stratégie import/export ; -10. la matrice de risques sécurité ; -11. les dépendances pressenties et leur justification ; -12. les tests/canaries nécessaires ; -13. le sizing et la prévision de prereleases ; -14. les questions ouvertes réellement bloquantes. - -Le gate `pre.001` doit conclure explicitement : - -```text -GO -``` - -ou : - -```text -SPLIT / RESCOPE -``` - -avec justification. - -## 20. Critère de sortie de `0.2.5` - -`0.2.5` ne peut être publié stable que si : - -- `ksp-wallet-lib` est autonome et documenté ; -- `.kspwallet` est versionné et documenté ; -- le secret n'est jamais stocké en clair dans le format natif ; -- le secret/password ne fuit pas dans Debug/Display/logs/errors ; -- create/open/sign/change-password sont validés ; -- l'identité publique reste accessible par un contrat sûr ; -- la persistence retenue est atomique/no-clobber selon son contrat ; -- les corruptions/tampering sont détectées ; -- import/export extensible est démontré avec le minimum de formats retenu ; -- `WalletPolicy` est absent ; -- Wallet ne dépend pas de Config/Transport/ExecutionPolicy ; -- les graphes Cargo sont réaudités ; -- les tests déterministes et le workspace passent ; -- README/USAGE/validation sont synchronisés ; -- le prompt `0.2.6 — Wallet Desk` est finalisé ; -- `rel.001` reste publicationnelle. - -## 21. Première action de la session - -Commencer par : - -```text -audit actuel --> brainstorming --> matrice des décisions --> sizing --> plan pre.001 -``` - -Ne pas commencer par coder le chiffrement du fichier.