Skip to content

id: encrypted identity backup — seed-phrase export/restore + passphrase-wrapped server backup #2381

Open

Description

@dezren39

Follow-up from the key-recovery investigation on #2060 (doc: doc/2026-10-29T11-28-18Z_investigation_key_recovery_hosted/, §4/§7 and §11). Parent epic: #2056.

Ordering (triaged 2026-11-03)

Slices per the investigation's §11; this issue is the umbrella for the export/server-backup/rotation remainder, not one implementation task:

Problem

If the only ID key is lost and no device survives, there is no recovery path that keeps the server from holding keys. The investigation recommends encrypted backups where the server holds ciphertext only.

Proposal

  1. Seed-phrase (BIP39-style) export/restore of the identity secret in the id CLI — zero server involvement; doubles as the hosted-edition exit ramp.
  2. Passphrase-wrapped backup stored server-side (hosted edition): memory-hard KDF, and a rate-limited blinded unwrap (OPRF-style) so the server can throttle guessing without learning the passphrase or the key.
  3. A backup-restored key is flagged until a keyset rotation retires it (restore may follow theft).

Acceptance

  • id CLI can export a seed phrase and restore an identity from it, with tests.
  • Server backup format + unwrap throttling designed and documented; server never sees plaintext key material at any step.
  • Restore flow forces/prompts rotation of the restored key.

Activity

  1. added
    kind/featureNew feature or capability request
    priority/normalOrdinary priority (the default)
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    effort/mMedium: expected under 1 day of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 29, 2026
  2. developing-today commented on Oct 29, 2026

    @developing-today
    Contributor
  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 3, 2026
  4. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    agent-note:v1
    state: triaged (coverage pass)
    Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
    Found via: coverage pass 2026-11-03

  5. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · triaged — live, not started; ordering recorded, one overlap guarded

    • Agent: queue worker (repo-worker-code), OpenChamber scheduled lane
    • Session / ID: ses_e5e5db7d11cffeh9uGRhQN1hIJ; queue task 7937 (triage)
    • Found via: atomic queue claim (coverage pass, code slices 3+)

    Verdict: still live; nothing implemented at main 048da81f1. Triaged as an umbrella, not a single implementation task — the three proposals have different prerequisites, and one of them overlaps an existing open issue.

    Fresh evidence:

    • No seed-phrase/mnemonic code: grep -rn "mnemonic\|seed.phrase\|seed_phrase" pkgs/id/src pkgs/id/crates → no matches.
    • No backup format or server-side blob: grep -rln "backup" in pkgs/id/src hits only world_doctor.rs, repl/input.rs, currency_poc/tests.rs, web/routes.rs, cli.rs — none is identity backup. Identity key is still the raw file KEY_FILE = ".iroh-key" (pkgs/id/src/lib.rs:314).
    • No OPRF/blinded unwrap anywhere: grep -rli "oprf\|blinded" over pkgs/id/ and doc/ → no matches. That half needs a design decision before code.
    • Overlap: id: key export/import — passphrase-wrapped identity key envelope (key-recovery slice 1) #2279 ("key export/import — passphrase-wrapped identity key envelope", key-recovery slice 1) is open and queued, and already owns the Argon2id versioned-envelope work. Building that here would duplicate it.
    • Body defect fixed: the issue pointed at investigations/key-recovery.md, which does not exist; the real document is doc/2026-10-29T11-28-18Z_investigation_key_recovery_hosted/. The ordering block above is now in the body.

    Ordering / blocked-by:

    1. id: key export/import — passphrase-wrapped identity key envelope (key-recovery slice 1) #2279 lands the envelope + KDF module (prerequisite).
    2. Seed-phrase export/restore — unique to id: encrypted identity backup — seed-phrase export/restore + passphrase-wrapped server backup #2381, builds on id: key export/import — passphrase-wrapped identity key envelope (key-recovery slice 1) #2279.
    3. Server backup blob + blinded unwrap throttle — design-first (new format + OPRF decision), ciphertext-only server storage; needs the hosted storage surface.
    4. Restore-forces-rotation flag — blocked on id: keyset/authorization log — device keys, revocation, bindings as signed records (identity substrate) #2380 (keyset/authorization log).

    Adjacent but not this issue: #2382 (guardian social recovery), #2804 (issuer key rotation).

    Next action in the system: dispatch the seed-phrase slice once #2279 merges; open a design issue for the server-backup/OPRF half rather than implementation.

  6. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed the split design issue

    Split filed: #5033 — id: design: server-side identity backup blob + rate-limited blinded unwrap (from #2381) — owns the design-first server-side half per the triage ordering. Seed-phrase export/restore stays on #2381 as its unique remainder, dispatchable after #2279.

  7. removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  8. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    Raw-conversation cross-link (WS-F2 mining pass, 2026-11-04). A protection mechanism in Drew's words that sits beside this issue's backup designs:

    "commit then merge then figure out on-disk persistence, maybe store in sqlite or something? ideally at least identity is encrypted with the iroh private key"
    — OpenCode session ses_2b824c120ffer6TEQrUAbYf2EX ("Worktree setup for client-persistence"), 2026-04-01

    This issue designs identity protection for backup/restore (seed-phrase export, passphrase-wrapped server backup). The quoted ask is the sibling case: local at-rest encryption of the identity store on the node's own disk, keyed by the node's iroh private key — the identity material is encrypted with the iroh keypair the node already has, rather than (or in addition to) a user passphrase. Design points it raises for whichever issue takes it: what exactly the iroh key wraps (the identity store key? the store itself?), what happens on key rotation (#2804 interplay), and the honest failure statement — losing the iroh key then loses both the node identity and the wrapped store, which may be the same loss the user already accepts, or a compounding of two losses into one event.

    Posted as a comment here because this is the identity-protection design home; if the at-rest case deserves its own design, it should be split out from this thread rather than filed cold.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workkind/featureNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions