anchorage_layer_simple/userwallet/features/userwallet-iframe-key-isolation.md
ncantu f9fe0e3419 Website-skeleton partie connectée, contrat en dur, navigate-login; UserWallet pairing-relay-status, redirect; website-data, proxy data, cryptographie, fixKnowledge
**Motivations:**
- Partie connectée du skeleton accessible seulement si pairing satisfait + relais OK, avec page type skeleton (avatar, notifications).
- Éviter « Aucun service disponible » : contrat présent en dur dans la page, transmis à l’iframe ; navigation évidente ou automatique vers login.
- Sécuriser postMessage (origine UserWallet uniquement) ; déployer data sur le proxy et certificat data.certificator.4nkweb.com.
- Vulgariser cryptographie (ECDH, AES-GCM, Schnorr, workflow, collecte signatures) ; documenter correctifs et architecture.

**Root causes:**
- Section connectée affichée sans vérifier pairing/relay ; possibilité de forger pairing-relay-status depuis la console.
- Iframe masquée ou /login chargé avant réception du contrat → graphe vide, redirection vers /services.
- Pas de contrôle d’origine sur les messages reçus ; pas de projet website-data ni config Nginx/certificat pour data.

**Correctifs:**
- Vérification msg.origin === USERWALLET_ORIGIN dans handleMessage (skeleton).
- Si session mais pas pairingRelayStatus : afficher iframe pour réception du statut, message « Vérification du statut… ».
- Contrat envoyé dès load iframe (init iframe.src = USERWALLET_ORIGIN) ; au clic « Se connecter », envoi contract + navigate-login (service, membre).
- UserWallet : écoute navigate-login → navigation /login?service=&membre= ; LoginScreen avec service+membre en URL ne redirige plus vers /services, dispatch E_SELECT_SERVICE / E_SELECT_MEMBER.

**Evolutions:**
- Message pairing-relay-status (iframe → parent) ; canShowConnectedSection exige login + pairing OK + relay OK ; page connectée avec header avatar + icône notifications.
- Skeleton : getLoginContext, sendNavigateLoginToIframe, onIframeLoad, loginRequested/iframeLoaded ; contrat envoyé avec serviceUuid, membreUuid.
- UserWallet : PairingRelayStatusMessage, envoi depuis HomeScreen/LoginScreen ; type navigate-login, handleNavigateLogin dans useChannel.
- Page cryptographie.html (workflow, algorithmes, collecte signatures) ; liens nav, build.
- website-data (Vite, channel, config), start/service/install ; configure-nginx-proxy + Certbot pour data.certificator.4nkweb.com.
- fixKnowledge (postmessage-origin, section-connectee-non-affichee) ; features (partie-connectee-pairing-relay, userwallet-iframe-key-isolation).

**Pages affectées:**
- website-skeleton (index, main, config, serviceContract, cryptographie, technique, membre, contrat, vite.config, README).
- userwallet (HomeScreen, LoginScreen, useChannel, iframeChannel, relay, crypto, iframe, Pairing*, RelaySettings, WordInputGrid, syncUpdateGraph, specs/synthese).
- website-data (nouveau), configure-nginx-proxy, docs DOMAINS_AND_PORTS README, features, fixKnowledge, userwallet features/docs.
2026-01-29 00:55:58 +01:00

35 lines
2.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UserWallet iframe — cloisonnement des clés et du chiffrement
**Objectif**
Garantir quaucune clé secrète ne quitte liframe UserWallet et quaucune opération de signature ou de chiffrement nest effectuée en dehors du domaine de liframe.
**Règles**
1. **Clés**
- Seules les **clés publiques** peuvent sortir de liframe (via postMessage vers le parent).
- Les clés privées (`privateKey`, `cle_privee`) ne doivent jamais être envoyées au parent ni à un autre domaine.
2. **Crypto**
- Toutes les opérations de **signature**, **chiffrement** et **déchiffrement** sont réalisées **uniquement dans liframe** (UserWallet).
- Le parent (site intégrateur, ex. skeleton) ne doit **jamais** signer, chiffrer ni déchiffrer. Il peut uniquement **vérifier** des signatures à laide des clés publiques (ex. `verifyLoginProof`).
**Implémentation**
- **iframeChannel** : `sendToChannel` appelle `assertNoSecretsInChannelPayload` avant `postMessage`. Toute présence de `privateKey` ou `cle_privee` dans le payload (récursif) lève une erreur ; le message nest pas envoyé.
- **iframe.ts** : `sendMessageToParent` appelle aussi `assertNoSecretsInChannelPayload` sur le payload avant `postMessage`. Tous les envois vers le parent passent par cette vérification.
- **Messages envoyés au parent** : `auth-response` (signature, publicKey, message), `login-proof` (challenge, signatures avec `cle_publique`), `error`, `service-status`, `pairing-relay-status` (pairingSatisfied, relayOk). Aucun de ces messages ne contient de clé secrète.
- **Messages reçus du parent** : `auth-request`, `contract`. Le contrat peut contenir des `cle_publique` de service (validateurs) ; ce sont des clés publiques. Le parent nenvoie jamais de clé privée.
- **Parent (intégrateur)** : Ne doit jamais signer, chiffrer ni déchiffrer. Il peut uniquement **vérifier** des signatures (ex. `verifyLoginProof` avec clés publiques). Ex. skeleton : vérification uniquement, pas de crypto secrète.
**Contrôles**
- Avant tout envoi vers le parent : vérification systématique des payloads pour `privateKey` et `cle_privee`.
- Aucun usage de `privateKey` / `cle_privee` dans les types de messages définis pour le canal iframe (`AuthResponseMessage`, `LoginProofMessage`, etc.).
**Pages affectées**
- `userwallet/src/utils/iframeChannel.ts` (assertion, `sendToChannel`)
- `userwallet/src/utils/iframe.ts` (assertion, `sendMessageToParent`)
- `userwallet/features/userwallet-iframe-key-isolation.md` (ce document)