@@ -31,6 +31,45 @@ Please include as much of the following as possible:
3131The QRL team will triage private reports, coordinate fixes, and publish
3232security advisories or release notes when appropriate.
3333
34+ ## Key Material & Memory Security
35+
36+ The secret protected by this library is the wallet ** seed** (and the extended seed / mnemonic that
37+ contain it). Anyone with the seed can derive the ML-DSA-87 secret key and sign arbitrary
38+ transactions, so it is critical material.
39+
40+ ** JavaScript does not provide guaranteed secure memory handling.** Unlike languages that expose raw
41+ buffers, a JS runtime may keep copies of a secret that the application cannot reach or erase — the
42+ garbage collector may relocate or retain copies, the JIT may materialise additional copies, and the
43+ value may reach swap or a core dump. This is a platform limitation, not a defect in this library, and
44+ it is the same constraint documented for [ ` @theqrl/wallet.js ` ] ( https://github.com/theQRL/wallet.js )
45+ (see its ` SECURITY.md ` "Memory Security").
46+
47+ ** Seeds are held as immutable strings.** ` web3.qrl.accounts ` exposes the seed as a hex string
48+ (` account.seed ` ). A JavaScript string is immutable, so — unlike a ` Uint8Array ` — it ** cannot be
49+ zeroized/overwritten** after use. Best-effort scrubbing therefore does not apply to the seed as this
50+ API exposes it; treat any seed string as unrecoverably resident in memory for the process lifetime.
51+
52+ What this library ** does** do to reduce accidental exposure:
53+
54+ - ` account.seed ` is defined ** non-enumerable** , so it does not appear in a spread, ` Object.keys ` , or
55+ a naive ` for…in ` .
56+ - ` account.toJSON() ` ** redacts** the seed (` '<redacted>' ` ), so ` JSON.stringify(account) ` and most
57+ loggers will not serialise it.
58+
59+ Recommendations for applications handling seeds:
60+
61+ - ** Minimise seed lifetime.** Derive what you need and drop references promptly; do not hold seeds in
62+ long-lived state, closures, or global caches.
63+ - ** Never log or serialise raw seeds.** Rely on the redaction above rather than passing the seed to a
64+ logger, telemetry, or error report yourself.
65+ - ** Prefer the encrypted keystore at rest.** Store seeds as an encrypted V1 keystore (Argon2id +
66+ AES-256-GCM), never as plaintext.
67+ - ** For tighter in-memory control** , operate on the lower-level ` Uint8Array ` -backed primitives in
68+ [ ` @theqrl/wallet.js ` ] ( https://github.com/theQRL/wallet.js ) and call its ` zeroize() ` when done —
69+ understanding that this is ** best-effort** protection, not a cryptographic guarantee.
70+ - ** For high-value use** , consider a hardware security module, a dedicated signer process, or a
71+ worker with a constrained lifetime rather than holding seeds in a general-purpose runtime.
72+
3473## Release Verification
3574
3675After the first audited release, published packages are expected to be verifiable
0 commit comments