Repository navigation
Open
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workMedium: expected under 1 day of workkind/featureNew feature or capability requestNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)Ordinary priority (the default)source/creatorFiled by the new-issue-creator jobFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this item
Description
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:
- Slice 1 —
id key export/id key importpassphrase-wrapped envelope: id: key export/import — passphrase-wrapped identity key envelope (key-recovery slice 1) #2279 (open, queued, not started). Prerequisite for everything below; do not build a second envelope format here. - Seed-phrase (BIP39-style) export/restore — unique to this issue; shares id: key export/import — passphrase-wrapped identity key envelope (key-recovery slice 1) #2279's KDF/envelope module; dispatch after id: key export/import — passphrase-wrapped identity key envelope (key-recovery slice 1) #2279.
- Server-side backup blob + rate-limited blinded unwrap (OPRF) — design decision first (no OPRF or backup-blob code exists at main); ciphertext-only server storage; depends on slice 1.
- Restore-forces-rotation flag — needs the keyset log substrate in id: keyset/authorization log — device keys, revocation, bindings as signed records (identity substrate) #2380 (device keys, revocation, bindings).
- Guardian/social recovery is id: guardian social recovery — threshold approvals + delayed, cancellable key rotation #2382; issuer key rotation is id: design: issuer key rotation and compromise recovery for currency issuers (from #2041) #2804 (different scope).
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
- Seed-phrase (BIP39-style) export/restore of the identity secret in the
idCLI — zero server involvement; doubles as the hosted-edition exit ramp. - 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.
- A backup-restored key is flagged until a keyset rotation retires it (restore may follow theft).
Acceptance
-
idCLI 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.
Metadata
Metadata
Assignees
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workMedium: expected under 1 day of workkind/featureNew feature or capability requestNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)Ordinary priority (the default)source/creatorFiled by the new-issue-creator jobFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this item
Activity
developing-today commentedon Oct 29, 2026
CODE-1208
developing-today commentedon Nov 3, 2026
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
dezren39 commentedon Nov 3, 2026
🤖 Agent note · triaged — live, not started; ordering recorded, one overlap guarded
ses_e5e5db7d11cffeh9uGRhQN1hIJ; queue task 7937 (triage)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:
grep -rn "mnemonic\|seed.phrase\|seed_phrase" pkgs/id/src pkgs/id/crates→ no matches.grep -rln "backup"inpkgs/id/srchits onlyworld_doctor.rs,repl/input.rs,currency_poc/tests.rs,web/routes.rs,cli.rs— none is identity backup. Identity key is still the raw fileKEY_FILE = ".iroh-key"(pkgs/id/src/lib.rs:314).grep -rli "oprf\|blinded"overpkgs/id/anddoc/→ no matches. That half needs a design decision before code.investigations/key-recovery.md, which does not exist; the real document isdoc/2026-10-29T11-28-18Z_investigation_key_recovery_hosted/. The ordering block above is now in the body.Ordering / blocked-by:
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.
dezren39 commentedon Nov 3, 2026
🤖 Agent note · filed the split design issue
ses_e5e5db7d11cffeh9uGRhQN1hIJ; queue task 7937 (triage of id: encrypted identity backup — seed-phrase export/restore + passphrase-wrapped server backup #2381)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.dezren39 commentedon Nov 5, 2026
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:
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.