Goal
Decide, and write down, what the Web3Auth Core Kit store is allowed to persist and where.
Problem
apps/web/src/auth/coreKit.ts passes storage: window.localStorage to Web3AuthMPCCoreKit, inherited from v1. Core Kit writes two things into it:
setDeviceFactor persists a raw factorKey hex — a tKey share scalar — once MFA is enabled.
createSession persists a sessionId, the handle for a session payload holding postBoxKey, factorKey, tssShare, and signatures. Anyone who reads that id can reconstitute a logged-in Core Kit and call _UNSAFE_exportTssKey.
Default sessionTime is 86400s, and localStorage survives tab close and is shared across every tab on the origin. So any same-origin XSS or shared-machine reader gets a 24-hour bearer path to the login secret.
The login secret itself is never written — it leaves the UI realm only as the transferred buffer — so this is not a violation of AGENTS.md rule 1 on its face. But the store is a credential, it is currently a default rather than a decision, and #911 shipped with only a code comment naming the tension.
Work
Pick and justify:
sessionStorage — per-tab, cleared on close. Still survives reload, which is all the useAuth restore effect needs. Costs cross-tab session restore, which the one-leader tab model may already make moot.
- An explicit, shorter
sessionTime.
- Keeping
localStorage deliberately, with the reasoning recorded.
Then make the accepted storage key set an assertion in the web-e2e login spec, so a future SDK bump that starts persisting something new fails a gate instead of a review. The current unit test cannot see this: it runs against a fake session with no SDK behind it.
Gate
web-e2e login spec. tests/web-e2e/ now exists (#809, #1078) and carries a login spec, so the assertion has somewhere to land — note that CI logs in through the introspection hook rather than an interactive Core Kit session, so the spec needs to reach a real Core Kit path or assert the absence of unexpected keys under the hook path deliberately.
Dependencies
None outstanding. #804 (the coreKit.ts storage choice) and #809 (the web-e2e harness the gate runs in) have both landed.
Corrected 2026-08-06 against main @ 3d087d673. Stale before this edit: the ## Depends on section named #804 and #809, both now closed, and its sequencing advice ("either sequence behind #809, or split") no longer applies — tests/web-e2e/ exists. The storage decision itself is untouched and still open.
Part of #642
Goal
Decide, and write down, what the Web3Auth Core Kit store is allowed to persist and where.
Problem
apps/web/src/auth/coreKit.tspassesstorage: window.localStoragetoWeb3AuthMPCCoreKit, inherited from v1. Core Kit writes two things into it:setDeviceFactorpersists a rawfactorKeyhex — a tKey share scalar — once MFA is enabled.createSessionpersists asessionId, the handle for a session payload holdingpostBoxKey,factorKey,tssShare, andsignatures. Anyone who reads that id can reconstitute a logged-in Core Kit and call_UNSAFE_exportTssKey.Default
sessionTimeis 86400s, andlocalStoragesurvives tab close and is shared across every tab on the origin. So any same-origin XSS or shared-machine reader gets a 24-hour bearer path to the login secret.The login secret itself is never written — it leaves the UI realm only as the transferred buffer — so this is not a violation of AGENTS.md rule 1 on its face. But the store is a credential, it is currently a default rather than a decision, and #911 shipped with only a code comment naming the tension.
Work
Pick and justify:
sessionStorage— per-tab, cleared on close. Still survives reload, which is all theuseAuthrestore effect needs. Costs cross-tab session restore, which the one-leader tab model may already make moot.sessionTime.localStoragedeliberately, with the reasoning recorded.Then make the accepted storage key set an assertion in the web-e2e login spec, so a future SDK bump that starts persisting something new fails a gate instead of a review. The current unit test cannot see this: it runs against a fake session with no SDK behind it.
Gate
web-e2e login spec.
tests/web-e2e/now exists (#809, #1078) and carries a login spec, so the assertion has somewhere to land — note that CI logs in through the introspection hook rather than an interactive Core Kit session, so the spec needs to reach a real Core Kit path or assert the absence of unexpected keys under the hook path deliberately.Dependencies
None outstanding. #804 (the
coreKit.tsstorage choice) and #809 (the web-e2e harness the gate runs in) have both landed.Corrected 2026-08-06 against
main@3d087d673. Stale before this edit: the## Depends onsection named #804 and #809, both now closed, and its sequencing advice ("either sequence behind #809, or split") no longer applies —tests/web-e2e/exists. The storage decision itself is untouched and still open.Part of #642