Some checks failed
Test / test (push) Has been cancelled
Cross-platform vectors / TypeScript vectors (bun) (push) Has been cancelled
Cross-platform vectors / Kotlin vectors (gradle) (push) Has been cancelled
Docker build and publish / docker (push) Has been cancelled
Publish / publish (push) Has been cancelled
V3.1 → V3.12 consolidated and tagged for the first GA release. Wire format unchanged from 0.4.x — 4.0 peers interoperate with 0.4.x peers byte-for-byte. The version bump is semantic: audit-cycle complete, opt-in surface fully exposed, threat model refreshed for every new surface. Highlights: - All 24 @shade/* packages bumped to 4.0.0 in lockstep. - CHANGELOG 4.0.0 section is the canonical manifest of what landed. - THREAT-MODEL extended (§10 fingerprint gates, §11 WebRTC P2P, §12 Web-Worker boundary) + residual-risks table refreshed. - OpenAPI now covers all 27 routes: prekey, transfer, KT, inbox, bridge, observer, /metrics, /healthz, /ready. - MIGRATION 0.3.x → 4.0 documented + smoke-tested against shade migrate-storage on a real SQLite DB. - docs/audit/REVIEW-BUNDLE.md + SCOPE.md ready for external reviewer. - scripts/soak.ts harness for the GA-stable 2-week soak window. - All V*.md plans archived under docs/archive/ with Status: Done. - Voice/Video carved out into V5.0; 4.0 audit focuses on the frozen non-realtime stack. Tests: TS 1000/1000 + Kotlin 11/11 cross-platform vectors green. Docker: gt.zyon.no/stian/shade-prekey:4.0.0 builds and reports version 4.0.0 on /health. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
135 lines
3.9 KiB
Markdown
135 lines
3.9 KiB
Markdown
# Shade V3.10 — Social Key Recovery
|
||
|
||
**Status:** Done — landet i `@shade/recovery` 0.4.0, frosset i 4.0 GA.
|
||
**Effort:** L (4–8 uker)
|
||
**Forrige:** V3.2 + V3.3
|
||
**Adresserer:** V2.1-tillegg "sosial nøkkel-recovery"
|
||
|
||
---
|
||
|
||
## Mål
|
||
|
||
Løs det største UX-hullet i alle E2EE-systemer: **"Hva skjer hvis jeg
|
||
mister telefonen?"**. Bruker velger N "guardians" (familie / venner /
|
||
jobb-partnere); når bruker mister enheten, kan en threshold-andel av
|
||
guardians sammen returnere identity-nøkkelen — uten at noen enkelt guardian
|
||
kan gjøre det alene, og uten at server lærer noe.
|
||
|
||
---
|
||
|
||
## Scope
|
||
|
||
### Inn
|
||
|
||
- Shamir Secret Sharing (k-of-n) over identity private key (eller en
|
||
backup-encryption-key).
|
||
- Distribusjon av shares via eksisterende 1:1 Shade-sesjoner — guardians
|
||
lagrer share lokalt.
|
||
- Recovery-flow: ny enhet ber threshold guardians sende sine shares;
|
||
rekonstruerer på ny enhet.
|
||
- Verifikasjons-step: ny enhet beviser identitet til hver guardian via OOB
|
||
safety-number-sammenligning **før** guardian frigjør share.
|
||
- UX-guide: hvor mange guardians, hvilken threshold, hvordan rotere når en
|
||
guardian mister enhet.
|
||
|
||
### Ut
|
||
|
||
- "Cloud guardian" / Shade-driftet recovery — vi tillater ingen sentralisert
|
||
komponent som kan gjøre det alene.
|
||
- Auto-distribusjon (vi krever eksplisitt valg av guardians).
|
||
|
||
---
|
||
|
||
## Design
|
||
|
||
### Hva deles
|
||
|
||
```text
|
||
shareSecret = AES-256-GCM-encrypt(identityState, recoveryKey)
|
||
recoveryKey is Shamir-split(k, n) → shares[i]
|
||
shareSecret stored locally + on each guardian
|
||
each guardian receives one share via Shade.send
|
||
```
|
||
|
||
`identityState` er det samme som `Shade.exportBackup` (eksisterer i 0.3.x),
|
||
men her gjenbrukes formatet.
|
||
|
||
### Recovery-flow
|
||
|
||
1. Ny enhet genererer **temporary** identity + safety number.
|
||
2. Ny enhet kontakter guardians via prekey-server (OOB verifisering først).
|
||
3. Hver guardian godkjenner manuelt og returnerer sin share via
|
||
`Shade.send`.
|
||
4. Ny enhet rekonstruerer `recoveryKey`, dekrypterer `shareSecret`,
|
||
gjenoppretter identity.
|
||
5. Original identity roterer (gammel identitet markeres som
|
||
"compromised — used for recovery").
|
||
|
||
### Guardian-UX
|
||
|
||
- Guardian-app/widget viser:
|
||
*"Alice (din venn) har mistet sin enhet og ber om recovery share.
|
||
Bekreft fingerprint før du sender."*
|
||
- Guardian kan **avslå** uten konsekvens.
|
||
|
||
---
|
||
|
||
## Leveranser
|
||
|
||
### Pakker
|
||
|
||
- `@shade/recovery` — Shamir + share-distribusjon.
|
||
- `@shade/widgets` — `<RecoverySetup />` (velg guardians) +
|
||
`<RecoveryRequest />` (ny enhet ber) + `<RecoveryApprove />` (guardian
|
||
godkjenner).
|
||
|
||
### Tester
|
||
|
||
- Unit: Shamir split/combine roundtrip; threshold-håndhevelse.
|
||
- Integration: full 3-of-5 recovery med 5 mock-guardians.
|
||
- Adversarial: 2 guardians koluderer (under threshold) → kan ikke
|
||
rekonstruere.
|
||
- Adversarial: ondsinnet ny enhet uten safety-number-bekreftelse → ingen
|
||
guardian skal frigjøre share.
|
||
|
||
### Dokumentasjon
|
||
|
||
- `docs/recovery.md` — full UX + threat model.
|
||
- Trusselmodell-utvidelse: kollusjon ≤ k-1, identitetsforfalskning, social
|
||
engineering.
|
||
|
||
---
|
||
|
||
## Akseptansekriterier
|
||
|
||
- [ ] 3-of-5 recovery fungerer end-to-end på 2 separate enheter.
|
||
- [ ] Ingen koalisjon av (k-1) guardians kan rekonstruere `shareSecret`
|
||
(verifisert med fast-check property test).
|
||
- [ ] Guardian-side widget krever fingerprint-bekreftelse før send (gate
|
||
fra V3.3 forsterket).
|
||
|
||
---
|
||
|
||
## Avhengigheter
|
||
|
||
- V3.2 — nøkkelmateriale at-rest hos guardian skal være kryptert.
|
||
- V3.3 — fingerprint-gate på recovery-handshake.
|
||
|
||
---
|
||
|
||
## Risiko
|
||
|
||
- **UX er det vanskeligste.** "Hvem er min guardian?" er sosialt komplekst;
|
||
bruker kan velge dårlig.
|
||
- **Social engineering.** Angriper imiterer offer over telefon → guardian
|
||
gir share. Mitiger med harde fingerprint-gates + cool-down.
|
||
- **Dead guardians.** Hvis guardian dør / mister sin enhet uten å være
|
||
erstattet, threshold synker. Periodisk "guardian health check"-prompt
|
||
anbefales.
|
||
|
||
---
|
||
|
||
## Migrasjon
|
||
|
||
Ny pakke. Apper kan legge til recovery-widget i innstillinger.
|