Social-recovery guardian shares (0243 — Apple-ADP recovery-contacts analogue)#337
Merged
Conversation
…ontacts analogue) The non-coercible 'recover without keeping a phrase' path the Apple-reframed escrow note recommends: wrap the already-shipped Shamir crypto in IdentityManager methods. createGuardianShares(config) splits a recoverable identity's phrase into k-of-n shares (passkey-gated read); recoverFromGuardianShares(shares) rebuilds the phrase from >=threshold shares on a new device, reproduces the same DID, and enrolls a local passkey. Entirely user-to-user — the cloud is never involved, so it stays zero-knowledge. Mirrored in the test-bypass manager. 3 new tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: xNet Test <test@xnet.dev>
Contributor
|
Preview removed for PR #337. |
crs48
added a commit
that referenced
this pull request
Jun 29, 2026
…nd to end) (#339) Wires the social-recovery engine ([#337](#337)) into the UI — xNet's **Apple recovery-contacts** analogue, the non-coercible "recover without keeping a phrase" path the [reframed escrow note](docs/plans/0243-p3-escrow-design.md) recommends over custodial escrow. ## What this adds - **Settings → Account → "Trusted guardians":** for a recoverable identity, split it into **3 guardian share codes (any 2 recover)**, each copy-pasteable. Hand one to each trusted person. - **Onboarding → "Recover with guardian shares":** a [`GuardianRecoveryScreen`](packages/react/src/onboarding/screens/GuardianRecoveryScreen.tsx) collects the share codes and reconstructs the **same DID** on a new device, enrolling a local passkey. New machine state `guardian-recovery` + `ENTER_GUARDIAN_SHARES` / `SUBMIT_GUARDIAN_SHARES` events + a provider side-effect calling `recoverFromGuardianShares`. - `@xnetjs/identity` `serializeShare` / `parseShare` for the opaque `xnet-share:…` codes guardians copy around. **Recovery is entirely user-to-user — the cloud is never involved**, so it stays zero-knowledge and non-coercible, exactly like Apple's ADP recovery contacts. Machine-transition tests (27 onboarding tests) + a share-code round-trip test; `@xnetjs/identity`, `@xnetjs/react`, and `apps/web` typecheck clean. Changeset: `@xnetjs/identity` + `@xnetjs/react` minor, with a user-facing changelog entry. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
crs48
added a commit
that referenced
this pull request
Jun 29, 2026
…#342) Marks [exploration 0243](docs/explorations/0243_[x]_ACCOUNT_VALIDATION_AND_RECOVERY_BINDING_THE_PAYER_TO_THE_PASSKEY.md) complete: renames `[_]` → `[x]`, records a **Resolution** summary of everything shipped, and reframes the last item (P3.1) from "implement custodial escrow" to a **documented decision to decline it**. ## Why P3.1 is "done" by being declined A WorkOS-gated KMS escrow that recovers from a login alone would make xNet **coercible** — a subpoena or a compromised WorkOS account would reach user data, the opposite of this exploration's guarantee. Following Apple's model (ADP holds no key; recovery via a user-held key + recovery *contacts*), we shipped the **non-coercible alternative** instead — configurable **trusted-guardian social recovery** (Shamir; #337/#339/#341), entirely user-to-user. A privacy-preserving escrow *engine* (#335) remains for a future Apple-grade ZK-PIN + rate-limiting-HSM design if a concrete enterprise need ever arises; the naive custodial variant is intentionally not built. ## Delivered across 17 PRs Validation hardening · recovery phrase + synced passkey + guardian social recovery + Settings management · account/device ledger (schemas, ops, binding→account, content-key re-wrap) · privacy-preserving escrow engine · Apple-reframed escrow design note. **13/13 implementation, 9/9 validation.** Docs-only → `skip-changelog`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Building the non-coercible "recover without keeping a phrase" path the reframed escrow note recommends over custodial escrow — xNet's equivalent of Apple's recovery contacts, built on the Shamir secret-sharing already shipped in
seed-recovery.ts.What this adds
Two
IdentityManagermethods (engine):createGuardianShares({ totalShares, threshold })— splits a recoverable identity's phrase into k-of-n guardian shares (prompts for the passkey to read the phrase). The user hands the shares to trusted guardians out of band.recoverFromGuardianShares(shares)— on a new device, reconstructs the phrase from anythresholdshares, reproduces the same DID, and enrolls a local passkey.Recovery is entirely user-to-user — the cloud is never involved, so it stays zero-knowledge and non-coercible by construction (nothing for anyone to compel). Mirrored in the test-bypass manager. 3 new tests: 2-of-3 round-trips to the same DID on a wiped device, too-few-shares fails, and a non-recoverable (PRF) identity is rejected.
@xnetjs/identitytypechecks clean; 8 manager tests green.Next
This is the engine; the guardian enroll/recover UI (a Settings "set up trusted guardians" flow + an onboarding "recover with guardian shares" path) follows. Changeset:
@xnetjs/identityminor; no user-visible behavior yet →skip-changelog.🤖 Generated with Claude Code