feat(v1.3.0): add ephemeral session-key encryption for sensitive state

This commit is contained in:
LC mac
2026-01-29 23:14:42 +08:00
parent 5a4018dcfe
commit 8e656749fe
8 changed files with 856 additions and 442 deletions

53
AGENTS.md Normal file
View File

@@ -0,0 +1,53 @@
# SeedPGP Agent Brief (read first)
## What this repo is
SeedPGP: a client-side BIP39 mnemonic encryption web app.
Goal: add features without changing security assumptions or breaking GH Pages deploy.
## Non-negotiables
- Small diffs only: one feature slice per PR (1-5 files if possible).
- No big code dumps; propose plan first, then implement.
- Never persist secrets (mnemonic, passphrases, private keys) to localStorage/sessionStorage.
- Prefer “explain what you found in the repo” over guessing.
## How to run
- Install deps: `bun install`
- Dev: `bun run dev`
- Build: `bun run build`
- Tests/lint (if present): `bun run test`, `bun run lint`, `bun run typecheck`
## Repo map (confirm/update)
- UI entry: `src/main.tsx`
- Components: `src/components/`
- Core logic/types: `src/lib/`
## Deploy
There is a deploy script (see `scripts/deploy.sh`) and a separate public repo for built output.
## Required workflow for every task
1) Repo study: identify entry points + relevant modules, list files to touch.
2) Plan: smallest vertical slice, with acceptance criteria.
3) Implement: code + minimal tests or manual verification steps.
4) Evidence: paste command output (build/test) and note any tradeoffs.
## Security Architecture (v1.3.0+)
- **Session-key encryption**: Ephemeral AES-GCM-256 key (non-exportable) encrypts sensitive state
- **Auto-clear**: Plaintext mnemonic cleared from UI immediately after QR generation
- **Encrypted cache**: Only ciphertext stored in React state; key lives in memory only
- **Lock/Clear**: Manual cleanup destroys session key + clears all state
- **Lifecycle**: Session key auto-destroyed on page close/refresh
## Module: src/lib/sessionCrypto.ts
- `getSessionKey()` - Generates/returns non-exportable AES-GCM key (idempotent)
- `encryptJsonToBlob(obj)` - Encrypts to {v, alg, iv_b64, ct_b64}
- `decryptBlobToJson(blob)` - Decrypts back to original object
- `destroySessionKey()` - Drops key reference for GC
- Test: `await window.runSessionCryptoTest()` (DEV only)