Files
Shade/docs/archive/V3.3.md
Sterister e6fdf31b49
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
release(v4.0.0): Shade GA — V3.x consolidation + audit prep
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>
2026-05-03 18:35:35 +02:00

4.2 KiB
Raw Blame History

Shade V3.3 — Fingerprint Gates & Trust UX

Status: Done Effort: M (24 uker) Forrige: V3.1 Adresserer: V2.3 §1B Implementert: se docs/trust-ux.md


Mål

Gjør safety numbers handlingspålagte — ikke bare synlige — i flyt der MITM-risikoen er reell. I dag finnes FingerprintCompare-widget og requireFingerprintVerifiedFor i @shade/files, men hovedkjernen (Shade.send, first-large-file, backup-import) har ingen automatisk gate. Resultat: alert-fatigue-fri, men også gate-fri.

Dette legger inn eksplisitt blokkerende verifisering på et lite antall kritiske hendelser, plus widget-støtte for å eksponere det i UI.


Scope

Inn — kritiske hendelser

  1. Før første store filShade.upload over en bytes-terskel uten verifisert peer.
  2. Før backup-importShade.importBackup blokkerer til peer (eller egen identitet) er bekreftet.
  3. Ny enhet med rotert identitetacceptIdentityChange blokkerer på første bruk inntil verifisert.
  4. Før @shade/inbox fan-out (V3.6) — gate per mottaker.

Inn — APIer

  • Shade.beforeFirstLargeFile(threshold, handler) — appen får mulighet til å vise modal og returnere bekreftelse.
  • Shade.beforeBackupImport(handler) — samme mønster.
  • Shade.beforeNewDeviceTrust(handler) — ditto.
  • Shade.markPeerVerified(address) / Shade.isPeerVerified(address) — persistent state.

Inn — widgets

  • <FingerprintGate /> — render-prop wrapper som blokkerer barn til verifisert.
  • <FingerprintCompare /> utvides med "kopier OOB-tekst" + "jeg har verifisert".

Ut

  • "Tving alle peers verifisert før hver melding" — alert fatigue.
  • Cross-device sync av verified-state (kommer evt. via V3.6 inbox).

Design

Persistent verified-state

Ny tabell peer_verifications:

CREATE TABLE peer_verifications (
  peer_address      TEXT PRIMARY KEY,
  fingerprint       TEXT NOT NULL,
  verified_at       INTEGER NOT NULL,
  verified_by       TEXT,        -- "user" | "transitive" | "tofu-after-warning"
  identity_version  INTEGER NOT NULL  -- knytter verifikasjon til identity-rotasjon
);

Når peer roterer identitet → identity_version bumper → verifikasjon "ugyldig" til ny verifisering.

Hook-flyt

shade.upload(peer, file)
    │
    ├─ if !verified(peer) AND file.size > threshold
    │    │
    │    └─ await beforeFirstLargeFileHandler(peer, fingerprint)
    │          ├─ true  → markPeerVerified(peer); proceed
    │          └─ false → throw FingerprintNotVerifiedError
    │
    └─ proceed

Leveranser

Kode

  • @shade/corepeer_verifications-tabell + storage methods.
  • @shade/sdk — gate-hooks + markPeerVerified / isPeerVerified.
  • @shade/widgets<FingerprintGate />, utvidet <FingerprintCompare />.

Tester

  • Unit: gate kalles, ikke kalles, retur false → throw, retur true → proceed.
  • Integration: fil < threshold går gjennom uten gate; fil > threshold blokkerer.
  • Identity-rotasjon ugyldiggjør verifikasjon.
  • Backup-import blokkerer.

Dokumentasjon

  • docs/trust-ux.md — guide til hvilke gates som finnes og når de bør tunes.

Akseptansekriterier

  • Gate kan ikke bypasses ved å nulle threshold ut — minimum gate finnes alltid for backup-import og new-device.
  • App uten registrerte gates får sane defaults (logger en warning, men kjører — ikke krasj).
  • Identity-rotasjon resetter verifikasjon i en testet ende-til-ende-flow.
  • Widget kan rendres SSR uten å trigge runtime-gate.

Avhengigheter

  • V3.1 — threat-matrise oppdatert til å vise hvilke gates som dekker hvilke rader.

Risiko

  • Alert fatigue. Hvis terskler er for lave → bruker klikker blindt. Mitiger ved å sette default-terskler høyt (10 MiB for first-large-file) og dokumenter justerings-guide.
  • DX-friksjon. Apper som ikke vet om gates får uventede prompts. Mitiger ved å logge tydelig ved første aktivering: "Shade.beforeFirstLargeFile not configured — using default modal".

Migrasjon

0.3.x apps får defaults aktivert med warning. Ingen breaking change.