docs: the paper recovery kit is cut — recovery is a passkey (accounts-and-recovery) (#1356)
Paul (2026-07-25): no passphrase- or printed-code-shaped recovery anywhere. The owner paper kit becomes a recovery passkey (cross-platform manager or hardware key — the ecosystem escape hatch paper used to be); managed members need no kit (the guardian's vault + ladder is the redundancy). Ladder rung 4, the mechanism/class tables, invariant 2's anchor pair, who-sees-what, and phasing all updated to match. Companion to #1354 (the code removal).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 file changed,
+51
−34
docs/accounts-and-recovery.md+51 −34
diff --git a/docs/accounts-and-recovery.md b/docs/accounts-and-recovery.md| index c7b672d..c3aedc0 100644 |
| --- a/docs/accounts-and-recovery.md |
| +++ b/docs/accounts-and-recovery.md |
| @@ -9,8 +9,11 @@ the native passkey/Apple/email doors. Merged but dark: the synced DEK |
| (#1144, flag off pending the device matrix). Not built yet: the `/invite` |
| link redesign (the phase-0 locked-card rungs shipped on the Mac 2026-07-22; |
| native add-device mint/QR still open), owner anchoring at creation, |
| -approve-from-another-device, paper kits, and the native OIDC doors (server |
| -legs done, client work open) — see *Phasing* below, per-item. |
| +approve-from-another-device, the recovery-passkey offer, and the native OIDC |
| +doors (server legs done, client work open) — see *Phasing* below, per-item. |
| +(The **paper recovery kit** that used to sit in this list was cut on |
| +2026-07-25 — Paul: recovery is a passkey, never a passphrase or a printed |
| +code; the recovery-passkey section below replaces it.) |
| This document supersedes the *Invariants* section of |
| `onboarding-and-home-server.md` — the "no email, no social login, ever" line — |
| after that invariant was field-falsified by real lockouts. Everything else in |
| @@ -55,7 +58,7 @@ Every mechanism in this design does one or both of: |
| | Email code | ✓ | — | ecosystem-neutral; blind-indexed (below) | |
| | iCloud-synced DEK item | — | ✓ | invisible; Apple-ecosystem only | |
| | Device key + approval | — | ✓ | transfers keys to a new device, given identity | |
| -| Paper recovery kit | — | ✓ | printed wrap of the DEK; survives everything | |
| +| Recovery passkey (manager / hardware key) | ✓ | ✓ | a second, independent credential; ecosystem-free | |
| | Guardian wrap | — | ✓ | DEK/credentials wrapped to another member's key | |
| An **identity anchor alone can never decrypt anything.** That single sentence |
| @@ -73,8 +76,8 @@ What "no email, no social login, ever" weakens to — each line deliberate: |
| Practically: *creating* a space requires an anchor; *joining* one never |
| does. The owner's anchor is a **pair**: an identity anchor (email, Sign in |
| with Apple, or a successor — see the open slot) *plus* a key anchor (on |
| - Apple platforms the synced DEK rides along invisibly; otherwise the paper |
| - kit). |
| + Apple platforms the synced DEK rides along invisibly; otherwise a |
| + recovery passkey in a synced manager or on a hardware key). |
| 3. **Providers attest; they are never the identity.** A third-party sign-in |
| is at most a verifier of an anchor. Our record is a blind index (a hash) — |
| there is no provider user-id column, no stored email address, and swapping |
| @@ -93,9 +96,9 @@ What "no email, no social login, ever" weakens to — each line deliberate: |
| | Class | Identity (job 1) | Keys (job 2) | Lost everything | |
| |---|---|---|---| |
| -| **Owner** (anchored) | SiwA / email / successor | synced DEK, or paper kit | full restore via anchor pair | |
| +| **Owner** (anchored) | SiwA / email / successor | synced DEK, or recovery passkey | full restore via anchor pair | |
| | **Member, anchored** (optional) | same menu | same menu | same ladder as owner | |
| -| **Member, identifier-less** | the key *is* the identity | passkey, paper kit, or nothing | re-invite floor | |
| +| **Member, identifier-less** | the key *is* the identity | passkey(s) or nothing | re-invite floor | |
| | **Guardian-managed** | none — guardian vouches | wrapped to guardian's key | guardian re-links, instantly | |
| - **Owner.** Whoever creates a space attaches the anchor pair at creation |
| @@ -104,7 +107,7 @@ What "no email, no social login, ever" weakens to — each line deliberate: |
| surface (quotas, reaping, billing), membership never was (invite-gated). |
| - **Identifier-less member.** Today's model, kept on purpose for |
| privacy-maximalists: bootstrap by invite, optionally strengthen with a |
| - passkey or a paper kit, accept the re-invite floor. This class is why |
| + passkey (or several), accept the re-invite floor. This class is why |
| the product can still truthfully say "no signup required". |
| - **Guardian-managed** — the family case. A child has no email and no |
| passkey. The guardian's signed-in app mints the child's credentials |
| @@ -112,9 +115,9 @@ What "no email, no social login, ever" weakens to — each line deliberate: |
| as a **managed entry in the guardian's own vault**. The child has *no home |
| account at all* — no server record, no identifier, nothing collected |
| (the right COPPA/GDPR-K posture by construction). Restore = guardian opens |
| - their app → managed member → "link this device" QR. A printed **paper kit |
| - per child** is optional redundancy for the guardian losing their own |
| - account. Disclosed honestly: a guardian holding a member's keys can read |
| + their app → managed member → "link this device" QR. The guardian's own |
| + recovery ladder is the redundancy: recover the guardian account and the |
| + managed entries come back with the vault. Disclosed honestly: a guardian holding a member's keys can read |
| and act as that member — that is what guardianship *is*, and the UI says |
| so at creation. (A later variant can give an older child their own home |
| account with the DEK additionally wrapped to the guardian — the graduation |
| @@ -134,7 +137,10 @@ Top rung first; each rung only matters when everything above it is gone: |
| the DEK is re-wrapped to the new device's ephemeral key. This is the |
| add-device flow wearing mainstream clothes (WhatsApp/Signal/Apple trained |
| everyone on it) and is the workhorse for web and non-Apple platforms. |
| -4. **The paper kit** — scan/upload, keys return. Survives ecosystems. |
| +4. **A recovery passkey outside the ecosystem** — a passkey in a |
| + cross-platform manager or on a hardware security key, enrolled as one |
| + more way in. This is what survives losing a whole vendor account: it is |
| + deliberately not parked where rung 2 lives. |
| 5. **Control-only recovery + the re-invite floor** — identity anchor alone. |
| The owner recovers *control* of the space (see below) and can re-admit |
| anyone; a re-invited member gets the **same stable thread keys re-wrapped |
| @@ -300,24 +306,35 @@ If plain email fills it: |
| the provider becomes a party who sees addresses and timing; per-address |
| rate limits and disposable-domain policy become the abuse levers. |
| -## The paper recovery kit |
| - |
| -A one-page PDF, **generated client-side only** (browser or app — the server |
| -never sees the plaintext payload), in the tradition of 1Password's Emergency |
| -Kit and Signal's backup key: |
| - |
| -- **Owner kit:** the home credential id + the DEK wrapped under a printed |
| - code (the same passphrase-wrap primitive the operator vault's recovery |
| - escrow ships — `vault: recovery escrow`, #995–#997). Tiny; QR-encodable. |
| -- **Child kit:** the managed member's credential bundle (instance URL + |
| - keypair) as a QR. |
| -- **Restore:** scan/upload → keys return. For credential-bundle kits this |
| - needs one small server feature — proving possession of the instance |
| - keypair re-issues a session — specified when the kit is built, not here. |
| -- **Framing:** the paper is a house key and the UI says so ("Keep this |
| - somewhere safe at home"). We never generate it server-side, never store a |
| - copy, and never make it a sign-up speed bump — it's offered from settings |
| - and at space creation, not demanded. |
| +## The recovery passkey |
| + |
| +**Decision (Paul, 2026-07-25): recovery is a passkey, never a passphrase or |
| +a printed code.** The earlier paper-kit design (a client-generated PDF |
| +wrapping the DEK under a printed code, riding the vault's passphrase-wrap |
| +primitive #995–#997) is dead — that primitive was removed from the product |
| +the same day. One kind of key everywhere; nothing to type, transcribe, or |
| +find in a drawer. |
| + |
| +- **Mechanically it's just another enrolment.** Home already wraps the DEK |
| + per enrolled credential, so "add a recovery passkey" is the existing |
| + add-a-passkey ceremony pointed at a *different home* for the credential: a |
| + cross-platform password manager (1Password, Bitwarden, Google Password |
| + Manager) or a hardware security key. No new crypto, no new server surface. |
| +- **What paper used to buy — surviving a lost vendor account — a |
| + hardware key or cross-platform manager buys instead.** The offer's copy |
| + steers there: a second passkey parked in the *same* iCloud account as |
| + rung 2 adds nearly nothing; one on a YubiKey in a drawer, or in a manager |
| + that syncs everywhere, is the real ecosystem escape hatch. |
| +- **Losing it is survivable and revocable.** A found hardware key is inert |
| + without its PIN, and the credential (plus its DEK wrap) can be removed |
| + from the account like any other — unlike a printed code, which could |
| + never be un-printed. |
| +- **Framing:** never a sign-up speed bump — offered from settings and at |
| + space creation ("add another way back in"), in the same no-jargon voice as |
| + the rest (invariant 6: the word "passkey" stays out of the UI). |
| +- **Managed members** need no kit of their own: their credentials live as |
| + entries in the guardian's vault (above), and the guardian's ladder is the |
| + redundancy. |
| ## Control-plane recovery (why the owner can always re-admit) |
| @@ -349,7 +366,7 @@ step, which is what makes this rung safe to gate on identity alone. |
| | Mail provider | addresses + timing, at send time only (email class) | |
| | Home server | blind indexes; one extra wrapped copy of the DEK per anchor | |
| | A guardian | everything their managed member can see (disclosed at creation) | |
| -| Paper kit finder | whatever the kit unlocks — physical custody is the control | |
| +| A found hardware key | nothing without its PIN — and the credential is revocable from the account | |
| | A compromised home server | still nothing readable (invariant 4) | |
| ## Phasing |
| @@ -374,8 +391,8 @@ Status per item as of 2026-07-22: |
| identity-first ordering are not built. The web doors overshot the plan — |
| Google/Microsoft/GitHub ship too; natively their server legs |
| (`elevenmessenger://home-oidc`) are done and the client halves are open. |
| -2. **Guardian-managed members + paper kits** (the family story). — **not |
| - built.** |
| +2. **Guardian-managed members + the recovery-passkey offer** (the family |
| + story; settings + creation). — **not built.** |
| 3. **Owner anchoring at creation** — email or the successor anchor; the |
| provisioner starts requiring/nudging it. — **not built** (creation from |
| home is effectively anchored via the home session; a bare setup link |
| @@ -393,7 +410,7 @@ Status per item as of 2026-07-22: |
| my other devices"). |
| - What identity-only recovery may show before a key anchor confirms: |
| recommendation **nothing** — the space list is metadata worth the same |
| - protection, so rungs 3–5 reveal it only after approval/kit/re-invite. |
| + protection, so rungs 3–5 reveal it only after approval/passkey/re-invite. |
| - Invite links: whether "include my name in the address" (name-in-path) |
| is offered as an explicit opt-in, or names stay fragment-only always. |
| - When the PAKE short-invite phase earns its build — and whether the |